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

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));
} }
} }



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

/** /**
* 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);
} }


/** /**

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

* @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));
} }
} }

+ 3
- 0
status.xml View File

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.

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

/*
* 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