git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1376500 13f79535-47bb-0310-9956-ffa450edef68tags/fop-2_0
@@ -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)); | |||
} | |||
} | |||
@@ -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); | |||
} | |||
/** |
@@ -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)); | |||
} | |||
} |
@@ -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. |
@@ -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"); | |||
} | |||
} |