git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1376500 13f79535-47bb-0310-9956-ffa450edef68tags/fop-2_0
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.Set; | import java.util.Set; | ||||
import org.apache.fop.fonts.CodePointMapping; | |||||
import org.apache.fop.fonts.SingleByteEncoding; | |||||
/** | /** | ||||
* Class representing an /Encoding object. | * 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. | * Indicates whether a given encoding is one of the predefined encodings. | ||||
* @param name the encoding name (ex. "StandardEncoding") | * @param name the encoding name (ex. "StandardEncoding") | ||||
return PREDEFINED_ENCODINGS.contains(name); | 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 | * Creates and returns a new DifferencesBuilder instance for constructing the Differences | ||||
* array. | * array. | ||||
*/ | */ | ||||
public class DifferencesBuilder { | public class DifferencesBuilder { | ||||
private PDFArray differences = new PDFArray(); | |||||
private int currentCode = -1; | 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. | * Start a new difference. | ||||
* @param code the starting code index inside the encoding | * @param code the starting code index inside the encoding | ||||
* @return this builder instance | * @return this builder instance | ||||
*/ | */ | ||||
public DifferencesBuilder addDifference(int code) { | |||||
private void addDifference(int code, PDFArray differences) { | |||||
this.currentCode = code; | this.currentCode = code; | ||||
this.differences.add(new Integer(code)); | |||||
return this; | |||||
differences.add(Integer.valueOf(code)); | |||||
} | } | ||||
/** | /** | ||||
* @param name the character name | * @param name the character name | ||||
* @return this builder instance | * @return this builder instance | ||||
*/ | */ | ||||
public DifferencesBuilder addName(String name) { | |||||
private void addName(String name, PDFArray differences) { | |||||
if (this.currentCode < 0) { | if (this.currentCode < 0) { | ||||
throw new IllegalStateException("addDifference(int) must be called first"); | 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. | * Creates a PDFEncoding instance from a CodePointMapping instance. | ||||
* @param encoding the code point mapping (encoding) | * @param encoding the code point mapping (encoding) | ||||
* @param fontNameHint ... | |||||
* @param fontName ... | |||||
* @return the PDF Encoding dictionary (or a String with the predefined encoding) | * @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 | * @param encoding the encoding | ||||
*/ | */ | ||||
public void setEncoding(String encoding) { | public void setEncoding(String encoding) { | ||||
if (encoding != null) { | |||||
if (encoding != null && !PDFEncoding.hasStandardEncoding(encoding)) { | |||||
put("Encoding", new PDFName(encoding)); | put("Encoding", new PDFName(encoding)); | ||||
} | } | ||||
} | } |
documents. Example: the fix of marks layering will be such a case when it's done. | documents. Example: the fix of marks layering will be such a case when it's done. | ||||
--> | --> | ||||
<release version="FOP Trunk" date="TBD"> | <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"> | <action context="Fonts" dev="MH" type="fix" fixes-bug="53685"> | ||||
Cached AFP charactersets have more unique keys preventing the two characters with | Cached AFP charactersets have more unique keys preventing the two characters with | ||||
but different binaries conflicting. | but different binaries conflicting. |
/* | |||||
* 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"); | |||||
} | |||||
} |