aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/pdf
diff options
context:
space:
mode:
authorRobert Meyer <rmeyer@apache.org>2014-05-23 15:05:19 +0000
committerRobert Meyer <rmeyer@apache.org>2014-05-23 15:05:19 +0000
commit764eba0b31076d7220082ac167f18cc75c427e27 (patch)
tree3e209ccb9e5e1a376b94e9e5ea29a811b45e3129 /src/java/org/apache/fop/pdf
parentc4e5885007f3c61837a12ab330658b131d978247 (diff)
downloadxmlgraphics-fop-764eba0b31076d7220082ac167f18cc75c427e27.tar.gz
xmlgraphics-fop-764eba0b31076d7220082ac167f18cc75c427e27.zip
FOP-2354: Subset support for Type 1 fonts
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1597112 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/pdf')
-rw-r--r--src/java/org/apache/fop/pdf/PDFFactory.java81
1 files changed, 70 insertions, 11 deletions
diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java
index 070630274..eb4f61077 100644
--- a/src/java/org/apache/fop/pdf/PDFFactory.java
+++ b/src/java/org/apache/fop/pdf/PDFFactory.java
@@ -23,6 +23,7 @@ package org.apache.fop.pdf;
import java.awt.Color;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
@@ -32,6 +33,8 @@ import java.util.BitSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
@@ -61,6 +64,7 @@ import org.apache.fop.fonts.truetype.OTFSubSetFile;
import org.apache.fop.fonts.truetype.TTFSubSetFile;
import org.apache.fop.fonts.type1.PFBData;
import org.apache.fop.fonts.type1.PFBParser;
+import org.apache.fop.fonts.type1.Type1SubsetFile;
/**
* This class provides method to create and register PDF objects.
@@ -1372,11 +1376,50 @@ public class PDFFactory {
} else {
singleByteFont = (SingleByteFont)metrics;
}
- int firstChar = singleByteFont.getFirstChar();
- int lastChar = singleByteFont.getLastChar();
- nonBase14.setWidthMetrics(firstChar,
- lastChar,
- new PDFArray(null, metrics.getWidths()));
+
+ int firstChar = 0;
+ int lastChar = 0;
+ boolean defaultChars = false;
+ if (singleByteFont.getEmbeddingMode() == EmbeddingMode.SUBSET) {
+ Map<Integer, Integer> usedGlyphs = singleByteFont.getUsedGlyphs();
+ if (fonttype == FontType.TYPE1 && usedGlyphs.size() > 0) {
+ SortedSet<Integer> keys = new TreeSet<Integer>(usedGlyphs.keySet());
+ keys.remove(0);
+ if (keys.size() > 0) {
+ firstChar = keys.first();
+ lastChar = keys.last();
+ int[] newWidths = new int[(lastChar - firstChar) + 1];
+ for (int i = firstChar; i < lastChar + 1; i++) {
+ if (usedGlyphs.get(i) != null) {
+ if (i - singleByteFont.getFirstChar() < metrics.getWidths().length) {
+ newWidths[i - firstChar] = metrics.getWidths()[i
+ - singleByteFont.getFirstChar()];
+ } else {
+ defaultChars = true;
+ break;
+ }
+ } else {
+ newWidths[i - firstChar] = 0;
+ }
+ }
+ nonBase14.setWidthMetrics(firstChar,
+ lastChar,
+ new PDFArray(null, newWidths));
+ }
+ } else {
+ defaultChars = true;
+ }
+ } else {
+ defaultChars = true;
+ }
+
+ if (defaultChars) {
+ firstChar = singleByteFont.getFirstChar();
+ lastChar = singleByteFont.getLastChar();
+ nonBase14.setWidthMetrics(firstChar,
+ lastChar,
+ new PDFArray(null, metrics.getWidths()));
+ }
//Handle encoding
SingleByteEncoding mapping = singleByteFont.getEncoding();
@@ -1493,7 +1536,7 @@ public class PDFFactory {
desc.getStemV(), null);
} else {
// Create normal FontDescriptor
- descriptor = new PDFFontDescriptor(desc.getEmbedFontName(),
+ descriptor = new PDFFontDescriptor(fontPrefix + desc.getEmbedFontName(),
desc.getAscender(),
desc.getDescender(),
desc.getCapHeight(),
@@ -1507,7 +1550,6 @@ public class PDFFactory {
// Check if the font is embeddable
if (desc.isEmbeddable()) {
AbstractPDFStream stream = makeFontFile(desc, fontPrefix);
-
if (stream != null) {
descriptor.setFontFile(desc.getFontType(), stream);
getDocument().registerObject(stream);
@@ -1586,10 +1628,19 @@ public class PDFFactory {
}
embeddedFont = getFontStream(font, fontBytes, isCFF);
} else if (desc.getFontType() == FontType.TYPE1) {
- PFBParser parser = new PFBParser();
- PFBData pfb = parser.parsePFB(in);
- embeddedFont = new PDFT1Stream();
- ((PDFT1Stream) embeddedFont).setData(pfb);
+ if (font.getEmbeddingMode() != EmbeddingMode.SUBSET) {
+ embeddedFont = fullyEmbedType1Font(in);
+ } else {
+ assert font instanceof SingleByteFont;
+ SingleByteFont sbfont = (SingleByteFont)font;
+ Type1SubsetFile pfbFile = new Type1SubsetFile();
+ byte[] subsetData = pfbFile.createSubset(in, sbfont, fontPrefix);
+ InputStream subsetStream = new ByteArrayInputStream(subsetData);
+ PFBParser parser = new PFBParser();
+ PFBData pfb = parser.parsePFB(subsetStream);
+ embeddedFont = new PDFT1Stream();
+ ((PDFT1Stream) embeddedFont).setData(pfb);
+ }
} else {
byte[] file = IOUtils.toByteArray(in);
embeddedFont = new PDFTTFStream(file.length);
@@ -1614,6 +1665,14 @@ public class PDFFactory {
}
}
+ private AbstractPDFStream fullyEmbedType1Font(InputStream in) throws IOException {
+ PFBParser parser = new PFBParser();
+ PFBData pfb = parser.parsePFB(in);
+ AbstractPDFStream embeddedFont = new PDFT1Stream();
+ ((PDFT1Stream) embeddedFont).setData(pfb);
+ return embeddedFont;
+ }
+
private byte[] getFontSubsetBytes(FontFileReader reader, MultiByteFont mbfont, String header,
String fontPrefix, FontDescriptor desc, boolean isCFF) throws IOException {
if (isCFF) {