Author: jeremias
Date: Tue Feb 16 09:36:40 2010
New Revision: 910445
URL: http://svn.apache.org/viewvc?rev=910445&view=rev
Log:
Bugzilla #48512:
Reverted rev 908543.
For some Type 1 fonts, the encoding mapped characters in the AFM file don't
match the font's primary encoding. This change tries to address this fact.
Modified:
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/AFMFile.java
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/AFMFile.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/AFMFile.java?rev=910445&r1=910444&r2=910445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/AFMFile.java
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/AFMFile.java Tue
Feb 16 09:36:40 2010
@@ -28,6 +28,9 @@
import org.apache.xmlgraphics.java2d.Dimension2DDouble;
+import org.apache.fop.fonts.NamedCharacter;
+import org.apache.fop.fonts.SingleByteEncoding;
+
/**
* Represents the contents of a Type 1 AFM font metrics file.
*/
@@ -442,6 +445,30 @@
return m;
}
+ /**
+ * The character codes in an AFM cannot always be trusted to be the same
values as in the
+ * font's primary encoding. Therefore, we provide a way to override this
primary encoding.
+ * @param encoding the encoding to replace the one given in the AFM
+ */
+ public void overridePrimaryEncoding(SingleByteEncoding encoding) {
+ Iterator iter = this.charMetrics.iterator();
+ while (iter.hasNext()) {
+ AFMCharMetrics cm = (AFMCharMetrics)iter.next();
+ NamedCharacter nc = cm.getCharacter();
+ if (nc.hasSingleUnicodeValue()) {
+ int mapped = encoding.mapChar(nc.getSingleUnicodeValue());
+ if (mapped > 0) {
+ cm.setCharCode(mapped);
+ } else {
+ cm.setCharCode(-1);
+ }
+ } else {
+ //No Unicode equivalent
+ cm.setCharCode(-1);
+ }
+ }
+ }
+
/** {...@inheritdoc} */
public String toString() {
return "AFM: " + getFullName();
Modified:
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
URL:
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java?rev=910445&r1=910444&r2=910445&view=diff
==============================================================================
---
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
(original)
+++
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
Tue Feb 16 09:36:40 2010
@@ -32,6 +32,7 @@
import org.apache.fop.fonts.FontLoader;
import org.apache.fop.fonts.FontResolver;
import org.apache.fop.fonts.FontType;
+import org.apache.fop.fonts.SingleByteEncoding;
import org.apache.fop.fonts.SingleByteFont;
/**
@@ -141,8 +142,11 @@
if (afm != null) {
String encoding = afm.getEncodingScheme();
singleFont.setUseNativeEncoding(true);
- if ("StandardEncoding".equals(encoding)) {
+ if ("AdobeStandardEncoding".equals(encoding)) {
singleFont.setEncoding(CodePointMapping.STANDARD_ENCODING);
+ addUnencodedBasedOnEncoding(afm);
+ //char codes in the AFM cannot be relied on in this case, so
we override
+ afm.overridePrimaryEncoding(singleFont.getEncoding());
} else {
String effEncodingName;
if ("FontSpecific".equals(encoding)) {
@@ -156,14 +160,7 @@
}
CodePointMapping mapping =
buildCustomEncoding(effEncodingName, afm);
singleFont.setEncoding(mapping);
- }
- List charMetrics = afm.getCharMetrics();
- for (int i = 0, c = afm.getCharCount(); i < c; i++) {
- AFMCharMetrics metrics = (AFMCharMetrics)charMetrics.get(i);
- if (!metrics.hasCharCode() && metrics.getCharacter() != null) {
- singleFont.addUnencodedCharacter(metrics.getCharacter(),
- (int)Math.round(metrics.getWidthX()));
- }
+ addUnencodedBasedOnAFM(afm);
}
} else {
if (pfm.getCharSet() >= 0 && pfm.getCharSet() <= 2) {
@@ -176,6 +173,50 @@
}
}
+ private Set toGlyphSet(String[] glyphNames) {
+ Set glyphSet = new java.util.HashSet();
+ for (int i = 0, c = glyphNames.length; i < c; i++) {
+ glyphSet.add(glyphNames[i]);
+ }
+ return glyphSet;
+ }
+
+ /**
+ * Adds characters not encoded in the font's primary encoding. This method
is used when we
+ * don't trust the AFM to expose the same encoding as the primary font.
+ * @param afm the AFM file.
+ */
+ private void addUnencodedBasedOnEncoding(AFMFile afm) {
+ SingleByteEncoding encoding = singleFont.getEncoding();
+ Set glyphNames = toGlyphSet(encoding.getCharNameMap());
+ List charMetrics = afm.getCharMetrics();
+ for (int i = 0, c = afm.getCharCount(); i < c; i++) {
+ AFMCharMetrics metrics = (AFMCharMetrics)charMetrics.get(i);
+ String charName = metrics.getCharName();
+ if (charName != null && !glyphNames.contains(charName)) {
+ singleFont.addUnencodedCharacter(metrics.getCharacter(),
+ (int)Math.round(metrics.getWidthX()));
+ }
+ }
+ }
+
+ /**
+ * Adds characters not encoded in the font's primary encoding. This method
is used when
+ * the primary encoding is built based on the character codes in the AFM
rather than
+ * the specified encoding (ex. with symbolic fonts).
+ * @param afm the AFM file
+ */
+ private void addUnencodedBasedOnAFM(AFMFile afm) {
+ List charMetrics = afm.getCharMetrics();
+ for (int i = 0, c = afm.getCharCount(); i < c; i++) {
+ AFMCharMetrics metrics = (AFMCharMetrics)charMetrics.get(i);
+ if (!metrics.hasCharCode() && metrics.getCharacter() != null) {
+ singleFont.addUnencodedCharacter(metrics.getCharacter(),
+ (int)Math.round(metrics.getWidthX()));
+ }
+ }
+ }
+
private void handleFontName(AFMFile afm, PFMFile pfm) {
//Font name
if (afm != null) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]