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.
*
}
}
+ /**
+ * 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")
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.
*/
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));
}
/**
* @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));
}
}
/**
* 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);
}
/**
* @param encoding the encoding
*/
public void setEncoding(String encoding) {
- if (encoding != null) {
+ if (encoding != null && !PDFEncoding.hasStandardEncoding(encoding)) {
put("Encoding", new PDFName(encoding));
}
}
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.
--- /dev/null
+/*
+ * 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");
+ }
+}