aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org
diff options
context:
space:
mode:
authorSimon Steiner <ssteiner@apache.org>2015-08-06 10:59:51 +0000
committerSimon Steiner <ssteiner@apache.org>2015-08-06 10:59:51 +0000
commit2e1089dd671b8d2283d245972a1bfd93e9d0daa0 (patch)
treea42ccd3102480265dad7442c165b137509e33af5 /src/java/org
parentcc829b9753aafc5fca96ea4e633433cfbc2795bd (diff)
downloadxmlgraphics-fop-2e1089dd671b8d2283d245972a1bfd93e9d0daa0.tar.gz
xmlgraphics-fop-2e1089dd671b8d2283d245972a1bfd93e9d0daa0.zip
FOP-2504: Truetype support for AFP
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1694450 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org')
-rw-r--r--src/java/org/apache/fop/afp/AFPResourceManager.java91
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSet.java8
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java6
-rw-r--r--src/java/org/apache/fop/afp/fonts/FopCharacterSet.java6
-rw-r--r--src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java8
-rw-r--r--src/java/org/apache/fop/afp/modca/ActiveEnvironmentGroup.java110
-rw-r--r--src/java/org/apache/fop/afp/modca/MapDataResource.java43
-rw-r--r--src/java/org/apache/fop/afp/modca/ObjectContainer.java2
-rw-r--r--src/java/org/apache/fop/afp/modca/Registry.java24
-rw-r--r--src/java/org/apache/fop/afp/modca/triplets/FullyQualifiedNameTriplet.java13
-rw-r--r--src/java/org/apache/fop/render/afp/AFPDocumentHandler.java2
-rw-r--r--src/java/org/apache/fop/render/afp/AFPFontConfig.java84
-rw-r--r--src/java/org/apache/fop/render/afp/AFPPainter.java16
13 files changed, 350 insertions, 63 deletions
diff --git a/src/java/org/apache/fop/afp/AFPResourceManager.java b/src/java/org/apache/fop/afp/AFPResourceManager.java
index fc34925d2..d4df8daab 100644
--- a/src/java/org/apache/fop/afp/AFPResourceManager.java
+++ b/src/java/org/apache/fop/afp/AFPResourceManager.java
@@ -36,15 +36,21 @@ import org.apache.fop.afp.fonts.AFPFont;
import org.apache.fop.afp.fonts.CharacterSet;
import org.apache.fop.afp.modca.AbstractNamedAFPObject;
import org.apache.fop.afp.modca.AbstractPageObject;
+import org.apache.fop.afp.modca.ActiveEnvironmentGroup;
import org.apache.fop.afp.modca.IncludeObject;
import org.apache.fop.afp.modca.IncludedResourceObject;
+import org.apache.fop.afp.modca.ObjectContainer;
import org.apache.fop.afp.modca.PageSegment;
import org.apache.fop.afp.modca.Registry;
import org.apache.fop.afp.modca.ResourceGroup;
import org.apache.fop.afp.modca.ResourceObject;
+import org.apache.fop.afp.modca.triplets.EncodingTriplet;
+import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet;
import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.afp.util.AFPResourceUtil;
import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.fonts.FontType;
+import org.apache.fop.render.afp.AFPFontConfig;
/**
* Manages the creation and storage of document resources
@@ -330,12 +336,19 @@ public class AFPResourceManager {
//Embed fonts (char sets and code pages)
if (charSet.getResourceAccessor() != null) {
AFPResourceAccessor accessor = charSet.getResourceAccessor();
- createIncludedResource(
- charSet.getName(), accessor,
- ResourceObject.TYPE_FONT_CHARACTER_SET);
- createIncludedResource(
- charSet.getCodePage(), accessor,
- ResourceObject.TYPE_CODE_PAGE);
+ if (afpFont.getFontType() == FontType.TRUETYPE) {
+
+ createIncludedResource(afpFont.getFontName(), accessor.resolveURI("."), accessor,
+ ResourceObject.TYPE_OBJECT_CONTAINER, true,
+ ((AFPFontConfig.AFPTrueTypeFont) afpFont).getTTC());
+ } else {
+ createIncludedResource(
+ charSet.getName(), accessor,
+ ResourceObject.TYPE_FONT_CHARACTER_SET);
+ createIncludedResource(
+ charSet.getCodePage(), accessor,
+ ResourceObject.TYPE_CODE_PAGE);
+ }
}
}
}
@@ -366,7 +379,7 @@ public class AFPResourceManager {
+ " (" + e.getMessage() + ")");
}
- createIncludedResource(resourceName, uri, accessor, resourceObjectType);
+ createIncludedResource(resourceName, uri, accessor, resourceObjectType, false, null);
}
/**
@@ -378,7 +391,7 @@ public class AFPResourceManager {
* @throws IOException if an I/O error occurs while loading the resource
*/
public void createIncludedResource(String resourceName, URI uri, AFPResourceAccessor accessor,
- byte resourceObjectType) throws IOException {
+ byte resourceObjectType, boolean truetype, String ttc) throws IOException {
AFPResourceLevel resourceLevel = new AFPResourceLevel(ResourceType.PRINT_FILE);
AFPResourceInfo resourceInfo = new AFPResourceInfo();
@@ -391,15 +404,46 @@ public class AFPResourceManager {
if (log.isDebugEnabled()) {
log.debug("Adding included resource: " + resourceName);
}
- IncludedResourceObject resourceContent = new IncludedResourceObject(
- resourceName, accessor, uri);
-
- ResourceObject resourceObject = factory.createResource(resourceName);
- resourceObject.setDataObject(resourceContent);
- resourceObject.setType(resourceObjectType);
ResourceGroup resourceGroup = streamer.getResourceGroup(resourceLevel);
- resourceGroup.addObject(resourceObject);
+
+ if (truetype) {
+ ResourceObject res = factory.createResource();
+ res.setType(ResourceObject.TYPE_OBJECT_CONTAINER);
+
+ ActiveEnvironmentGroup.setupTruetypeMDR(res, false);
+
+ ObjectContainer oc = factory.createObjectContainer();
+ InputStream is;
+ try {
+ is = accessor.createInputStream(new URI("."));
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
+
+ if (ttc != null) {
+ oc.setData(extractTTC(ttc, is));
+ } else {
+ oc.setData(IOUtils.toByteArray(is));
+ }
+
+ ActiveEnvironmentGroup.setupTruetypeMDR(oc, true);
+
+ res.addTriplet(new EncodingTriplet(1200));
+
+ res.setFullyQualifiedName(FullyQualifiedNameTriplet.TYPE_REPLACE_FIRST_GID_NAME,
+ FullyQualifiedNameTriplet.FORMAT_CHARSTR, resourceName, true);
+
+ res.setDataObject(oc);
+ resourceGroup.addObject(res);
+ } else {
+ ResourceObject resourceObject = factory.createResource(resourceName);
+ IncludedResourceObject resourceContent = new IncludedResourceObject(
+ resourceName, accessor, uri);
+ resourceObject.setDataObject(resourceContent);
+ resourceObject.setType(resourceObjectType);
+ resourceGroup.addObject(resourceObject);
+ }
//TODO what is the data object?
cachedObject = new CachedObject(resourceName, null);
@@ -411,6 +455,23 @@ public class AFPResourceManager {
}
}
+ private byte[] extractTTC(String ttc, InputStream is) throws IOException {
+// TrueTypeCollection trueTypeCollection = new TrueTypeCollection(is);
+// for (TrueTypeFont ttf : trueTypeCollection.getFonts()) {
+// String name = ttf.getNaming().getFontFamily();
+// if (name.equals(ttc)) {
+// ByteArrayOutputStream bos = new ByteArrayOutputStream();
+// TTFSubsetter s = new TTFSubsetter(ttf, null);
+// for (int i = 0; i < 256 * 256; i++) {
+// s.addCharCode(i);
+// }
+// s.writeToStream(bos);
+// return bos.toByteArray();
+// }
+// }
+ throw new IOException(ttc + " not supported");
+ }
+
/**
* Creates an included resource extracting the named resource from an external source.
* @param resourceName the name of the resource
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSet.java b/src/java/org/apache/fop/afp/fonts/CharacterSet.java
index d57b14ed7..593b40592 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSet.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSet.java
@@ -108,8 +108,12 @@ public class CharacterSet {
// the character set name must be 8 chars long
this.name = padName(name);
- // the code page name must be 8 chars long
- this.codePage = padName(codePage);
+ if (codePage == null) {
+ this.codePage = null;
+ } else {
+ // the code page name must be 8 chars long
+ this.codePage = padName(codePage);
+ }
this.encoding = encoding;
this.encoder = charsetType.getEncoder(encoding);
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
index e7b9041ba..39d2be845 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
@@ -232,6 +232,12 @@ public abstract class CharacterSetBuilder {
eventProducer);
}
+ public CharacterSet build(String characterSetName, String codePageName, String encoding,
+ Typeface typeface, AFPResourceAccessor accessor, AFPEventProducer eventProducer)
+ throws IOException {
+ return new FopCharacterSet(codePageName, encoding, characterSetName, typeface, accessor, eventProducer);
+ }
+
private CharacterSet processFont(String characterSetName, String codePageName, String encoding,
CharacterSetType charsetType, AFPResourceAccessor accessor, AFPEventProducer eventProducer)
throws IOException {
diff --git a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
index d3af78f7b..9d53cc7ea 100644
--- a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
+++ b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
@@ -49,6 +49,12 @@ public class FopCharacterSet extends CharacterSet {
this.charSet = charSet;
}
+ public FopCharacterSet(String codePage, String encoding, String name, Typeface charSet,
+ AFPResourceAccessor accessor, AFPEventProducer eventProducer) {
+ super(codePage, encoding, CharacterSetType.SINGLE_BYTE, name, accessor, eventProducer);
+ this.charSet = charSet;
+ }
+
/**
* Ascender height is the distance from the character baseline to the
* top of the character box. A negative ascender height signifies that
diff --git a/src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java b/src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java
index 662b344c1..d840e2077 100644
--- a/src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java
+++ b/src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java
@@ -103,7 +103,7 @@ public abstract class AbstractTripletStructuredObject extends AbstractStructured
*
* @param triplet the triplet to add
*/
- protected void addTriplet(AbstractTriplet triplet) {
+ public void addTriplet(AbstractTriplet triplet) {
triplets.add(triplet);
}
@@ -131,7 +131,11 @@ public abstract class AbstractTripletStructuredObject extends AbstractStructured
* @param fqName the fully qualified name of this resource
*/
public void setFullyQualifiedName(byte fqnType, byte fqnFormat, String fqName) {
- addTriplet(new FullyQualifiedNameTriplet(fqnType, fqnFormat, fqName));
+ addTriplet(new FullyQualifiedNameTriplet(fqnType, fqnFormat, fqName, false));
+ }
+
+ public void setFullyQualifiedName(byte fqnType, byte fqnFormat, String fqName, boolean utf16be) {
+ addTriplet(new FullyQualifiedNameTriplet(fqnType, fqnFormat, fqName, utf16be));
}
/** @return the fully qualified name of this triplet or null if it does not exist */
diff --git a/src/java/org/apache/fop/afp/modca/ActiveEnvironmentGroup.java b/src/java/org/apache/fop/afp/modca/ActiveEnvironmentGroup.java
index 05f48b47c..48eaa0a40 100644
--- a/src/java/org/apache/fop/afp/modca/ActiveEnvironmentGroup.java
+++ b/src/java/org/apache/fop/afp/modca/ActiveEnvironmentGroup.java
@@ -23,8 +23,17 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
+import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.Factory;
import org.apache.fop.afp.fonts.AFPFont;
+import org.apache.fop.afp.modca.triplets.AbstractTriplet;
+import org.apache.fop.afp.modca.triplets.EncodingTriplet;
+import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet;
+import org.apache.fop.afp.modca.triplets.ObjectClassificationTriplet;
+import org.apache.fop.afp.util.BinaryUtils;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.fonts.FontType;
+import org.apache.fop.render.afp.AFPFontConfig;
/**
* An Active Environment Group (AEG) is associated with each page,
@@ -63,6 +72,8 @@ public final class ActiveEnvironmentGroup extends AbstractEnvironmentGroup {
/** the resource manager */
private final Factory factory;
+ private MapDataResource mdr;
+
/**
* Constructor for the ActiveEnvironmentGroup, this takes a
* name parameter which must be 8 characters long.
@@ -169,27 +180,100 @@ public final class ActiveEnvironmentGroup extends AbstractEnvironmentGroup {
* @param orientation the orientation of the font (e.g. 0, 90, 180, 270)
*/
public void createFont(int fontRef, AFPFont font, int size, int orientation) {
- MapCodedFont mapCodedFont = getCurrentMapCodedFont();
- if (mapCodedFont == null) {
- mapCodedFont = factory.createMapCodedFont();
- mapCodedFonts.add(mapCodedFont);
- }
+ if (font.getFontType() == FontType.TRUETYPE) {
+ if (mdr == null) {
+ mdr = factory.createMapDataResource();
+ mapCodedFonts.add(mdr);
+ }
+ mdr.addTriplet(new EncodingTriplet(1200));
+ String name = font.getFontName();
+ if (((AFPFontConfig.AFPTrueTypeFont)font).getTTC() != null) {
+ name = ((AFPFontConfig.AFPTrueTypeFont)font).getTTC();
+ }
+ mdr.setFullyQualifiedName(FullyQualifiedNameTriplet.TYPE_DATA_OBJECT_EXTERNAL_RESOURCE_REF,
+ FullyQualifiedNameTriplet.FORMAT_CHARSTR, name, true);
+ mdr.addTriplet(new FontFullyQualifiedNameTriplet((byte) fontRef));
- try {
- mapCodedFont.addFont(fontRef, font, size, orientation);
- } catch (MaximumSizeExceededException msee) {
- mapCodedFont = factory.createMapCodedFont();
- mapCodedFonts.add(mapCodedFont);
+ setupTruetypeMDR(mdr, false);
+ mdr.addTriplet(new DataObjectFontTriplet(size / 1000));
+ mdr.finishElement();
+ } else {
+ MapCodedFont mapCodedFont = getCurrentMapCodedFont();
+ if (mapCodedFont == null) {
+ mapCodedFont = factory.createMapCodedFont();
+ mapCodedFonts.add(mapCodedFont);
+ }
try {
mapCodedFont.addFont(fontRef, font, size, orientation);
- } catch (MaximumSizeExceededException ex) {
- // Should never happen (but log just in case)
- LOG.error("createFont():: resulted in a MaximumSizeExceededException");
+ } catch (MaximumSizeExceededException msee) {
+ mapCodedFont = factory.createMapCodedFont();
+ mapCodedFonts.add(mapCodedFont);
+
+ try {
+ mapCodedFont.addFont(fontRef, font, size, orientation);
+ } catch (MaximumSizeExceededException ex) {
+ // Should never happen (but log just in case)
+ LOG.error("createFont():: resulted in a MaximumSizeExceededException");
+ }
}
}
}
+ public static void setupTruetypeMDR(AbstractTripletStructuredObject mdr, boolean res) {
+ AFPDataObjectInfo dataInfo = new AFPDataObjectInfo();
+ dataInfo.setMimeType(MimeConstants.MIME_AFP_TRUETYPE);
+ mdr.setObjectClassification(ObjectClassificationTriplet.CLASS_DATA_OBJECT_FONT,
+ dataInfo.getObjectType(), res, false, res);
+ }
+
+ public static class FontFullyQualifiedNameTriplet extends AbstractTriplet {
+ private byte fqName;
+ public FontFullyQualifiedNameTriplet(byte fqName) {
+ super(FULLY_QUALIFIED_NAME);
+ this.fqName = fqName;
+ }
+
+ public int getDataLength() {
+ return 5;
+ }
+
+ public void writeToStream(OutputStream os) throws IOException {
+ byte[] data = getData();
+ data[2] = FullyQualifiedNameTriplet.TYPE_DATA_OBJECT_INTERNAL_RESOURCE_REF;
+ data[3] = FullyQualifiedNameTriplet.FORMAT_CHARSTR;
+ data[4] = fqName;
+ os.write(data);
+ }
+ }
+
+ static class DataObjectFontTriplet extends AbstractTriplet {
+ private int pointSize;
+
+ public DataObjectFontTriplet(int size) {
+ super(DATA_OBJECT_FONT_DESCRIPTOR);
+ pointSize = size;
+ }
+
+ public int getDataLength() {
+ return 16;
+ }
+
+ public void writeToStream(OutputStream os) throws IOException {
+ byte[] data = getData();
+ data[3] = 0x20;
+ byte[] pointSizeBytes = BinaryUtils.convert(pointSize * 20, 2);
+ data[4] = pointSizeBytes[0]; //vfs
+ data[5] = pointSizeBytes[1];
+// data[6] = pointSizeBytes[0]; //hsf
+// data[7] = pointSizeBytes[1];
+ //charrot
+ data[11] = 0x03; //encenv
+ data[13] = 0x01; //encid
+ os.write(data);
+ }
+ }
+
/**
* Getter method for the most recent MapCodedFont added to the
* Active Environment Group (returns null if no MapCodedFonts exist)
diff --git a/src/java/org/apache/fop/afp/modca/MapDataResource.java b/src/java/org/apache/fop/afp/modca/MapDataResource.java
index 0bac920bd..c7aa758cf 100644
--- a/src/java/org/apache/fop/afp/modca/MapDataResource.java
+++ b/src/java/org/apache/fop/afp/modca/MapDataResource.java
@@ -21,7 +21,11 @@ package org.apache.fop.afp.modca;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.fop.afp.modca.triplets.AbstractTriplet;
+import org.apache.fop.afp.modca.triplets.Triplet;
import org.apache.fop.afp.util.BinaryUtils;
/**
@@ -29,6 +33,7 @@ import org.apache.fop.afp.util.BinaryUtils;
* required for presentation.
*/
public class MapDataResource extends AbstractTripletStructuredObject {
+ private List<List<AbstractTriplet>> tripletsList = new ArrayList<List<AbstractTriplet>>();
/**
* Main constructor
@@ -36,23 +41,45 @@ public class MapDataResource extends AbstractTripletStructuredObject {
public MapDataResource() {
}
+ public void finishElement() {
+ tripletsList.add(triplets);
+ triplets = new ArrayList<AbstractTriplet>();
+ }
+
+ @Override
+ protected int getTripletDataLength() {
+ int dataLength = 0;
+ for (List<AbstractTriplet> l : tripletsList) {
+ dataLength += getTripletDataLength(l) + 2;
+ }
+ return dataLength;
+ }
+
+ private int getTripletDataLength(List<AbstractTriplet> l) {
+ int dataLength = 0;
+ for (Triplet triplet : l) {
+ dataLength += triplet.getDataLength();
+ }
+ return dataLength;
+ }
+
/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
super.writeStart(os);
- byte[] data = new byte[11];
+ byte[] data = new byte[9];
copySF(data, Type.MAP, Category.DATA_RESOURCE);
int tripletDataLen = getTripletDataLength();
- byte[] len = BinaryUtils.convert(10 + tripletDataLen, 2);
+ byte[] len = BinaryUtils.convert(8 + tripletDataLen, 2);
data[1] = len[0];
data[2] = len[1];
-
- len = BinaryUtils.convert(2 + tripletDataLen, 2);
- data[9] = len[0];
- data[10] = len[1];
-
os.write(data);
- writeTriplets(os);
+
+ for (List<AbstractTriplet> l : tripletsList) {
+ len = BinaryUtils.convert(2 + getTripletDataLength(l), 2);
+ os.write(len);
+ writeObjects(l, os);
+ }
}
}
diff --git a/src/java/org/apache/fop/afp/modca/ObjectContainer.java b/src/java/org/apache/fop/afp/modca/ObjectContainer.java
index 50aabb03b..288e5aad0 100644
--- a/src/java/org/apache/fop/afp/modca/ObjectContainer.java
+++ b/src/java/org/apache/fop/afp/modca/ObjectContainer.java
@@ -36,7 +36,7 @@ import org.apache.fop.afp.util.BinaryUtils;
public class ObjectContainer extends AbstractDataObject {
/** the object container data maximum length */
- private static final int MAX_DATA_LEN = 32759;
+ private static final int MAX_DATA_LEN = 8192;
private byte[] data;
diff --git a/src/java/org/apache/fop/afp/modca/Registry.java b/src/java/org/apache/fop/afp/modca/Registry.java
index 50aaca32c..fe0a42790 100644
--- a/src/java/org/apache/fop/afp/modca/Registry.java
+++ b/src/java/org/apache/fop/afp/modca/Registry.java
@@ -174,24 +174,24 @@ public final class Registry {
MimeConstants.MIME_PCL
)
);
+ mimeObjectTypeMap.put(
+ MimeConstants.MIME_AFP_TRUETYPE,
+ new ObjectType(
+ COMPID_TRUETYPE_OPENTYPE_FONT_RESOURCE_OBJECT,
+ new byte[] {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x33},
+ "TrueType/OpenType Font Resource Object",
+ true,
+ MimeConstants.MIME_AFP_TRUETYPE
+ )
+ );
// mimeObjectTypeMap.put(
-// null,
-// new ObjectType(
-// COMPID_TRUETYPE_OPENTYPE_FONT_RESOURCE_OBJECT,
-// new byte[] {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x33},
-// "TrueType/OpenType Font Resource Object",
-// true,
-// null
-// )
-// );
-// mimeObjectTypeMap.put(
-// null,
+// MimeConstants.MIME_AFP_TTC,
// new ObjectType(
// COMPID_TRUETYPE_OPENTYPE_FONT_COLLECTION_RESOURCE_OBJECT,
// new byte[] {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x35},
// "TrueType/OpenType Font Collection Resource Object",
// true,
-// null
+// MimeConstants.MIME_AFP_TTC
// )
// );
}
diff --git a/src/java/org/apache/fop/afp/modca/triplets/FullyQualifiedNameTriplet.java b/src/java/org/apache/fop/afp/modca/triplets/FullyQualifiedNameTriplet.java
index db6d8add8..581d215b8 100644
--- a/src/java/org/apache/fop/afp/modca/triplets/FullyQualifiedNameTriplet.java
+++ b/src/java/org/apache/fop/afp/modca/triplets/FullyQualifiedNameTriplet.java
@@ -150,6 +150,10 @@ public class FullyQualifiedNameTriplet extends AbstractTriplet {
/** the actual fully qualified name */
private final String fqName;
+ private String encoding = AFPConstants.EBCIDIC_ENCODING;
+
+ private int charlen = 1;
+
/**
* Main constructor
*
@@ -157,11 +161,15 @@ public class FullyQualifiedNameTriplet extends AbstractTriplet {
* @param format the fully qualified name format
* @param fqName the fully qualified name
*/
- public FullyQualifiedNameTriplet(byte type, byte format, String fqName) {
+ public FullyQualifiedNameTriplet(byte type, byte format, String fqName, boolean utf16be) {
super(FULLY_QUALIFIED_NAME);
this.type = type;
this.format = format;
this.fqName = fqName;
+ if (utf16be) {
+ encoding = "UTF-16BE";
+ charlen = 2;
+ }
}
/**
@@ -180,7 +188,7 @@ public class FullyQualifiedNameTriplet extends AbstractTriplet {
/** {@inheritDoc} */
public int getDataLength() {
- return 4 + fqName.length();
+ return 4 + (fqName.length() * charlen);
}
/** {@inheritDoc} */
@@ -191,7 +199,6 @@ public class FullyQualifiedNameTriplet extends AbstractTriplet {
// FQName
byte[] fqNameBytes;
- String encoding = AFPConstants.EBCIDIC_ENCODING;
if (format == FORMAT_URL) {
encoding = AFPConstants.US_ASCII_ENCODING;
}
diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
index 092e2a425..a2c1389d7 100644
--- a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
+++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
@@ -399,7 +399,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
try {
getResourceManager().createIncludedResource(formMap.getName(),
formMap.getSrc(), accessor,
- ResourceObject.TYPE_FORMDEF);
+ ResourceObject.TYPE_FORMDEF, false, null);
} catch (IOException ioe) {
throw new IFException(
"I/O error while embedding form map resource: " + formMap.getName(), ioe);
diff --git a/src/java/org/apache/fop/render/afp/AFPFontConfig.java b/src/java/org/apache/fop/render/afp/AFPFontConfig.java
index 149973edd..341123331 100644
--- a/src/java/org/apache/fop/render/afp/AFPFontConfig.java
+++ b/src/java/org/apache/fop/render/afp/AFPFontConfig.java
@@ -20,6 +20,8 @@
package org.apache.fop.render.afp;
import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -42,12 +44,16 @@ import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.events.EventProducer;
+import org.apache.fop.fonts.EmbedFontInfo;
import org.apache.fop.fonts.FontConfig;
import org.apache.fop.fonts.FontManager;
import org.apache.fop.fonts.FontManagerConfigurator;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.FontTriplet.Matcher;
+import org.apache.fop.fonts.FontType;
+import org.apache.fop.fonts.FontUris;
import org.apache.fop.fonts.FontUtil;
+import org.apache.fop.fonts.LazyFont;
import org.apache.fop.fonts.Typeface;
/**
@@ -154,6 +160,13 @@ public final class AFPFontConfig implements FontConfig {
triplet.getAttribute("style"), weight);
tripletList.add(fontTriplet);
}
+
+ String tturi = fontCfg.getAttribute("embed-url", null);
+ if (tturi != null) {
+ fontFromType(tripletList, "truetype", null, "UTF-16BE", fontCfg, eventProducer, tturi);
+ return;
+ }
+
//build the fonts
Configuration[] config = fontCfg.getChildren("afp-font");
if (config.length == 0) {
@@ -199,8 +212,9 @@ public final class AFPFontConfig implements FontConfig {
embedURI);
} else if ("CIDKeyed".equalsIgnoreCase(type)) {
config = getCIDKeyedFont(fontTriplets, type, codepage, encoding, cfg,
- eventProducer,
- embedURI);
+ eventProducer, embedURI);
+ } else if ("truetype".equalsIgnoreCase(type)) {
+ config = getTruetypeFont(fontTriplets, type, codepage, encoding, cfg, eventProducer, embedURI);
} else {
LOG.error("No or incorrect type attribute: " + type);
}
@@ -240,6 +254,19 @@ public final class AFPFontConfig implements FontConfig {
name, base14, isEmbbedable(fontTriplets), uri);
}
+ private TrueTypeFontConfig getTruetypeFont(List<FontTriplet> fontTriplets, String type, String codepage,
+ String encoding, Configuration cfg, AFPEventProducer eventProducer,
+ String uri) throws ConfigurationException {
+ String name = cfg.getAttribute("name", null);
+ if (name == null) {
+ eventProducer.fontConfigMissing(this, "font name attribute", cfg.getLocation());
+ return null;
+ }
+ String subfont = cfg.getAttribute("sub-font", null);
+ return new TrueTypeFontConfig(fontTriplets, type, codepage, encoding, "",
+ name, subfont, isEmbbedable(fontTriplets), uri);
+ }
+
private RasterFontConfig getRasterFont(List<FontTriplet> triplets, String type,
String codepage, String encoding, Configuration cfg,
AFPEventProducer eventProducer, String uri)
@@ -281,12 +308,12 @@ public final class AFPFontConfig implements FontConfig {
}
abstract static class AFPFontConfigData {
- private final List<FontTriplet> triplets;
+ protected final List<FontTriplet> triplets;
private final String codePage;
private final String encoding;
private final String name;
private final boolean embeddable;
- private final String uri;
+ protected final String uri;
AFPFontConfigData(List<FontTriplet> triplets, String type, String codePage,
String encoding, String name, boolean embeddable, String uri) {
@@ -334,6 +361,55 @@ public final class AFPFontConfig implements FontConfig {
}
}
+ static final class TrueTypeFontConfig extends AFPFontConfigData {
+ private String characterset;
+ private String subfont;
+
+ private TrueTypeFontConfig(List<FontTriplet> triplets, String type, String codePage,
+ String encoding, String characterset, String name, String subfont,
+ boolean embeddable, String uri) {
+ super(triplets, type, codePage, encoding, name, embeddable, uri);
+ this.characterset = characterset;
+ this.subfont = subfont;
+ }
+
+ @Override
+ AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver, AFPEventProducer eventProducer)
+ throws IOException {
+ Typeface tf;
+ try {
+ tf = new LazyFont(new EmbedFontInfo(
+ new FontUris(new URI(uri), null)
+ , false, true, null, subfont), resourceResolver, false).getRealFont();
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
+ AFPResourceAccessor accessor = getAccessor(resourceResolver);
+ CharacterSet characterSet = CharacterSetBuilder.getDoubleByteInstance().build(characterset, super.codePage,
+ super.encoding, tf, accessor, eventProducer);
+ OutlineFont font = new AFPTrueTypeFont(super.name, super.embeddable, characterSet,
+ eventProducer, subfont);
+ return getFontInfo(font, this);
+ }
+ }
+
+ public static class AFPTrueTypeFont extends OutlineFont {
+ private String ttc;
+ public AFPTrueTypeFont(String name, boolean embeddable, CharacterSet charSet, AFPEventProducer eventProducer,
+ String ttc) {
+ super(name, embeddable, charSet, eventProducer);
+ this.ttc = ttc;
+ }
+
+ public FontType getFontType() {
+ return FontType.TRUETYPE;
+ }
+
+ public String getTTC() {
+ return ttc;
+ }
+ }
+
static final class OutlineFontConfig extends AFPFontConfigData {
private final String base14;
private final String characterset;
diff --git a/src/java/org/apache/fop/render/afp/AFPPainter.java b/src/java/org/apache/fop/render/afp/AFPPainter.java
index aaa702afa..bfaa5db74 100644
--- a/src/java/org/apache/fop/render/afp/AFPPainter.java
+++ b/src/java/org/apache/fop/render/afp/AFPPainter.java
@@ -68,6 +68,7 @@ import org.apache.fop.afp.ptoca.PtocaProducer;
import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.fonts.FontType;
import org.apache.fop.fonts.Typeface;
import org.apache.fop.render.ImageHandlerUtil;
import org.apache.fop.render.RenderingContext;
@@ -973,11 +974,18 @@ public class AFPPainter extends AbstractIFPainter<AFPDocumentHandler> {
builder.setVariableSpaceCharacterIncrement(varSpaceCharacterIncrement);
boolean fixedSpaceMode = false;
+ int ttPos = p.x;
for (int i = 0; i < l; i++) {
char orgChar = text.charAt(i);
float glyphAdjust = 0;
- if (CharUtilities.isFixedWidthSpace(orgChar)) {
+ if (afpFont.getFontType() == FontType.TRUETYPE) {
+ flushText(builder, sb, charSet);
+ fixedSpaceMode = true;
+ int charWidth = font.getCharWidth(orgChar);
+ sb.append(orgChar);
+ glyphAdjust += charWidth;
+ } else if (CharUtilities.isFixedWidthSpace(orgChar)) {
flushText(builder, sb, charSet);
builder.setVariableSpaceCharacterIncrement(
fixedSpaceCharacterIncrement);
@@ -1005,7 +1013,11 @@ public class AFPPainter extends AbstractIFPainter<AFPDocumentHandler> {
glyphAdjust += dx[i + 1];
}
- if (glyphAdjust != 0) {
+ if (afpFont.getFontType() == FontType.TRUETYPE) {
+ flushText(builder, sb, charSet);
+ ttPos += Math.round(unitConv.mpt2units(glyphAdjust));
+ builder.absoluteMoveInline(ttPos);
+ } else if (glyphAdjust != 0) {
flushText(builder, sb, charSet);
int increment = Math.round(unitConv.mpt2units(glyphAdjust));
builder.relativeMoveInline(increment);