You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2018/02/17 18:09:20 UTC

svn commit: r1824616 - in /pdfbox/branches/2.0/pdfbox/src: main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java test/java/org/apache/pdfbox/pdmodel/font/TestFontEmbedding.java

Author: tilman
Date: Sat Feb 17 18:09:20 2018
New Revision: 1824616

URL: http://svn.apache.org/viewvc?rev=1824616&view=rev
Log:
PDFBOX-4106: Remove unnecessary vertical displacement fixup, by Aaron Madlon-Kay

Modified:
    pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
    pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
    pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/font/TestFontEmbedding.java

Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java?rev=1824616&r1=1824615&r2=1824616&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java Sat Feb 17 18:09:20 2018
@@ -49,9 +49,9 @@ public abstract class PDCIDFont implemen
     private float defaultWidth;
     private float averageWidth;
 
-    final Map<Integer, Float> verticalDisplacementY = new HashMap<Integer, Float>(); // w1y
-    final Map<Integer, Vector> positionVectors = new HashMap<Integer, Vector>();     // v
-    float[] dw2 = new float[] { 880, -1000 };
+    private final Map<Integer, Float> verticalDisplacementY = new HashMap<Integer, Float>(); // w1y
+    private final Map<Integer, Vector> positionVectors = new HashMap<Integer, Vector>();     // v
+    private float[] dw2 = new float[] { 880, -1000 };
 
     protected final COSDictionary dict;
     private PDFontDescriptor fontDescriptor;

Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java?rev=1824616&r1=1824615&r2=1824616&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java Sat Feb 17 18:09:20 2018
@@ -18,31 +18,20 @@ package org.apache.pdfbox.pdmodel.font;
 
 import java.awt.geom.GeneralPath;
 import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.fontbox.cff.Type2CharString;
 import org.apache.fontbox.cmap.CMap;
 import org.apache.fontbox.ttf.CmapLookup;
 import org.apache.fontbox.ttf.GlyphData;
-import org.apache.fontbox.ttf.HorizontalMetricsTable;
 import org.apache.fontbox.ttf.OTFParser;
 import org.apache.fontbox.ttf.OpenTypeFont;
 import org.apache.fontbox.ttf.TrueTypeFont;
-import org.apache.fontbox.ttf.VerticalHeaderTable;
-import org.apache.fontbox.ttf.VerticalMetricsTable;
 import org.apache.fontbox.util.BoundingBox;
-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.common.PDRectangle;
 import org.apache.pdfbox.pdmodel.common.PDStream;
 import org.apache.pdfbox.util.Matrix;
-import org.apache.pdfbox.util.Vector;
 
 /**
  * Type 2 CIDFont (TrueType).
@@ -155,85 +144,6 @@ public class PDCIDFontType2 extends PDCI
         }
         cmap = ttf.getUnicodeCmapLookup(false);
         cid2gid = readCIDToGIDMap();
-        fixVerticalDisplacements();
-    }
-
-    private void fixVerticalDisplacements() throws IOException
-    {
-        if (!COSName.IDENTITY_V.equals(parent.dict.getCOSName(COSName.ENCODING)))
-        {
-            return;
-        }
-        // The "vhea" and "vmtx" tables that specify vertical metrics shall never be used by a conforming
-        // reader. The only way to specify vertical metrics in PDF shall be by means of the DW2 and W2
-        // entries in a CIDFont dictionary.
-        VerticalHeaderTable vhea = ttf.getVerticalHeader();
-        if (vhea == null)
-        {
-            if (dict.getItem(COSName.DW2) == null)
-            {
-                LOG.warn("Identity-V font seems to be missing vertical metrics: it has no 'vhea' table and no DW2 entry");
-            }
-            return;
-        }
-        // Clear any data previously set from DW2 / W2
-        verticalDisplacementY.clear();
-        positionVectors.clear();
-
-        float scaling = 1000f / ttf.getHeader().getUnitsPerEm();
-
-        dw2[0] = vhea.getAscender() * scaling;
-        dw2[1] = -vhea.getAdvanceHeightMax() * scaling;
-        Map<Integer, Integer> gid2cid = invert(cid2gid);
-        HorizontalMetricsTable hmtx = ttf.getHorizontalMetrics();
-        VerticalMetricsTable vmtx = ttf.getVerticalMetrics();
-        for (int gid = 0; gid < ttf.getNumberOfGlyphs(); gid++)
-        {
-            float advance = -vmtx.getAdvanceHeight(gid) * scaling;
-            if (advance != dw2[1])
-            {
-                int cid = gid2cid == null ? gid : gid2cid.get(gid);
-                verticalDisplacementY.put(cid, advance);
-                positionVectors.put(cid, new Vector(hmtx.getAdvanceWidth(gid) / 2f, dw2[0]));
-            }
-        }
-        freezeVerticalPositions();
-    }
-
-    private void freezeVerticalPositions() throws IOException
-    {
-        COSArray cosDw2 = new COSArray();
-        cosDw2.add(COSInteger.get(Math.round(dw2[0])));
-        cosDw2.add(COSInteger.get(Math.round(dw2[1])));
-        dict.setItem(COSName.DW2, cosDw2);
-
-        COSArray cosW2 = new COSArray();
-        COSArray values = new COSArray();
-        int prev = Integer.MIN_VALUE;
-        Set<Integer> keys = new TreeSet<Integer>(verticalDisplacementY.keySet());
-        for (int cid : keys)
-        {
-            long w1 = Math.round(verticalDisplacementY.get(cid));
-            if (w1 == dw2[1])
-            {
-                continue;
-            }
-            Vector pos = positionVectors.get(cid);
-            long v_x = Math.round(pos.getX());
-            long v_y = Math.round(pos.getY());
-            // c [w1_1y v_1x v_1y w1_2y v_2x v_2y ... w1_ny v_nx v_ny]
-            if (prev != cid - 1)
-            {
-                values = new COSArray();
-                cosW2.add(COSInteger.get(cid)); // c
-                cosW2.add(values);
-            }
-            values.add(COSInteger.get(w1)); // w1_iy
-            values.add(COSInteger.get(v_x)); // v_ix
-            values.add(COSInteger.get(v_y)); // v_iy
-            prev = cid;
-        }
-        dict.setItem(COSName.W2, cosW2);
     }
 
     private TrueTypeFont findFontOrSubstitute() throws IOException
@@ -309,20 +219,6 @@ public class PDCIDFontType2 extends PDCI
         return cMap.toCID(code);
     }
 
-    private Map<Integer, Integer> invert(int[] cid2gid)
-    {
-        if (cid2gid == null)
-        {
-            return null;
-        }
-        Map<Integer, Integer> inverse = new HashMap<Integer, Integer>(cid2gid.length);
-        for (int i = 0; i < cid2gid.length; i++)
-        {
-            inverse.put(cid2gid[i], i);
-        }
-        return inverse;
-    }
-
     /**
      * Returns the GID for the given character code.
      *

Modified: pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/font/TestFontEmbedding.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/font/TestFontEmbedding.java?rev=1824616&r1=1824615&r2=1824616&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/font/TestFontEmbedding.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/font/TestFontEmbedding.java Sat Feb 17 18:09:20 2018
@@ -63,15 +63,15 @@ public class TestFontEmbedding extends T
     }
 
     /**
-     * Embed a TTF as vertical CIDFontType2 with subsetting.
-     * 
-     * @throws IOException 
+     * Embed a monospace TTF as vertical CIDFontType2 with subsetting.
+     *
+     * @throws IOException
      */
-    public void testCIDFontType2VerticalSubset() throws IOException
+    public void testCIDFontType2VerticalSubsetMonospace() throws IOException
     {
         String text = "「ABC」";
         String expectedExtractedtext = "「\nA\nB\nC\n」";
-        File pdf = new File(OUT_DIR, "CIDFontType2V.pdf");
+        File pdf = new File(OUT_DIR, "CIDFontType2VM.pdf");
 
         PDDocument document = new PDDocument();
         PDPage page = new PDPage(PDRectangle.A4);
@@ -96,12 +96,16 @@ public class TestFontEmbedding extends T
         // Check the dictionaries
         COSDictionary fontDict = vfont.getCOSObject();
         assertEquals(COSName.IDENTITY_V, fontDict.getDictionaryObject(COSName.ENCODING));
+
+        document.save(pdf);
+
+        // Vertical metrics are fixed during subsetting, so do this after calling save()
         COSDictionary descFontDict = vfont.getDescendantFont().getCOSObject();
         COSArray dw2 = (COSArray) descFontDict.getDictionaryObject(COSName.DW2);
-        assertEquals(880, dw2.getInt(0));
-        assertEquals(-1000, dw2.getInt(1));
+        assertNull(dw2); // This font uses default values for DW2
+        COSArray w2 = (COSArray) descFontDict.getDictionaryObject(COSName.W2);
+        assertEquals(0, w2.size()); // Monospaced font has no entries
 
-        document.save(pdf);
         document.close();
 
         // Check text extraction