diff options
author | Jeremias Maerki <jeremias@apache.org> | 2009-01-05 07:59:39 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2009-01-05 07:59:39 +0000 |
commit | c0028134f8261116cbfd1a263f8e28456a81522e (patch) | |
tree | 8c076130ae9be0cc0871132b5fb2348dbedc05ff /src/java/org/apache/fop | |
parent | 011fd36fcef0003a63e9dc8da3233fd18c7889fb (diff) | |
parent | 68dd1750c65ec6ce5475f2f12ea63f6495a708ad (diff) | |
download | xmlgraphics-fop-c0028134f8261116cbfd1a263f8e28456a81522e.tar.gz xmlgraphics-fop-c0028134f8261116cbfd1a263f8e28456a81522e.zip |
Merge from Trunk revisions 728026 - 731479.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign@731480 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop')
19 files changed, 263 insertions, 56 deletions
diff --git a/src/java/org/apache/fop/fo/FObj.java b/src/java/org/apache/fop/fo/FObj.java index e0624df69..55844e6db 100644 --- a/src/java/org/apache/fop/fo/FObj.java +++ b/src/java/org/apache/fop/fo/FObj.java @@ -215,7 +215,7 @@ public abstract class FObj extends FONode implements Constants { * @param parent the (cloned) parent node * @throws FOPException when the child could not be added to the parent */ - protected static void addChildTo(FONode child, FObj parent) + protected static void addChildTo(FONode child, FONode parent) throws FOPException { parent.addChildNode(child); } @@ -573,11 +573,11 @@ public abstract class FObj extends FONode implements Constants { } } - /** @return true if this FObj has extension attachments */ + /** @return true if this FObj has extension attachments */ public boolean hasExtensionAttachments() { return extensionAttachments != null; } - + /** * Adds a foreign attribute to this FObj. * @param attributeName the attribute name as a QName instance diff --git a/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java b/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java index ebba1fda5..1432c9381 100644 --- a/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java +++ b/src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java @@ -30,8 +30,8 @@ import org.apache.fop.fo.FObj; import org.apache.fop.fo.FObjMixed; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.ValidationException; +import org.apache.fop.fo.XMLObj; import org.apache.fop.fo.flow.table.Table; -import org.apache.fop.fo.flow.table.TableFObj; /** * Abstract base class for the <a href="http://www.w3.org/TR/xsl/#fo_retrieve-marker"> @@ -102,7 +102,7 @@ public abstract class AbstractRetrieveMarker extends FObjMixed { getLocator(), pList, newPropertyList); - addChildTo(newChild, (FObj) newParent); + addChildTo(newChild, newParent); if (newChild.getNameId() == FO_TABLE) { Table t = (Table) child; cloneSubtree(t.getColumns().iterator(), @@ -117,7 +117,9 @@ public abstract class AbstractRetrieveMarker extends FObjMixed { } else if (child instanceof FOText) { FOText ft = (FOText) newChild; ft.bind(parentPropertyList); - addChildTo(newChild, (FObj) newParent); + addChildTo(newChild, newParent); + } else if (child instanceof XMLObj) { + addChildTo(newChild, newParent); } // trigger end-of-node white-space handling diff --git a/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java b/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java index 94639a5a6..eeafbb68b 100755 --- a/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java +++ b/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java @@ -20,7 +20,10 @@ package org.apache.fop.fo.properties; import java.awt.Color; +import java.io.FileNotFoundException; +import java.io.IOException; +import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageManager; import org.apache.xmlgraphics.image.loader.ImageSessionContext; @@ -29,7 +32,9 @@ import org.apache.fop.apps.FOUserAgent; import org.apache.fop.datatypes.Length; import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.datatypes.URISpecification; +import org.apache.fop.events.ResourceEventProducer; import org.apache.fop.fo.Constants; +import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.expr.PropertyException; @@ -362,6 +367,7 @@ public class CommonBorderPaddingBackground { && !("".equals(newInstance.backgroundImage))) { //Additional processing: preload image String uri = URISpecification.getURL(newInstance.backgroundImage); + FObj fobj = pList.getFObj(); FOUserAgent userAgent = pList.getFObj().getUserAgent(); ImageManager manager = userAgent.getFactory().getImageManager(); ImageSessionContext sessionContext = userAgent.getImageSessionContext(); @@ -369,10 +375,19 @@ public class CommonBorderPaddingBackground { try { info = manager.getImageInfo(uri, sessionContext); newInstance.backgroundImageInfo = info; - } catch (Exception e) { - Property.log.error("Background image not available: " + uri); + } catch (ImageException e) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + fobj.getUserAgent().getEventBroadcaster()); + eventProducer.imageError(fobj, uri, e, fobj.getLocator()); + } catch (FileNotFoundException fnfe) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + fobj.getUserAgent().getEventBroadcaster()); + eventProducer.imageNotFound(fobj, uri, fnfe, fobj.getLocator()); + } catch (IOException ioe) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( + fobj.getUserAgent().getEventBroadcaster()); + eventProducer.imageIOError(fobj, uri, ioe, fobj.getLocator()); } - //TODO Report to caller so he can decide to throw an exception } return (cachedInstance != null ? cachedInstance : newInstance); diff --git a/src/java/org/apache/fop/fonts/AbstractCodePointMapping.java b/src/java/org/apache/fop/fonts/AbstractCodePointMapping.java index 56558b02e..f03d4beab 100644 --- a/src/java/org/apache/fop/fonts/AbstractCodePointMapping.java +++ b/src/java/org/apache/fop/fonts/AbstractCodePointMapping.java @@ -189,12 +189,7 @@ public class AbstractCodePointMapping implements SingleByteEncoding { return this.unicodeMap[idx]; } - /** - * Returns a character array with Unicode scalar values which can be used to map encoding - * code points to Unicode values. Note that this does not return all possible Unicode values - * that the encoding maps. - * @return a character array with Unicode scalar values - */ + /** {@inheritDoc} */ public final char[] getUnicodeCharMap() { char[] copy = new char[this.unicodeMap.length]; System.arraycopy(this.unicodeMap, 0, copy, 0, this.unicodeMap.length); diff --git a/src/java/org/apache/fop/fonts/EmbedFontInfo.java b/src/java/org/apache/fop/fonts/EmbedFontInfo.java index 3c4964b97..aa464c21d 100644 --- a/src/java/org/apache/fop/fonts/EmbedFontInfo.java +++ b/src/java/org/apache/fop/fonts/EmbedFontInfo.java @@ -29,7 +29,7 @@ import java.util.List; public class EmbedFontInfo implements Serializable { /** Serialization Version UID */ - private static final long serialVersionUID = 8755432068669997367L; + private static final long serialVersionUID = 8755432068669997368L; /** filename of the metrics file */ protected String metricsFile; @@ -37,6 +37,8 @@ public class EmbedFontInfo implements Serializable { protected String embedFile; /** false, to disable kerning */ protected boolean kerning; + /** the requested encoding mode for the font */ + protected EncodingMode encodingMode = EncodingMode.AUTO; /** the PostScript name of the font */ protected String postScriptName = null; @@ -142,6 +144,25 @@ public class EmbedFontInfo implements Serializable { this.embedded = value; } + /** + * Returns the requested encoding mode for this font. + * @return the encoding mode + */ + public EncodingMode getEncodingMode() { + return this.encodingMode; + } + + /** + * Sets the requested encoding mode for this font. + * @param mode the new encoding mode + */ + public void setEncodingMode(EncodingMode mode) { + if (mode == null) { + throw new NullPointerException("mode must not be null"); + } + this.encodingMode = mode; + } + private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); @@ -150,8 +171,10 @@ public class EmbedFontInfo implements Serializable { /** {@inheritDoc} */ public String toString() { - return "metrics-url=" + metricsFile + ",embed-url=" + embedFile - + ", kerning=" + kerning + ", " + "font-triplet=" + fontTriplets + return "metrics-url=" + metricsFile + ", embed-url=" + embedFile + + ", kerning=" + kerning + + ", enc-mode=" + encodingMode + + ", font-triplet=" + fontTriplets + (getSubFontName() != null ? ", sub-font=" + getSubFontName() : "") + (isEmbedded() ? "" : ", NOT embedded"); } diff --git a/src/java/org/apache/fop/fonts/EncodingMode.java b/src/java/org/apache/fop/fonts/EncodingMode.java new file mode 100644 index 000000000..734292c54 --- /dev/null +++ b/src/java/org/apache/fop/fonts/EncodingMode.java @@ -0,0 +1,82 @@ +/* + * 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. + */ + +/* $Id$ */ + +package org.apache.fop.fonts; + +import java.io.ObjectStreamException; +import java.io.Serializable; + + +/** + * This class enumerates all supported encoding modes for fonts: auto, single-byte and CID. + */ +public final class EncodingMode implements Serializable { + + private static final long serialVersionUID = 8311486102457779529L; + + /** Automatic selection of encoding mode. */ + public static final EncodingMode AUTO = new EncodingMode("auto"); + + /** Single-byte encoding */ + public static final EncodingMode SINGLE_BYTE = new EncodingMode("single-byte"); + + /** CID encoding */ + public static final EncodingMode CID = new EncodingMode("cid"); + + private String name; + + private EncodingMode(String name) { + this.name = name; + } + + /** + * Returns the encoding mode name. + * @return the encoding mode name + */ + public String getName() { + return this.name; + } + + /** + * Returns the {@link EncodingMode} by name. + * @param name the name of the encoding mode to look up + * @return the encoding mode constant + */ + public static EncodingMode valueOf(String name) { + if (name.equalsIgnoreCase(EncodingMode.AUTO.getName())) { + return EncodingMode.AUTO; + } else if (name.equalsIgnoreCase(EncodingMode.SINGLE_BYTE.getName())) { + return EncodingMode.SINGLE_BYTE; + } else if (name.equalsIgnoreCase(EncodingMode.CID.getName())) { + return EncodingMode.CID; + } else { + throw new IllegalArgumentException("Invalid encoding mode: " + name); + } + } + + private Object readResolve() throws ObjectStreamException { + return valueOf(getName()); + } + + /** {@inheritDoc} */ + public String toString() { + return "EncodingMode:" + getName(); + } + +} diff --git a/src/java/org/apache/fop/fonts/FontLoader.java b/src/java/org/apache/fop/fonts/FontLoader.java index 6d2593fad..b3d32e38d 100644 --- a/src/java/org/apache/fop/fonts/FontLoader.java +++ b/src/java/org/apache/fop/fonts/FontLoader.java @@ -75,13 +75,14 @@ public abstract class FontLoader { * @param fontFile the File representation of the font * @param subFontName the sub-fontname of a font (for TrueType Collections, null otherwise) * @param embedded indicates whether the font is embedded or referenced + * @param encodingMode the requested encoding mode * @param resolver the font resolver to use when resolving URIs * @return the newly loaded font * @throws IOException In case of an I/O error */ public static CustomFont loadFont(File fontFile, String subFontName, - boolean embedded, FontResolver resolver) throws IOException { - return loadFont(fontFile.getAbsolutePath(), subFontName, embedded, resolver); + boolean embedded, EncodingMode encodingMode, FontResolver resolver) throws IOException { + return loadFont(fontFile.getAbsolutePath(), subFontName, embedded, encodingMode, resolver); } /** @@ -89,13 +90,14 @@ public abstract class FontLoader { * @param fontUrl the URL representation of the font * @param subFontName the sub-fontname of a font (for TrueType Collections, null otherwise) * @param embedded indicates whether the font is embedded or referenced + * @param encodingMode the requested encoding mode * @param resolver the font resolver to use when resolving URIs * @return the newly loaded font * @throws IOException In case of an I/O error */ public static CustomFont loadFont(URL fontUrl, String subFontName, - boolean embedded, FontResolver resolver) throws IOException { - return loadFont(fontUrl.toExternalForm(), subFontName, embedded, resolver); + boolean embedded, EncodingMode encodingMode, FontResolver resolver) throws IOException { + return loadFont(fontUrl.toExternalForm(), subFontName, embedded, encodingMode, resolver); } /** @@ -103,19 +105,24 @@ public abstract class FontLoader { * @param fontFileURI the URI to the font * @param subFontName the sub-fontname of a font (for TrueType Collections, null otherwise) * @param embedded indicates whether the font is embedded or referenced + * @param encodingMode the requested encoding mode * @param resolver the font resolver to use when resolving URIs * @return the newly loaded font * @throws IOException In case of an I/O error */ public static CustomFont loadFont(String fontFileURI, String subFontName, - boolean embedded, FontResolver resolver) throws IOException { + boolean embedded, EncodingMode encodingMode, FontResolver resolver) throws IOException { fontFileURI = fontFileURI.trim(); boolean type1 = isType1(fontFileURI); FontLoader loader; if (type1) { + if (encodingMode == EncodingMode.CID) { + throw new IllegalArgumentException( + "CID encoding mode not supported for Type 1 fonts"); + } loader = new Type1FontLoader(fontFileURI, embedded, resolver); } else { - loader = new TTFFontLoader(fontFileURI, subFontName, embedded, resolver); + loader = new TTFFontLoader(fontFileURI, subFontName, embedded, encodingMode, resolver); } return loader.getFont(); } diff --git a/src/java/org/apache/fop/fonts/LazyFont.java b/src/java/org/apache/fop/fonts/LazyFont.java index ebf31f258..c18ed6965 100644 --- a/src/java/org/apache/fop/fonts/LazyFont.java +++ b/src/java/org/apache/fop/fonts/LazyFont.java @@ -44,6 +44,7 @@ public class LazyFont extends Typeface implements FontDescriptor { private String metricsFileName = null; private String fontEmbedPath = null; private boolean useKerning = false; + private EncodingMode encodingMode = EncodingMode.AUTO; private boolean embedded = true; private String subFontName = null; @@ -63,6 +64,7 @@ public class LazyFont extends Typeface implements FontDescriptor { this.metricsFileName = fontInfo.getMetricsFile(); this.fontEmbedPath = fontInfo.getEmbedFile(); this.useKerning = fontInfo.getKerning(); + this.encodingMode = fontInfo.getEncodingMode(); this.subFontName = fontInfo.getSubFontName(); this.embedded = fontInfo.isEmbedded(); this.resolver = resolver; @@ -130,7 +132,7 @@ public class LazyFont extends Typeface implements FontDescriptor { throw new RuntimeException("Cannot load font. No font URIs available."); } realFont = FontLoader.loadFont(fontEmbedPath, this.subFontName, - this.embedded, resolver); + this.embedded, this.encodingMode, resolver); } if (realFont instanceof FontDescriptor) { realFontDescriptor = (FontDescriptor) realFont; diff --git a/src/java/org/apache/fop/fonts/SimpleSingleByteEncoding.java b/src/java/org/apache/fop/fonts/SimpleSingleByteEncoding.java index 6517f0328..d55529d58 100644 --- a/src/java/org/apache/fop/fonts/SimpleSingleByteEncoding.java +++ b/src/java/org/apache/fop/fonts/SimpleSingleByteEncoding.java @@ -25,6 +25,8 @@ import java.util.Map; import org.apache.xmlgraphics.fonts.Glyphs; +import org.apache.fop.util.CharUtilities; + /** * A simple implementation of the OneByteEncoding mostly used for encodings that are constructed * on-the-fly. @@ -138,6 +140,18 @@ public class SimpleSingleByteEncoding implements SingleByteEncoding { } /** {@inheritDoc} */ + public char[] getUnicodeCharMap() { + char[] map = new char[getLastChar() + 1]; + for (int i = 0; i < getFirstChar(); i++) { + map[i] = CharUtilities.NOT_A_CHARACTER; + } + for (int i = getFirstChar(); i <= getLastChar(); i++) { + map[i] = getCharacterForIndex(i).getSingleUnicodeValue(); + } + return map; + } + + /** {@inheritDoc} */ public String toString() { return getName() + " (" + getSize() + " chars)"; } diff --git a/src/java/org/apache/fop/fonts/SingleByteEncoding.java b/src/java/org/apache/fop/fonts/SingleByteEncoding.java index bc680f983..ad9d691f6 100644 --- a/src/java/org/apache/fop/fonts/SingleByteEncoding.java +++ b/src/java/org/apache/fop/fonts/SingleByteEncoding.java @@ -47,4 +47,12 @@ public interface SingleByteEncoding { */ String[] getCharNameMap(); + /** + * Returns a character array with Unicode scalar values which can be used to map encoding + * code points to Unicode values. Note that this does not return all possible Unicode values + * that the encoding maps. + * @return a character array with Unicode scalar values + */ + char[] getUnicodeCharMap(); + } diff --git a/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java b/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java index d0ff4a287..951ebdcff 100644 --- a/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java +++ b/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java @@ -33,6 +33,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.fonts.CustomFont; import org.apache.fop.fonts.EmbedFontInfo; +import org.apache.fop.fonts.EncodingMode; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontCache; import org.apache.fop.fonts.FontEventListener; @@ -224,7 +225,7 @@ public class FontInfoFinder { } try { TTFFontLoader ttfLoader = new TTFFontLoader( - fontFileURI, fontName, true, resolver); + fontFileURI, fontName, true, EncodingMode.AUTO, resolver); customFont = ttfLoader.getFont(); if (this.eventListener != null) { customFont.setEventListener(this.eventListener); @@ -248,7 +249,7 @@ public class FontInfoFinder { } else { // The normal case try { - customFont = FontLoader.loadFont(fontUrl, null, true, resolver); + customFont = FontLoader.loadFont(fontUrl, null, true, EncodingMode.AUTO, resolver); if (this.eventListener != null) { customFont.setEventListener(this.eventListener); } diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java b/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java index e14514b51..cbf9c9d17 100644 --- a/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java +++ b/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java @@ -31,6 +31,7 @@ import org.apache.xmlgraphics.fonts.Glyphs; import org.apache.fop.fonts.BFEntry; import org.apache.fop.fonts.CIDFontType; +import org.apache.fop.fonts.EncodingMode; import org.apache.fop.fonts.FontLoader; import org.apache.fop.fonts.FontResolver; import org.apache.fop.fonts.FontType; @@ -46,6 +47,7 @@ public class TTFFontLoader extends FontLoader { private MultiByteFont multiFont; private SingleByteFont singleFont; private String subFontName; + private EncodingMode encodingMode; /** * Default constructor @@ -53,7 +55,7 @@ public class TTFFontLoader extends FontLoader { * @param resolver the FontResolver for font URI resolution */ public TTFFontLoader(String fontFileURI, FontResolver resolver) { - this(fontFileURI, null, true, resolver); + this(fontFileURI, null, true, EncodingMode.AUTO, resolver); } /** @@ -62,12 +64,17 @@ public class TTFFontLoader extends FontLoader { * @param subFontName the sub-fontname of a font in a TrueType Collection (or null for normal * TrueType fonts) * @param embedded indicates whether the font is embedded or referenced + * @param encodingMode the requested encoding mode * @param resolver the FontResolver for font URI resolution */ public TTFFontLoader(String fontFileURI, String subFontName, - boolean embedded, FontResolver resolver) { + boolean embedded, EncodingMode encodingMode, FontResolver resolver) { super(fontFileURI, embedded, resolver); this.subFontName = subFontName; + this.encodingMode = encodingMode; + if (this.encodingMode == EncodingMode.AUTO) { + this.encodingMode = EncodingMode.CID; //Default to CID mode for TrueType + } } /** {@inheritDoc} */ @@ -105,6 +112,9 @@ public class TTFFontLoader extends FontLoader { } boolean isCid = this.embedded; + if (this.encodingMode == EncodingMode.SINGLE_BYTE) { + isCid = false; + } if (isCid) { multiFont = new MultiByteFont(); @@ -156,7 +166,7 @@ public class TTFFontLoader extends FontLoader { copyKerning(ttf, isCid); if (this.embedded && ttf.isEmbeddable()) { - multiFont.setEmbedFileName(this.fontFileURI); + returnFont.setEmbedFileName(this.fontFileURI); } } diff --git a/src/java/org/apache/fop/pdf/CMapBuilder.java b/src/java/org/apache/fop/pdf/CMapBuilder.java index 8e30ad04a..affb4fcad 100644 --- a/src/java/org/apache/fop/pdf/CMapBuilder.java +++ b/src/java/org/apache/fop/pdf/CMapBuilder.java @@ -110,8 +110,16 @@ public class CMapBuilder { } protected void writeCodeSpaceRange() throws IOException { + writeCodeSpaceRange(false); + } + + protected void writeCodeSpaceRange(boolean singleByte) throws IOException { writer.write("1 begincodespacerange\n"); - writer.write("<0000> <FFFF>\n"); + if (singleByte) { + writer.write("<00> <FF>\n"); + } else { + writer.write("<0000> <FFFF>\n"); + } writer.write("endcodespacerange\n"); } diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java index a5beb4ec7..b820e12fe 100644 --- a/src/java/org/apache/fop/pdf/PDFFactory.java +++ b/src/java/org/apache/fop/pdf/PDFFactory.java @@ -1227,10 +1227,23 @@ public class PDFFactory { return preRegisteredfont; } + boolean forceToUnicode = true; + if (descriptor == null) { //Usually Base 14 fonts PDFFont font = new PDFFont(fontname, FontType.TYPE1, basefont, encoding); getDocument().registerObject(font); + if (forceToUnicode && !PDFEncoding.isPredefinedEncoding(encoding)) { + SingleByteEncoding mapping; + if (encoding != null) { + mapping = CodePointMapping.getMapping(encoding); + } else { + //for Symbol and ZapfDingbats where encoding must be null in PDF + Typeface tf = (Typeface)metrics; + mapping = CodePointMapping.getMapping(tf.getEncodingName()); + } + generateToUnicodeCmap(font, mapping); + } return font; } else { FontType fonttype = metrics.getFontType(); @@ -1266,7 +1279,7 @@ public class PDFFactory { "fop-ucs-H", new PDFCIDSystemInfo("Adobe", "Identity", - 0)); + 0), false); getDocument().registerObject(cmap); ((PDFFontType0)font).setCMAP(cmap); ((PDFFontType0)font).setDescendantFonts(cidFont); @@ -1290,8 +1303,13 @@ public class PDFFactory { SingleByteEncoding mapping = singleByteFont.getEncoding(); if (singleByteFont.isSymbolicFont()) { //no encoding, use the font's encoding + if (forceToUnicode) { + generateToUnicodeCmap(nonBase14, mapping); + } } else if (PDFEncoding.isPredefinedEncoding(mapping.getName())) { font.setEncoding(mapping.getName()); + //No ToUnicode CMap necessary if PDF 1.4, chapter 5.9 (page 368) is to be + //believed. } else { Object pdfEncoding = createPDFEncoding(mapping, singleByteFont.getFontName()); @@ -1300,16 +1318,9 @@ public class PDFFactory { } else { font.setEncoding((String)pdfEncoding); } - - /* JM: What I thought would be a necessity with custom encodings turned out to - * be a bug in Adobe Acrobat 8. The following section just demonstrates how - * to generate a ToUnicode CMap for a Type 1 font. - PDFCMap cmap = new PDFToUnicodeCMap(mapping.getUnicodeCharMap(), - "fop-ucs-H", - new PDFCIDSystemInfo("Adobe", "Identity", 0)); - getDocument().registerObject(cmap); - nonBase14.setToUnicode(cmap); - */ + if (forceToUnicode) { + generateToUnicodeCmap(nonBase14, mapping); + } } //Handle additional encodings (characters outside the primary encoding) @@ -1330,6 +1341,9 @@ public class PDFFactory { new PDFArray(null, singleByteFont.getAdditionalWidths(i))); getDocument().registerObject(addFont); getDocument().getResources().addFont(addFont); + if (forceToUnicode) { + generateToUnicodeCmap(addFont, addEncoding); + } } } } @@ -1338,6 +1352,14 @@ public class PDFFactory { } } + private void generateToUnicodeCmap(PDFFont font, SingleByteEncoding encoding) { + PDFCMap cmap = new PDFToUnicodeCMap(encoding.getUnicodeCharMap(), + "fop-ucs-H", + new PDFCIDSystemInfo("Adobe", "Identity", 0), true); + getDocument().registerObject(cmap); + font.setToUnicode(cmap); + } + /** * Creates a PDFEncoding instance from a CodePointMapping instance. * @param encoding the code point mapping (encoding) diff --git a/src/java/org/apache/fop/pdf/PDFFont.java b/src/java/org/apache/fop/pdf/PDFFont.java index 6ba6ab9a2..2808e5ba7 100644 --- a/src/java/org/apache/fop/pdf/PDFFont.java +++ b/src/java/org/apache/fop/pdf/PDFFont.java @@ -86,6 +86,14 @@ public class PDFFont extends PDFDictionary { } /** + * Sets a ToUnicode CMap. + * @param cmap the ToUnicode character map + */ + public void setToUnicode(PDFCMap cmap) { + put("ToUnicode", cmap); + } + + /** * factory method with the basic parameters * * @param fontname the internal name for the font diff --git a/src/java/org/apache/fop/pdf/PDFFontNonBase14.java b/src/java/org/apache/fop/pdf/PDFFontNonBase14.java index 9b6cef618..79ed10f48 100644 --- a/src/java/org/apache/fop/pdf/PDFFontNonBase14.java +++ b/src/java/org/apache/fop/pdf/PDFFontNonBase14.java @@ -71,14 +71,6 @@ public abstract class PDFFontNonBase14 extends PDFFont { return (PDFFontDescriptor)get("FontDescriptor"); } - /** - * Sets a ToUnicode CMap. - * @param cmap the ToUnicode character map - */ - public void setToUnicode(PDFCMap cmap) { - put("ToUnicode", cmap); - } - /** {@inheritDoc} */ protected void validate() { if (getDocumentSafely().getProfile().isFontEmbeddingRequired()) { diff --git a/src/java/org/apache/fop/pdf/PDFToUnicodeCMap.java b/src/java/org/apache/fop/pdf/PDFToUnicodeCMap.java index b70430af4..95999b73f 100644 --- a/src/java/org/apache/fop/pdf/PDFToUnicodeCMap.java +++ b/src/java/org/apache/fop/pdf/PDFToUnicodeCMap.java @@ -43,6 +43,8 @@ public class PDFToUnicodeCMap extends PDFCMap { */ protected char[] unicodeCharMap; + private boolean singleByte; + /** * Constructor. * @@ -51,10 +53,17 @@ public class PDFToUnicodeCMap extends PDFCMap { * @param name One of the registered names found in Table 5.14 in PDF * Reference, Second Edition. * @param sysInfo The attributes of the character collection of the CIDFont. + * @param singleByte true for single-byte, false for double-byte */ - public PDFToUnicodeCMap(char[] unicodeCharMap, String name, PDFCIDSystemInfo sysInfo) { + public PDFToUnicodeCMap(char[] unicodeCharMap, String name, PDFCIDSystemInfo sysInfo, + boolean singleByte) { super(name, sysInfo); + if (singleByte && unicodeCharMap.length > 256) { + throw new IllegalArgumentException("unicodeCharMap may not contain more than" + + " 256 characters for single-byte encodings"); + } this.unicodeCharMap = unicodeCharMap; + this.singleByte = singleByte; } /** {@inheritDoc} */ @@ -78,7 +87,7 @@ public class PDFToUnicodeCMap extends PDFCMap { writeCIDSystemInfo("Adobe", "UCS", 0); writeName("Adobe-Identity-UCS"); writeType("2"); - writeCodeSpaceRange(); + writeCodeSpaceRange(singleByte); writeBFEntries(); writeWrapUp(); } @@ -122,7 +131,7 @@ public class PDFToUnicodeCMap extends PDFCMap { while (partOfRange(charArray, charIndex)) { charIndex++; } - writer.write("<" + padHexString(Integer.toHexString(charIndex), 4) + "> "); + writer.write("<" + padCharIndex(charIndex) + "> "); writer.write("<" + padHexString(Integer.toHexString(charArray[charIndex]), 4) + ">\n"); charIndex++; @@ -132,6 +141,10 @@ public class PDFToUnicodeCMap extends PDFCMap { } while (remainingEntries > 0); } + private String padCharIndex(int charIndex) { + return padHexString(Integer.toHexString(charIndex), (singleByte ? 2 : 4)); + } + /** * Writes the entries for character ranges for a base font. * @param p StringBuffer to write to @@ -159,9 +172,9 @@ public class PDFToUnicodeCMap extends PDFCMap { while (!startOfRange(charArray, charIndex)) { charIndex++; } - writer.write("<" + padHexString(Integer.toHexString(charIndex), 4) + "> "); + writer.write("<" + padCharIndex(charIndex) + "> "); writer.write("<" - + padHexString(Integer.toHexString(endOfRange(charArray, charIndex)), 4) + + padCharIndex(endOfRange(charArray, charIndex)) + "> "); writer.write("<" + padHexString(Integer.toHexString(charArray[charIndex]), 4) + ">\n"); diff --git a/src/java/org/apache/fop/render/PrintRendererConfigurator.java b/src/java/org/apache/fop/render/PrintRendererConfigurator.java index 806331e88..e01750b99 100644 --- a/src/java/org/apache/fop/render/PrintRendererConfigurator.java +++ b/src/java/org/apache/fop/render/PrintRendererConfigurator.java @@ -42,6 +42,7 @@ import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FopFactory; import org.apache.fop.fonts.EmbedFontInfo; +import org.apache.fop.fonts.EncodingMode; import org.apache.fop.fonts.FontCache; import org.apache.fop.fonts.FontEventAdapter; import org.apache.fop.fonts.FontEventListener; @@ -425,8 +426,11 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator } boolean useKerning = fontCfg.getAttributeAsBoolean("kerning", true); + EncodingMode encodingMode = EncodingMode.valueOf( + fontCfg.getAttribute("encoding-mode", EncodingMode.AUTO.getName())); EmbedFontInfo embedFontInfo = new EmbedFontInfo(metricsUrl, useKerning, tripletList, embedUrl, subFont); + embedFontInfo.setEncodingMode(encodingMode); if (fontCache != null) { if (!fontCache.containsFont(embedFontInfo)) { fontCache.addFont(embedFontInfo); diff --git a/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java b/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java index 26d64af74..9f96087b9 100644 --- a/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java +++ b/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java @@ -28,6 +28,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.fonts.CustomFont; import org.apache.fop.fonts.EmbedFontInfo; +import org.apache.fop.fonts.EncodingMode; import org.apache.fop.fonts.FontCollection; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontLoader; @@ -87,7 +88,7 @@ public class ConfiguredFontCollection implements FontCollection { font = new CustomFontMetricsMapper(fontMetrics, fontSource); } else { CustomFont fontMetrics = FontLoader.loadFont( - fontFile, null, true, fontResolver); + fontFile, null, true, EncodingMode.AUTO, fontResolver); font = new CustomFontMetricsMapper(fontMetrics); } |