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();
     }
 
     /**


Reply via email to