aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2009-01-05 07:59:39 +0000
committerJeremias Maerki <jeremias@apache.org>2009-01-05 07:59:39 +0000
commitc0028134f8261116cbfd1a263f8e28456a81522e (patch)
tree8c076130ae9be0cc0871132b5fb2348dbedc05ff
parent011fd36fcef0003a63e9dc8da3233fd18c7889fb (diff)
parent68dd1750c65ec6ce5475f2f12ea63f6495a708ad (diff)
downloadxmlgraphics-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
-rw-r--r--src/documentation/content/xdocs/trunk/fonts.xml11
-rw-r--r--src/foschema/fop-configuration.xsd9
-rw-r--r--src/java/org/apache/fop/fo/FObj.java6
-rw-r--r--src/java/org/apache/fop/fo/flow/AbstractRetrieveMarker.java8
-rwxr-xr-xsrc/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java21
-rw-r--r--src/java/org/apache/fop/fonts/AbstractCodePointMapping.java7
-rw-r--r--src/java/org/apache/fop/fonts/EmbedFontInfo.java29
-rw-r--r--src/java/org/apache/fop/fonts/EncodingMode.java82
-rw-r--r--src/java/org/apache/fop/fonts/FontLoader.java19
-rw-r--r--src/java/org/apache/fop/fonts/LazyFont.java4
-rw-r--r--src/java/org/apache/fop/fonts/SimpleSingleByteEncoding.java14
-rw-r--r--src/java/org/apache/fop/fonts/SingleByteEncoding.java8
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java5
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java16
-rw-r--r--src/java/org/apache/fop/pdf/CMapBuilder.java10
-rw-r--r--src/java/org/apache/fop/pdf/PDFFactory.java44
-rw-r--r--src/java/org/apache/fop/pdf/PDFFont.java8
-rw-r--r--src/java/org/apache/fop/pdf/PDFFontNonBase14.java8
-rw-r--r--src/java/org/apache/fop/pdf/PDFToUnicodeCMap.java23
-rw-r--r--src/java/org/apache/fop/render/PrintRendererConfigurator.java4
-rw-r--r--src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java3
-rw-r--r--status.xml11
-rw-r--r--test/layoutengine/disabled-testcases.xml5
23 files changed, 293 insertions, 62 deletions
diff --git a/src/documentation/content/xdocs/trunk/fonts.xml b/src/documentation/content/xdocs/trunk/fonts.xml
index 758a537cc..165487e73 100644
--- a/src/documentation/content/xdocs/trunk/fonts.xml
+++ b/src/documentation/content/xdocs/trunk/fonts.xml
@@ -367,7 +367,9 @@
<renderer mime="application/pdf">
<fonts>
<!-- register a particular font -->
- <font metrics-url="file:///C:/myfonts/FTL_____.xml" kerning="yes" embed-url="file:///C:/myfonts/FTL_____.pfb">
+ <font metrics-url="file:///C:/myfonts/FTL_____.xml" kerning="yes"
+ embed-url="file:///C:/myfonts/FTL_____.pfb"
+ encoding-mode="single-byte">
<font-triplet name="FrutigerLight" style="normal" weight="normal"/>
</font>
@@ -393,6 +395,13 @@
<li>The font "kerning" attribute is optional. Default is "true".</li>
<li>If embedding is off (i.e. embed-url is not set), the output will position the text correctly (from the metrics file), but it will not be displayed or printed correctly unless the viewer has the applicable font available to their local system.</li>
<li>When setting the "embed-url" attribute for Type 1 fonts, be sure to specify the PFB (actual font data), not PFM (font metrics) file that you used to generate the XML font metrics file.</li>
+ <li>The attribute "encoding-mode" is optional an may have the following values:
+ <ul>
+ <li>auto: default font encoding mode ("cid" for Truetype, "single-byte" for Type 1)</li>
+ <li>single-byte: use single-byte encodings in the target format (if applicable)</li>
+ <li>cid: encode as CID-keyed font (currently only supported for PDF output with TrueType fonts)</li>
+ </ul>
+ </li>
<li>The fonts "directory" tag can be used to register fonts contained within a single or list of directory paths. The "recursive" attribute can be specified to recursively add fonts from all sub directories.</li>
<li>The fonts "auto-detect" tag can be used to automatically register fonts that are found to be installed on the native operating system.</li>
<li>Fonts registered with "font" tag configurations override fonts found by means of "directory" tag definitions.</li>
diff --git a/src/foschema/fop-configuration.xsd b/src/foschema/fop-configuration.xsd
index 94f690342..9ceec1717 100644
--- a/src/foschema/fop-configuration.xsd
+++ b/src/foschema/fop-configuration.xsd
@@ -219,6 +219,15 @@
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
+ <xsd:attribute name="encoding-mode" use="optional" default="auto">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="auto"/>
+ <xsd:enumeration value="single-byte"/>
+ <xsd:enumeration value="cid"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
</xsd:complexType>
<xsd:complexType name="fontTripletType">
<xsd:attribute name="name" type="xsd:string" use="required"/>
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);
}
diff --git a/status.xml b/status.xml
index 6d9373a9f..2a3f7a20f 100644
--- a/status.xml
+++ b/status.xml
@@ -53,6 +53,17 @@
<changes>
<release version="FOP Trunk" date="TBD">
+ <action context="Fonts" dev="JM" type="add">
+ FOP now creates ToUnicode CMaps for single-byte fonts that don't use built-in
+ encodings to help PDF text extractors interpreting characters.
+ </action>
+ <action context="Fonts" dev="JM" type="add">
+ Added support for forcing single-byte encodings for TrueType fonts without
+ creating an XML font metric file (see "encoding-mode" attribute on "font" element)
+ </action>
+ <action context="Layout" dev="JM" type="fix" fixes-bug="45306">
+ Fixed fo:instream-foreign-object inside fo:marker.
+ </action>
<action context="Renderers" dev="JM" type="fix">
Fixed black backgrounds occurring for transparent images in PCL output.
</action>
diff --git a/test/layoutengine/disabled-testcases.xml b/test/layoutengine/disabled-testcases.xml
index 7bf441d5b..ca05b156b 100644
--- a/test/layoutengine/disabled-testcases.xml
+++ b/test/layoutengine/disabled-testcases.xml
@@ -223,9 +223,4 @@
relaxed validation must be switched on, otherwise there is a validation
exception.</description>
</testcase>
- <testcase>
- <name>Instream foreign objects in markers</name>
- <file>marker_instream-foreign-object.xml</file>
- <description>Foreign objects in markers do not work.</description>
- </testcase>
</disabled-testcases>