Browse Source

Bugfix#53766: Remove StandardEncoding as the encoding type from fonts used in the PDF renderer. Submitted by Robert Meyer.


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1376500 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-2_0
Mehdi Houshmand 11 years ago
parent
commit
d6994df393

+ 76
- 23
src/java/org/apache/fop/pdf/PDFEncoding.java View File

@@ -23,6 +23,9 @@ package org.apache.fop.pdf;
import java.util.Collections;
import java.util.Set;

import org.apache.fop.fonts.CodePointMapping;
import org.apache.fop.fonts.SingleByteEncoding;

/**
* Class representing an /Encoding object.
*
@@ -73,6 +76,38 @@ public class PDFEncoding extends PDFDictionary {
}
}

/**
* Creates a PDFEncoding instance from a CodePointMapping instance.
* @param encoding the code point mapping (encoding)
* @param fontName ...
* @return the PDF Encoding dictionary (or a String with the predefined encoding)
*/
static Object createPDFEncoding(SingleByteEncoding encoding, String fontName) {
//If encoding type is null, return null which causes /Encoding to be omitted.
if (encoding == null) {
return null;
}
String encodingName = null;
SingleByteEncoding baseEncoding;
if (fontName.indexOf("Symbol") >= 0) {
baseEncoding = CodePointMapping.getMapping(CodePointMapping.SYMBOL_ENCODING);
encodingName = baseEncoding.getName();
} else {
baseEncoding = CodePointMapping.getMapping(CodePointMapping.STANDARD_ENCODING);
}
PDFEncoding pdfEncoding = new PDFEncoding(encodingName);
PDFEncoding.DifferencesBuilder builder = pdfEncoding.createDifferencesBuilder();
PDFArray differences = builder.buildDifferencesArray(baseEncoding, encoding);
// TODO This method should not be returning an Object with two different outcomes
// resulting in subsequent `if (X instanceof Y)` statements.
if (differences.length() > 0) {
pdfEncoding.setDifferences(differences);
return pdfEncoding;
} else {
return encodingName;
}
}

/**
* Indicates whether a given encoding is one of the predefined encodings.
* @param name the encoding name (ex. "StandardEncoding")
@@ -82,6 +117,15 @@ public class PDFEncoding extends PDFDictionary {
return PREDEFINED_ENCODINGS.contains(name);
}

/**
* Indicates whether the given encoding type is that of standard encoding
* @param name The encoding name
* @return Returns true if it is of type standard encoding
*/
static boolean hasStandardEncoding(String encodingName) {
return encodingName.equals(STANDARD_ENCODING);
}

/**
* Creates and returns a new DifferencesBuilder instance for constructing the Differences
* array.
@@ -104,18 +148,44 @@ public class PDFEncoding extends PDFDictionary {
*/
public class DifferencesBuilder {

private PDFArray differences = new PDFArray();
private int currentCode = -1;

/**
* Creates an array containing the differences between two single-byte.
* font encodings.
* @param encoding_A The first single-byte encoding
* @param encoding_B The second single-byte encoding
* @return The PDFArray of differences between encodings
*/
public PDFArray buildDifferencesArray(SingleByteEncoding encodingA,
SingleByteEncoding encodingB) {
PDFArray differences = new PDFArray();
int start = -1;
String[] baseNames = encodingA.getCharNameMap();
String[] charNameMap = encodingB.getCharNameMap();
for (int i = 0, ci = charNameMap.length; i < ci; i++) {
String basec = baseNames[i];
String c = charNameMap[i];
if (!basec.equals(c)) {
if (start != i) {
addDifference(i, differences);
start = i;
}
addName(c, differences);
start++;
}
}
return differences;
}

/**
* Start a new difference.
* @param code the starting code index inside the encoding
* @return this builder instance
*/
public DifferencesBuilder addDifference(int code) {
private void addDifference(int code, PDFArray differences) {
this.currentCode = code;
this.differences.add(new Integer(code));
return this;
differences.add(Integer.valueOf(code));
}

/**
@@ -123,28 +193,11 @@ public class PDFEncoding extends PDFDictionary {
* @param name the character name
* @return this builder instance
*/
public DifferencesBuilder addName(String name) {
private void addName(String name, PDFArray differences) {
if (this.currentCode < 0) {
throw new IllegalStateException("addDifference(int) must be called first");
}
this.differences.add(new PDFName(name));
return this;
}

/**
* Indicates whether any differences have been recorded.
* @return true if there are differences.
*/
public boolean hasDifferences() {
return (this.differences.length() > 0);
}

/**
* Creates and returns the PDFArray representing the Differences entry.
* @return the Differences entry
*/
public PDFArray toPDFArray() {
return this.differences;
differences.add(new PDFName(name));
}
}


+ 3
- 34
src/java/org/apache/fop/pdf/PDFFactory.java View File

@@ -1469,42 +1469,11 @@ public class PDFFactory {
/**
* Creates a PDFEncoding instance from a CodePointMapping instance.
* @param encoding the code point mapping (encoding)
* @param fontNameHint ...
* @param fontName ...
* @return the PDF Encoding dictionary (or a String with the predefined encoding)
*/
public Object createPDFEncoding(SingleByteEncoding encoding, String fontNameHint) {
SingleByteEncoding baseEncoding;
if (fontNameHint.indexOf("Symbol") >= 0) {
baseEncoding = CodePointMapping.getMapping(
CodePointMapping.SYMBOL_ENCODING);
} else {
baseEncoding = CodePointMapping.getMapping(
CodePointMapping.STANDARD_ENCODING);
}
PDFEncoding pdfEncoding = new PDFEncoding(baseEncoding.getName());
PDFEncoding.DifferencesBuilder builder
= pdfEncoding.createDifferencesBuilder();
int start = -1;
String[] baseNames = baseEncoding.getCharNameMap();
String[] charNameMap = encoding.getCharNameMap();
for (int i = 0, ci = charNameMap.length; i < ci; i++) {
String basec = baseNames[i];
String c = charNameMap[i];
if (!basec.equals(c)) {
if (start != i) {
builder.addDifference(i);
start = i;
}
builder.addName(c);
start++;
}
}
if (builder.hasDifferences()) {
pdfEncoding.setDifferences(builder.toPDFArray());
return pdfEncoding;
} else {
return baseEncoding.getName();
}
public Object createPDFEncoding(SingleByteEncoding encoding, String fontName) {
return PDFEncoding.createPDFEncoding(encoding, fontName);
}

/**

+ 1
- 1
src/java/org/apache/fop/pdf/PDFFont.java View File

@@ -70,7 +70,7 @@ public class PDFFont extends PDFDictionary {
* @param encoding the encoding
*/
public void setEncoding(String encoding) {
if (encoding != null) {
if (encoding != null && !PDFEncoding.hasStandardEncoding(encoding)) {
put("Encoding", new PDFName(encoding));
}
}

+ 3
- 0
status.xml View File

@@ -62,6 +62,9 @@
documents. Example: the fix of marks layering will be such a case when it's done.
-->
<release version="FOP Trunk" date="TBD">
<action context="Renderers" dev="MH" type="fix" fixes-bug="53766" due-to="Robert Meyer">
Remove StandardEncoding as the encoding type from fonts used in the PDF renderer
</action>
<action context="Fonts" dev="MH" type="fix" fixes-bug="53685">
Cached AFP charactersets have more unique keys preventing the two characters with
but different binaries conflicting.

+ 76
- 0
test/java/org/apache/fop/pdf/PDFEncodingTestCase.java View File

@@ -0,0 +1,76 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.fop.pdf;

import org.junit.Test;

import org.apache.fop.fonts.CodePointMapping;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

public class PDFEncodingTestCase {

/**
* Tests the createPDFEncoding method to ensure a null encoding type
* is handled correctly.
*/
@Test
public void testCreatePDFEncodingForNull() {
Object encoding = PDFEncoding.createPDFEncoding(null, "Test");
assertEquals(encoding, null);
}

/**
* Tests that when a PDFEncoding object is created, if the encoding type is
* that of StandardEncoding, the baseEncoding tag is omitted.
*/
@Test
public void testStandardEncodingDiffs() {
Object encoding = PDFEncoding.createPDFEncoding(CodePointMapping.getMapping(
CodePointMapping.SYMBOL_ENCODING), "Test");
if (encoding instanceof PDFEncoding) {
PDFEncoding pdfEncoding = (PDFEncoding) encoding;
assertFalse(pdfEncoding.entries.containsKey("BaseEncoding"));
}
}

/**
* Tests that when the StandardEncoding type is provided and there are no
* differences, the returned encoding object is null.
*/
@Test
public void testStandardEncodingNoDiff() {
Object encoding = PDFEncoding.createPDFEncoding(CodePointMapping.getMapping(
CodePointMapping.STANDARD_ENCODING), "Test");
assertEquals(encoding, null);
}

/**
* Tests that when the SymbolEncoding type is provided and there are no
* differences, the returned encoding string is that of SymbolEncoding.
*/
@Test
public void testCreatePDFEncodingSymbol() {
Object encoding = PDFEncoding.createPDFEncoding(CodePointMapping.getMapping(
CodePointMapping.SYMBOL_ENCODING), "Symbol");
assert (encoding instanceof String);
String pdfEncoding = (String) encoding;
assertEquals(pdfEncoding, "SymbolEncoding");
}
}

Loading…
Cancel
Save