You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2013/09/23 18:18:25 UTC

svn commit: r1525637 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox: pdfviewer/PageDrawer.java pdfviewer/font/TTFGlyph2D.java pdmodel/font/PDCIDFontType2Font.java

Author: lehmi
Date: Mon Sep 23 16:18:25 2013
New Revision: 1525637

URL: http://svn.apache.org/r1525637
Log:
PDFBOX-1718: use a given CIDToGID mapping, rearranged some code

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Font.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java?rev=1525637&r1=1525636&r2=1525637&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/PageDrawer.java Mon Sep 23 16:18:25 2013
@@ -113,8 +113,8 @@ public class PageDrawer extends PDFStrea
 
     private GeneralPath linePath = new GeneralPath();
 
-    private HashMap<PDFont, Glyph2D> fontGlyph2D = new HashMap<PDFont, Glyph2D>();
-    private HashMap<PDFont, Font> awtFonts = new HashMap<PDFont, Font>();
+    private Map<PDFont, Glyph2D> fontGlyph2D = new HashMap<PDFont, Glyph2D>();
+    private Map<PDFont, Font> awtFonts = new HashMap<PDFont, Font>();
 
     /**
      * Default constructor, loads properties from file.
@@ -299,13 +299,13 @@ public class PageDrawer extends PDFStrea
                 if (glyph2D != null)
                 {
                     // Let PDFBox render the font if supported
-                    drawGlyph2D(glyph2D, text.getCodePoints(), graphics, at, x, y);
+                    drawGlyph2D(glyph2D, text.getCodePoints(), at, x, y);
                 }
                 else
                 {
                     // Use AWT to render the font (Type1 fonts, standard14 fonts, if the embedded font is substituted)
                     // TODO to be removed in the long run?
-                    drawString((PDSimpleFont) font, text.getCharacter(), text.getCodePoints(), graphics, at, x, y);
+                    drawString((PDSimpleFont) font, text.getCharacter(), at, x, y);
                 }
             }
         }
@@ -320,13 +320,12 @@ public class PageDrawer extends PDFStrea
      * 
      * @param glyph2D the Glyph2D implementation provided a GeneralPath for each glyph
      * @param codePoints the string to be rendered
-     * @param graphics the graphics object to be used for rendering
      * @param at the transformation
      * @param x the x coordinate of the text
      * @param y the y coordinate of the text
      * @throws IOException if something went wrong
      */
-    private void drawGlyph2D(Glyph2D glyph2D, int[] codePoints, Graphics graphics, AffineTransform at, float x, float y)
+    private void drawGlyph2D(Glyph2D glyph2D, int[] codePoints, AffineTransform at, float x, float y)
             throws IOException
     {
         Graphics2D g2d = (Graphics2D) graphics;
@@ -412,7 +411,6 @@ public class PageDrawer extends PDFStrea
      * 
      * @param font the font to be used to draw the string
      * @param string The string to draw.
-     * @param codePoints The codePoints of the given string.
      * @param g The graphics to draw onto.
      * @param at The transformation matrix with all information for scaling and shearing of the font.
      * @param x The x coordinate to draw at.
@@ -420,14 +418,13 @@ public class PageDrawer extends PDFStrea
      * 
      * @throws IOException If there is an error drawing the specific string.
      */
-    private void drawString(PDSimpleFont font, String string, int[] codePoints, Graphics g, AffineTransform at,
-            float x, float y) throws IOException
+    private void drawString(PDSimpleFont font, String string, AffineTransform at, float x, float y) throws IOException
     {
         Font awtFont = createAWTFont(font);
         FontRenderContext frc = new FontRenderContext(new AffineTransform(), true, true);
         GlyphVector glyphs = awtFont.createGlyphVector(frc, string);
 
-        Graphics2D g2d = (Graphics2D) g;
+        Graphics2D g2d = (Graphics2D) graphics;
         g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
         writeFont(g2d, at, x, y, glyphs);
     }
@@ -486,7 +483,7 @@ public class PageDrawer extends PDFStrea
             {
                 PDType1Font type1Font = (PDType1Font) font;
                 PDFontDescriptor fd = type1Font.getFontDescriptor();
-                if (fd != null && fd instanceof PDFontDescriptorDictionary)
+                if (fd instanceof PDFontDescriptorDictionary)
                 {
                     PDFontDescriptorDictionary fdDictionary = (PDFontDescriptorDictionary) fd;
                     if (fdDictionary.getFontFile() != null)
@@ -570,7 +567,7 @@ public class PageDrawer extends PDFStrea
                 TrueTypeFont ttf = ttfFont.getTTFFont();
                 if (ttf != null)
                 {
-                    glyph2D = new TTFGlyph2D(ttf, font.getBaseFont(), ttfFont.isSymbolicFont(), font.getFontEncoding());
+                    glyph2D = new TTFGlyph2D(ttf, font);
                 }
             }
             else if (font instanceof PDType1Font)
@@ -598,16 +595,7 @@ public class PageDrawer extends PDFStrea
                     TrueTypeFont ttf = cidType2Font.getTTFFont();
                     if (ttf != null)
                     {
-                        if (cidType2Font.hasCIDToGIDMap())
-                        {
-                            glyph2D = new TTFGlyph2D(ttf, font.getBaseFont(), cidType2Font.isSymbolicFont(),
-                                    font.getFontEncoding(), cidType2Font.getCID2GID());
-                        }
-                        else
-                        {
-                            glyph2D = new TTFGlyph2D(ttf, font.getBaseFont(), cidType2Font.isSymbolicFont(),
-                                    font.getFontEncoding(), type0Font.getCMap());
-                        }
+                        glyph2D = new TTFGlyph2D(ttf, font, cidType2Font);
                     }
                 }
                 else if (type0Font.getDescendantFont() instanceof PDCIDFontType0Font)

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java?rev=1525637&r1=1525636&r2=1525637&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/TTFGlyph2D.java Mon Sep 23 16:18:25 2013
@@ -23,6 +23,7 @@ import java.awt.geom.GeneralPath;
 import java.awt.geom.Point2D;
 import java.io.IOException;
 import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -36,6 +37,8 @@ import org.apache.fontbox.ttf.HeaderTabl
 import org.apache.fontbox.ttf.TrueTypeFont;
 import org.apache.pdfbox.encoding.Encoding;
 import org.apache.pdfbox.encoding.MacOSRomanEncoding;
+import org.apache.pdfbox.pdmodel.font.PDCIDFontType2Font;
+import org.apache.pdfbox.pdmodel.font.PDFont;
 
 /**
  * This class provides a glyph to GeneralPath conversion for true type fonts.
@@ -51,91 +54,73 @@ public class TTFGlyph2D implements Glyph
      */
     private static final Log LOG = LogFactory.getLog(TTFGlyph2D.class);
 
+    /**
+     * Default scaling value.
+     */
+    private static final float DEFAULT_SCALING = 0.001f;
+
+    /**
+     * Start of coderanges.
+     */
+    private static final int START_RANGE_F000 = 0xF000;
+    private static final int START_RANGE_F100 = 0xF100;
+    private static final int START_RANGE_F200 = 0xF200;
+
     private TrueTypeFont font;
+    private PDCIDFontType2Font descendantFont;
     private String name;
-    private float scale = 0.001f;
+    private float scale;
     private CMAPEncodingEntry cmapWinUnicode = null;
     private CMAPEncodingEntry cmapWinSymbol = null;
     private CMAPEncodingEntry cmapMacintoshSymbol = null;
     private boolean isSymbol = false;
-    private HashMap<Integer, GeneralPath> glyphs = new HashMap<Integer, GeneralPath>();
+    private Map<Integer, GeneralPath> glyphs = new HashMap<Integer, GeneralPath>();
     private Encoding fontEncoding = null;
     private CMap fontCMap = null;
+    private boolean hasIdentityCIDMapping = false;
+    private boolean hasCID2GIDMapping = false;
     private boolean hasTwoByteMappings = false;
-    private int[] cid2gid = null;
-
-    /**
-     * Constructor.
-     * 
-     * @param trueTypeFont the true type font containing the glyphs
-     * @param fontname the name of the given font
-     * @param symbolFont indicates if the font is a symbolic font
-     * @param encoding the encoding of the font
-     * 
-     */
-    public TTFGlyph2D(TrueTypeFont trueTypeFont, String fontname, boolean symbolFont, Encoding encoding)
-    {
-        this(trueTypeFont, fontname, symbolFont, encoding, null, null);
-    }
 
     /**
      * Constructor.
      * 
      * @param trueTypeFont the true type font containing the glyphs
-     * @param fontname the name of the given font
-     * @param symbolFont indicates if the font is a symbolic font
-     * @param encoding the encoding of the font
-     * @param cid2gidMapping an optional CID2GID mapping
+     * @param pdFont the given PDFont
      */
-    public TTFGlyph2D(TrueTypeFont trueTypeFont, String fontname, boolean symbolFont, Encoding encoding,
-            int[] cid2gidMapping)
+    public TTFGlyph2D(TrueTypeFont trueTypeFont, PDFont pdFont)
     {
-        this(trueTypeFont, fontname, symbolFont, encoding, cid2gidMapping, null);
+        this(trueTypeFont, pdFont, null);
     }
 
     /**
      * Constructor.
      * 
      * @param trueTypeFont the true type font containing the glyphs
-     * @param fontname the name of the given font
-     * @param symbolFont indicates if the font is a symbolic font
-     * @param encoding the encoding of the font
-     * @param cMap an optional CMap
+     * @param pdFont the given PDFont
+     * @param descFont the descendant font of a Type0Font
      */
-    public TTFGlyph2D(TrueTypeFont trueTypeFont, String fontname, boolean symbolFont, Encoding encoding, CMap cMap)
-    {
-        this(trueTypeFont, fontname, symbolFont, encoding, null, cMap);
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param trueTypeFont the true type font containing the glyphs
-     * @param fontname the name of the given font
-     * @param symbolFont indicates if the font is a symbolic font
-     * @param encoding the encoding of the font
-     * @param cid2gidMapping an optional CID2GID mapping
-     * @param cMap an optional CMap
-     */
-    public TTFGlyph2D(TrueTypeFont trueTypeFont, String fontname, boolean symbolFont, Encoding encoding,
-            int[] cid2gidMapping, CMap cMap)
+    public TTFGlyph2D(TrueTypeFont trueTypeFont, PDFont pdFont, PDCIDFontType2Font descFont)
     {
         font = trueTypeFont;
-        isSymbol = symbolFont;
-        name = fontname;
-        fontEncoding = encoding;
-        cid2gid = cid2gidMapping;
-        fontCMap = cMap;
-        if (fontCMap != null)
-        {
-            hasTwoByteMappings = fontCMap.hasTwoByteMappings();
-        }
         // get units per em, which is used as scaling factor
         HeaderTable header = font.getHeader();
         if (header != null)
         {
             scale = 1f / header.getUnitsPerEm();
         }
+        else
+        {
+            scale = DEFAULT_SCALING;
+        }
+        extractCMaps();
+        extractFontSpecifics(pdFont, descFont);
+    }
+
+    /**
+     * extract all useful CMaps.
+     */
+    private void extractCMaps()
+    {
         CMAPTable cmapTable = font.getCMAP();
         if (cmapTable != null)
         {
@@ -163,6 +148,31 @@ public class TTFGlyph2D implements Glyph
                 }
             }
         }
+
+    }
+
+    /**
+     * Extract all font specific information.
+     * 
+     * @param pdFont the given PDFont
+     */
+    private void extractFontSpecifics(PDFont pdFont, PDCIDFontType2Font descFont)
+    {
+        isSymbol = pdFont.isSymbolicFont();
+        name = pdFont.getBaseFont();
+        fontEncoding = pdFont.getFontEncoding();
+        if (descFont != null)
+        {
+            descendantFont = descFont;
+            hasIdentityCIDMapping = descendantFont.hasIdentityCIDToGIDMap();
+            hasCID2GIDMapping = descendantFont.hasCIDToGIDMap();
+            fontCMap = pdFont.getCMap();
+            if (fontCMap != null)
+            {
+                hasTwoByteMappings = fontCMap.hasTwoByteMappings();
+            }
+
+        }
     }
 
     /**
@@ -222,6 +232,17 @@ public class TTFGlyph2D implements Glyph
      */
     private int getGlyphcode(int code)
     {
+        if (hasIdentityCIDMapping)
+        {
+            // identity mapping
+            return code;
+        }
+        if (hasCID2GIDMapping)
+        {
+            // use the provided CID2GID mapping
+            return descendantFont.mapCIDToGID(code);
+        }
+
         int result = 0;
         if (fontEncoding != null && !isSymbol)
         {
@@ -235,14 +256,14 @@ public class TTFGlyph2D implements Glyph
                         String unicode = Encoding.getCharacterForName(charactername);
                         if (unicode != null)
                         {
-                            code = unicode.codePointAt(0);
+                            result = unicode.codePointAt(0);
                         }
-                        result = cmapWinUnicode.getGlyphId(code);
+                        result = cmapWinUnicode.getGlyphId(result);
                     }
                     else if (cmapMacintoshSymbol != null)
                     {
-                        code = MacOSRomanEncoding.INSTANCE.getCode(charactername);
-                        result = cmapMacintoshSymbol.getGlyphId(code);
+                        result = MacOSRomanEncoding.INSTANCE.getCode(charactername);
+                        result = cmapMacintoshSymbol.getGlyphId(result);
                     }
                 }
             }
@@ -264,17 +285,17 @@ public class TTFGlyph2D implements Glyph
                     if (result == 0)
                     {
                         // F000 - F0FF
-                        result = cmapWinSymbol.getGlyphId(code + 0xF000);
+                        result = cmapWinSymbol.getGlyphId(code + START_RANGE_F000);
                     }
                     if (result == 0)
                     {
                         // F100 - F1FF
-                        result = cmapWinSymbol.getGlyphId(code + 0xF100);
+                        result = cmapWinSymbol.getGlyphId(code + START_RANGE_F100);
                     }
                     if (result == 0)
                     {
                         // F200 - F2FF
-                        result = cmapWinSymbol.getGlyphId(code + 0xF200);
+                        result = cmapWinSymbol.getGlyphId(code + START_RANGE_F200);
                     }
                 }
             }
@@ -299,21 +320,17 @@ public class TTFGlyph2D implements Glyph
         {
             return getPathForGlyphId(glyphId);
         }
+        glyphId = code;
         // there isn't any mapping, but probably an optional CMap
         if (fontCMap != null)
         {
             String string = fontCMap.lookup(code, hasTwoByteMappings ? 2 : 1);
             if (string != null)
             {
-                code = string.codePointAt(0);
+                glyphId = string.codePointAt(0);
             }
         }
-        // there isn't any mapping, but probably an optional CID2GID mapping
-        if (cid2gid != null && code <= cid2gid.length)
-        {
-            code = cid2gid[code];
-        }
-        return getPathForGlyphId(code);
+        return getPathForGlyphId(glyphId);
     }
 
     /**
@@ -429,7 +446,7 @@ public class TTFGlyph2D implements Glyph
                 lastCtrlPoint = point;
                 continue;
             }
-            System.err.println("Unknown glyph command!!");
+            LOG.error("Unknown glyph command!!");
             break;
         }
         return path;
@@ -447,10 +464,10 @@ public class TTFGlyph2D implements Glyph
     private class Point
     {
 
-        public int x = 0;
-        public int y = 0;
-        public boolean onCurve = true;
-        public boolean endOfContour = false;
+        private int x = 0;
+        private int y = 0;
+        private boolean onCurve = true;
+        private boolean endOfContour = false;
 
         public Point(int xValue, int yValue, boolean onCurveValue, boolean endOfContourValue)
         {
@@ -478,12 +495,13 @@ public class TTFGlyph2D implements Glyph
     @Override
     public void dispose()
     {
-        cid2gid = null;
         cmapMacintoshSymbol = null;
         cmapWinSymbol = null;
         cmapWinUnicode = null;
         font = null;
+        descendantFont = null;
         fontCMap = null;
+        fontEncoding = null;
         if (glyphs != null)
         {
             glyphs.clear();

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Font.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Font.java?rev=1525637&r1=1525636&r2=1525637&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Font.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Font.java Mon Sep 23 16:18:25 2013
@@ -44,6 +44,7 @@ public class PDCIDFontType2Font extends 
     private static final Log LOG = LogFactory.getLog(PDCIDFontType2Font.class);
 
     private Boolean hasCIDToGIDMap = null;
+    private Boolean hasIdentityCIDToGIDMap = null;
     private int[] cid2gid = null;
 
     /**
@@ -116,6 +117,28 @@ public class PDCIDFontType2Font extends 
     }
 
     /**
+     * Indicates if this font has an identity CIDToGIDMap.
+     * 
+     * @return returns true if the font has an identity CIDToGIDMap.
+     */
+    public boolean hasIdentityCIDToGIDMap()
+    {
+        if (hasIdentityCIDToGIDMap == null)
+        {
+            COSBase map = font.getDictionaryObject(COSName.CID_TO_GID_MAP);
+            if (map != null && map instanceof COSName)
+            {
+                hasIdentityCIDToGIDMap = Boolean.TRUE;
+            }
+            else
+            {
+                hasIdentityCIDToGIDMap = Boolean.FALSE;
+            }
+        }
+        return hasIdentityCIDToGIDMap.booleanValue();
+    }
+
+    /**
      * Maps the given CID to the correspondent GID.
      * 
      * @param cid the given CID