You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ja...@apache.org on 2014/12/13 00:20:51 UTC

svn commit: r1645090 - in /pdfbox/trunk: fontbox/src/main/java/org/apache/fontbox/ttf/ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/

Author: jahewson
Date: Fri Dec 12 23:20:51 2014
New Revision: 1645090

URL: http://svn.apache.org/r1645090
Log:
PDFBOX-1372: Handle monospace width for last hmtx entry

Modified:
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/HorizontalMetricsTable.java
    pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFontEmbedder.java

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/HorizontalMetricsTable.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/HorizontalMetricsTable.java?rev=1645090&r1=1645089&r2=1645090&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/HorizontalMetricsTable.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/HorizontalMetricsTable.java Fri Dec 12 23:20:51 2014
@@ -33,6 +33,7 @@ public class HorizontalMetricsTable exte
     private int[] advanceWidth;
     private short[] leftSideBearing;
     private short[] nonHorizontalLeftSideBearing;
+    private int numHMetrics;
     
     /**
      * This will read the required data from the stream.
@@ -44,7 +45,7 @@ public class HorizontalMetricsTable exte
     public void read(TrueTypeFont ttf, TTFDataStream data) throws IOException
     {
         HorizontalHeaderTable hHeader = ttf.getHorizontalHeader();
-        int numHMetrics = hHeader.getNumberOfHMetrics();
+        numHMetrics = hHeader.getNumberOfHMetrics();
         int numGlyphs = ttf.getNumberOfGlyphs();
 
         int bytesRead = 0;
@@ -80,18 +81,23 @@ public class HorizontalMetricsTable exte
 
         initialized = true;
     }
+
     /**
-     * @return Returns the advanceWidth.
-     */
-    public int[] getAdvanceWidth()
-    {
-        return advanceWidth;
-    }
-    /**
-     * @param advanceWidthValue The advanceWidth to set.
+     * Returns the advance width for the given GID.
+     *
+     * @param gid GID
      */
-    public void setAdvanceWidth(int[] advanceWidthValue)
+    public int getAdvanceWidth(int gid)
     {
-        advanceWidth = advanceWidthValue;
+        if (gid < numHMetrics)
+        {
+            return advanceWidth[gid];
+        }
+        else
+        {
+            // monospaced fonts may not have a width for every glyph
+            // the last one is for subsequent glyphs
+            return advanceWidth[advanceWidth.length -1];
+        }
     }
 }

Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java?rev=1645090&r1=1645089&r2=1645090&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/TrueTypeFont.java Fri Dec 12 23:20:51 2014
@@ -37,7 +37,6 @@ public class TrueTypeFont implements Typ
     private float version;
     private int numberOfGlyphs = -1;
     private int unitsPerEm = -1;
-    private int[] advanceWidths = null;
     protected Map<String,TTFTable> tables = new HashMap<String,TTFTable>();
     private TTFDataStream data;
     private Map<String, Integer> postScriptNames;
@@ -342,28 +341,15 @@ public class TrueTypeFont implements Typ
      */
     public int getAdvanceWidth(int gid) throws IOException
     {
-        if (advanceWidths == null)
+        HorizontalMetricsTable hmtx = getHorizontalMetrics();
+        if (hmtx != null)
         {
-            HorizontalMetricsTable hmtx = getHorizontalMetrics();
-            if (hmtx != null)
-            {
-                advanceWidths = hmtx.getAdvanceWidth();
-            }
-            else
-            {
-                // this should never happen
-                advanceWidths = new int[]{250};
-            }
-        }
-        if (advanceWidths.length > gid)
-        {
-            return advanceWidths[gid];
+            return hmtx.getAdvanceWidth(gid);
         }
         else
         {
-            // monospaced fonts may not have a width for every glyph
-            // the last one is for subsequent glyphs
-            return advanceWidths[advanceWidths.length-1];
+            // this should never happen
+            return 250;
         }
     }
 

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java?rev=1645090&r1=1645089&r2=1645090&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java Fri Dec 12 23:20:51 2014
@@ -141,12 +141,12 @@ final class PDCIDFontType2Embedder exten
         cidFont.setItem(COSName.FONT_DESC, fontDescriptor.getCOSObject());
 
         // W - widths
-        int[] subwidths = ttf.getHorizontalMetrics().getAdvanceWidth();
-        int[] gidwidths = new int[subwidths.length*2];
-        for (int i = 0; i < subwidths.length; i++)
+        int numGlyphs = ttf.getNumberOfGlyphs();
+        int[] gidwidths = new int[numGlyphs * 2];
+        for (int i = 0; i < numGlyphs; i++)
         {
             gidwidths[i * 2] = i;
-            gidwidths[i * 2 + 1] = subwidths[i];
+            gidwidths[i * 2 + 1] = ttf.getHorizontalMetrics().getAdvanceWidth(i);
         }
         cidFont.setItem(COSName.W, getWidths(gidwidths));
 

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFontEmbedder.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFontEmbedder.java?rev=1645090&r1=1645089&r2=1645090&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFontEmbedder.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFontEmbedder.java Fri Dec 12 23:20:51 2014
@@ -75,54 +75,33 @@ final class PDTrueTypeFontEmbedder exten
     private void setWidths(COSDictionary font, GlyphList glyphList) throws IOException
     {
         float scaling = 1000f / ttf.getHeader().getUnitsPerEm();
+        HorizontalMetricsTable hmtx = ttf.getHorizontalMetrics();
 
-        Map<Integer, String> codeToName = this.getFontEncoding().getCodeToNameMap();
+        Map<Integer, String> codeToName = getFontEncoding().getCodeToNameMap();
 
         int firstChar = Collections.min(codeToName.keySet());
         int lastChar = Collections.max(codeToName.keySet());
 
-        HorizontalMetricsTable hMet = ttf.getHorizontalMetrics();
-        int[] widthValues = hMet.getAdvanceWidth();
-
-        // some monospaced fonts provide only one value for the width
-        // instead of an array containing the same value for every glyph id
-        boolean isMonospaced = ttf.getHorizontalHeader().getNumberOfHMetrics() == 1;
-
-        int numWidths = lastChar - firstChar + 1;
-        List<Integer> widths = new ArrayList<Integer>(numWidths);
-
-        // use the first width as default
-        // proportional fonts -> width of the .notdef character
-        // monospaced-fonts -> the first width
-        int defaultWidth = Math.round(widthValues[0] * scaling);
-        for (int i = 0; i < numWidths; i++)
+        List<Integer> widths = new ArrayList<Integer>(lastChar - firstChar + 1);
+        for (int i = 0; i < lastChar - firstChar + 1; i++)
         {
-            widths.add(defaultWidth);
+            widths.add(0);
         }
 
         // a character code is mapped to a glyph name via the provided font encoding
         // afterwards, the glyph name is translated to a glyph ID.
-        for (Map.Entry<Integer, String> e : codeToName.entrySet())
+        for (Map.Entry<Integer, String> entry : codeToName.entrySet())
         {
-            String name = e.getValue();
-            // pdf code to unicode by glyph list.
-            if (!name.equals(".notdef"))
+            int code = entry.getKey();
+            String name = entry.getValue();
+
+            if (code >= firstChar && code <= lastChar)
             {
-                String c = glyphList.toUnicode(name);
-                int charCode = c.codePointAt(0);
+                String uni = glyphList.toUnicode(name);
+                int charCode = uni.codePointAt(0);
                 int gid = cmap.getGlyphId(charCode);
-                if (gid != 0)
-                {
-                    if (isMonospaced)
-                    {
-                        widths.set(e.getKey() - firstChar, defaultWidth);
-                    }
-                    else
-                    {
-                        widths.set(e.getKey() - firstChar,
-                                Math.round(widthValues[gid] * scaling));
-                    }
-                }
+                widths.set(entry.getKey() - firstChar,
+                           Math.round(hmtx.getAdvanceWidth(gid) * scaling));
             }
         }