Author: jahewson Date: Mon Jul 13 05:38:41 2015 New Revision: 1690568 URL: http://svn.apache.org/r1690568 Log: PDFBOX-2875: Better embedding of Type 1 fonts
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1FontEmbedder.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/encoding/DictionaryEncoding.java Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java?rev=1690568&r1=1690567&r2=1690568&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java Mon Jul 13 05:38:41 2015 @@ -139,8 +139,30 @@ public class PDType1Font extends PDSimpl */ public PDType1Font(PDDocument doc, InputStream afmIn, InputStream pfbIn) throws IOException { - PDType1FontEmbedder embedder = new PDType1FontEmbedder(doc, dict, afmIn, pfbIn); + PDType1FontEmbedder embedder = new PDType1FontEmbedder(doc, dict, afmIn, pfbIn, null); encoding = embedder.getFontEncoding(); + glyphList = embedder.getGlyphList(); + type1font = embedder.getType1Font(); + genericFont = embedder.getType1Font(); + isEmbedded = true; + isDamaged = false; + fontMatrixTransform = new AffineTransform(); + } + + /** + * Creates a new Type 1 font for embedding. + * + * @param doc PDF document to write to + * @param afmIn AFM file stream + * @param pfbIn PFB file stream + * @throws IOException + */ + public PDType1Font(PDDocument doc, InputStream afmIn, InputStream pfbIn, Encoding encoding) + throws IOException + { + PDType1FontEmbedder embedder = new PDType1FontEmbedder(doc, dict, afmIn, pfbIn, encoding); + this.encoding = encoding; + glyphList = embedder.getGlyphList(); type1font = embedder.getType1Font(); genericFont = embedder.getType1Font(); isEmbedded = true; Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1FontEmbedder.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1FontEmbedder.java?rev=1690568&r1=1690567&r2=1690568&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1FontEmbedder.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1FontEmbedder.java Mon Jul 13 05:38:41 2015 @@ -16,8 +16,12 @@ */ package org.apache.pdfbox.pdmodel.font; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; import org.apache.fontbox.afm.AFMParser; -import org.apache.fontbox.afm.CharMetric; import org.apache.fontbox.afm.FontMetrics; import org.apache.fontbox.pfb.PfbParser; import org.apache.fontbox.type1.Type1Font; @@ -25,21 +29,15 @@ import org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSDictionary; import org.apache.pdfbox.cos.COSInteger; import org.apache.pdfbox.cos.COSName; -import org.apache.pdfbox.pdmodel.font.encoding.DictionaryEncoding; -import org.apache.pdfbox.pdmodel.font.encoding.Encoding; -import org.apache.pdfbox.pdmodel.font.encoding.Type1Encoding; import org.apache.pdfbox.io.IOUtils; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.common.COSArrayList; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.common.PDStream; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import org.apache.pdfbox.pdmodel.font.encoding.DictionaryEncoding; +import org.apache.pdfbox.pdmodel.font.encoding.Encoding; +import org.apache.pdfbox.pdmodel.font.encoding.GlyphList; +import org.apache.pdfbox.pdmodel.font.encoding.Type1Encoding; /** * Embedded PDType1Font builder. Helper class to populate a PDType1Font from a PFB and AFM. @@ -51,7 +49,7 @@ class PDType1FontEmbedder private final Encoding fontEncoding; private final FontMetrics metrics; private final Type1Font type1; - + /** * This will load a afm and pfb to be embedding into a document. * @@ -62,14 +60,21 @@ class PDType1FontEmbedder * @throws IOException If there is an error loading the data. */ PDType1FontEmbedder(PDDocument doc, COSDictionary dict, InputStream afmStream, - InputStream pfbStream) throws IOException + InputStream pfbStream, Encoding encoding) throws IOException { dict.setItem(COSName.SUBTYPE, COSName.TYPE1); // read the afm AFMParser afmParser = new AFMParser(afmStream); metrics = afmParser.parse(); - this.fontEncoding = encodingFromAFM(metrics); + if (encoding == null) + { + this.fontEncoding = encodingFromAFM(metrics); + } + else + { + this.fontEncoding = encoding; + } // build font descriptor PDFontDescriptor fd = buildFontDescriptor(metrics); @@ -92,37 +97,15 @@ class PDType1FontEmbedder dict.setItem(COSName.FONT_DESC, fd); dict.setName(COSName.BASE_FONT, metrics.getFontName()); - // get firstchar, lastchar - int firstchar = 255; - int lastchar = 0; - // widths - List<CharMetric> listmetric = metrics.getCharMetrics(); - int maxWidths = 256; - List<Integer> widths = new ArrayList<Integer>(maxWidths); - int zero = 250; - - Iterator<CharMetric> iter = listmetric.iterator(); - for (int i = 0; i < maxWidths; i++) + List<Integer> widths = new ArrayList<Integer>(256); + for (int code = 0; code <= 255; code++) { - widths.add(zero); - } - - while (iter.hasNext()) - { - CharMetric m = iter.next(); - int n = m.getCharacterCode(); - if (n > 0) - { - firstchar = Math.min(firstchar, n); - lastchar = Math.max(lastchar, n); - if (m.getWx() > 0) - { - int width = Math.round(m.getWx()); - widths.set(n, width); - } - } + String name = fontEncoding.getName(code); + int width = Math.round(metrics.getCharacterWidth(name)); + widths.add(width); } + dict.setInt(COSName.FIRST_CHAR, 0); dict.setInt(COSName.LAST_CHAR, 255); dict.setItem(COSName.WIDTHS, COSArrayList.converterToCOSArray(widths)); @@ -190,6 +173,14 @@ class PDType1FontEmbedder } /** + * Returns the font's glyph list. + */ + public GlyphList getGlyphList() + { + return GlyphList.getAdobeGlyphList(); + } + + /** * Returns the font's metrics. */ public FontMetrics getFontMetrics() Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/encoding/DictionaryEncoding.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/encoding/DictionaryEncoding.java?rev=1690568&r1=1690567&r2=1690568&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/encoding/DictionaryEncoding.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/encoding/DictionaryEncoding.java Mon Jul 13 05:38:41 2015 @@ -58,6 +58,10 @@ public class DictionaryEncoding extends { throw new IllegalArgumentException("Invalid encoding: " + baseEncoding); } + + codeToName.putAll( this.baseEncoding.codeToName ); + names.addAll( this.baseEncoding.names ); + applyDifferences(); } /**