PDFBOX-6175: enable caching for the FontDecriptor of a Type0 font

git-svn-id: https://svn.apache.org/repos/asf/pdfbox/trunk@1936798 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java
index 2c18d93..84f5e58 100644
--- a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java
+++ b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java
@@ -168,13 +168,28 @@
                     {
                         resourceCache.removeCIDFont((COSObject) descendantFontBaseObject);
                     }
+                    // the font descriptor of a type0 font is part of the descendant font not of the parent font
+                    COSBase descFont = descendantFonts.getObject(0);
+                    if (descFont instanceof COSDictionary)
+                    {
+                        COSObject fdIndirectObject = ((COSDictionary) descFont)
+                                .getCOSObject(COSName.FONT_DESC);
+                        // remove PDFontDescriptor from cache
+                        if (fdIndirectObject != null)
+                        {
+                            resourceCache.removeFontDescriptor(fdIndirectObject);
+                        }
+                    }
                 }
             }
-            COSObject fdIndirectObject = fontDict.getCOSObject(COSName.FONT_DESC);
-            // remove PDFontDescriptor from cache
-            if (fdIndirectObject != null)
+            else
             {
-                resourceCache.removeFontDescriptor(fdIndirectObject);
+                COSObject fdIndirectObject = fontDict.getCOSObject(COSName.FONT_DESC);
+                // remove PDFontDescriptor from cache
+                if (fdIndirectObject != null)
+                {
+                    resourceCache.removeFontDescriptor(fdIndirectObject);
+                }
             }
         }
         for (COSObject cosObject : getIndirectResourceObjects(resources, COSName.XOBJECT))
diff --git a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
index d51df3a..96a4f77 100644
--- a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
+++ b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
@@ -32,7 +32,9 @@
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.cos.COSNumber;
+import org.apache.pdfbox.cos.COSObject;
 import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdmodel.ResourceCache;
 import org.apache.pdfbox.pdmodel.common.COSObjectable;
 import org.apache.pdfbox.util.Matrix;
 import org.apache.pdfbox.util.Vector;
@@ -66,18 +68,40 @@
     protected boolean isEmbedded;
     protected boolean isDamaged;
 
-    private PDFontDescriptor fontDescriptor;
+    private final PDFontDescriptor fontDescriptor;
 
     /**
      * Constructor.
      *
      * @param fontDictionary The font dictionary according to the PDF specification.
+     * @param resourceCache ResourceCache, can be null.
+     * 
      */
-    PDCIDFont(COSDictionary fontDictionary)
+    PDCIDFont(COSDictionary fontDictionary, ResourceCache resourceCache)
     {
         this.dict = fontDictionary;
         readWidths();
         readVerticalDisplacements();
+        
+        PDFontDescriptor fd = null;
+        COSObject fdIndirectObject = dict.getCOSObject(COSName.FONT_DESC);
+        if (fdIndirectObject != null && resourceCache != null)
+        {
+            fd = resourceCache.getFontDescriptor(fdIndirectObject);
+        }
+        if (fd == null)
+        {
+            COSDictionary fdDict = dict.getCOSDictionary(COSName.FONT_DESC);
+            if (fdDict != null)
+            {
+                fd = new PDFontDescriptor(fdDict);
+                if (resourceCache != null && fdIndirectObject != null)
+                {
+                    resourceCache.put(fdIndirectObject, fd);
+                }
+            }
+        }
+        fontDescriptor = fd;
     }
 
     private void readWidths()
@@ -219,14 +243,6 @@
      */
     public PDFontDescriptor getFontDescriptor()
     {
-        if (fontDescriptor == null)
-        {
-            COSDictionary fd = dict.getCOSDictionary(COSName.FONT_DESC);
-            if (fd != null)
-            {
-                fontDescriptor = new PDFontDescriptor(fd);
-            }
-        }
         return fontDescriptor;
     }
 
diff --git a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
index 9c25426..77d0973 100644
--- a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
+++ b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
@@ -34,6 +34,7 @@
 import org.apache.fontbox.util.BoundingBox;
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.io.RandomAccessRead;
+import org.apache.pdfbox.pdmodel.ResourceCache;
 import org.apache.pdfbox.pdmodel.common.PDRectangle;
 import org.apache.pdfbox.pdmodel.common.PDStream;
 import org.apache.pdfbox.util.Matrix;
@@ -65,12 +66,14 @@
      * Constructor.
      * 
      * @param fontDictionary The font dictionary according to the PDF specification.
+     * @param resourceCache ResourceCache, can be null.
      * 
      * @throws IOException if the font could not be read
      */
-    public PDCIDFontType0(COSDictionary fontDictionary) throws IOException
+    public PDCIDFontType0(COSDictionary fontDictionary, ResourceCache resourceCache)
+            throws IOException
     {
-        super(fontDictionary);
+        super(fontDictionary, resourceCache);
 
         boolean fontIsDamaged = false;
         CFFFont cffFont = null;
@@ -122,9 +125,8 @@
         else
         {
             // find font or substitute
-            CIDFontMapping mapping = FontMappers.instance()
-                                                .getCIDFont(getBaseFont(), getFontDescriptor(),
-                                                            getCIDSystemInfo());
+            CIDFontMapping mapping = FontMappers.instance().getCIDFont(getBaseFont(), fd,
+                    getCIDSystemInfo());
             FontBoxFont font;
             if (mapping.isCIDFont())
             {
@@ -211,7 +213,8 @@
 
     private BoundingBox generateBoundingBox()
     {
-        if (getFontDescriptor() != null) {
+        if (getFontDescriptor() != null)
+        {
             PDRectangle bbox = getFontDescriptor().getFontBoundingBox();
             if (bbox != null && (Float.compare(bbox.getLowerLeftX(),0) != 0 ||
                 Float.compare(bbox.getLowerLeftY(),0) != 0 ||
diff --git a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
index abe2f08..b58001f 100644
--- a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
+++ b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
@@ -37,6 +37,7 @@
 import org.apache.fontbox.util.BoundingBox;
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.io.RandomAccessRead;
+import org.apache.pdfbox.pdmodel.ResourceCache;
 import org.apache.pdfbox.pdmodel.common.PDRectangle;
 import org.apache.pdfbox.pdmodel.common.PDStream;
 import org.apache.pdfbox.util.Matrix;
@@ -62,11 +63,14 @@
      * Constructor.
      * 
      * @param fontDictionary The font dictionary according to the PDF specification.
+     * @param resourceCache ResourceCache, can be null.
+     * 
      * @throws IOException if the font could not be read
      */
-    public PDCIDFontType2(COSDictionary fontDictionary) throws IOException
+    public PDCIDFontType2(COSDictionary fontDictionary, ResourceCache resourceCache)
+            throws IOException
     {
-        this(fontDictionary, null);
+        this(fontDictionary, null, resourceCache);
     }
     
     /**
@@ -74,14 +78,14 @@
      * 
      * @param fontDictionary The font dictionary according to the PDF specification.
      * @param trueTypeFont The true type font used to create the parent font
+     * @param resourceCache ResourceCache, can be null.
+     * 
      * @throws IOException if the font could not be read
      */
-    public PDCIDFontType2(COSDictionary fontDictionary, TrueTypeFont trueTypeFont)
-            throws IOException
+    public PDCIDFontType2(COSDictionary fontDictionary, TrueTypeFont trueTypeFont,
+            ResourceCache resourceCache) throws IOException
     {
-        super(fontDictionary);
-
-        PDFontDescriptor fd = getFontDescriptor();
+        super(fontDictionary, resourceCache);
         if (trueTypeFont != null)
         {
             ttf = trueTypeFont;
@@ -95,8 +99,8 @@
         {
             boolean fontIsDamaged = false;
             TrueTypeFont ttfFont = null;
-            
             PDStream stream = null;
+            PDFontDescriptor fd = getFontDescriptor();
             if (fd != null)
             {
                 stream = fd.getFontFile2();
@@ -155,9 +159,8 @@
     {
         TrueTypeFont ttfFont;
 
-        CIDFontMapping mapping = FontMappers.instance()
-                .getCIDFont(getBaseFont(), getFontDescriptor(),
-                        getCIDSystemInfo());
+        CIDFontMapping mapping = FontMappers.instance().getCIDFont(getBaseFont(),
+                getFontDescriptor(), getCIDSystemInfo());
         if (mapping.isCIDFont())
         {
             ttfFont = mapping.getFont();
@@ -350,6 +353,7 @@
         return width;
     }
 
+    @Override
     protected byte[] encode(int unicode, PDType0Font parent)
     {
         int cid = -1;
diff --git a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
index f8f3d93..930dc20 100644
--- a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
+++ b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
@@ -733,6 +733,6 @@
      */
     public PDCIDFont getCIDFont() throws IOException
     {
-        return new PDCIDFontType2(cidFont, ttf);
+        return new PDCIDFontType2(cidFont, ttf, null);
     }
 }
diff --git a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java
index b1ae004..e0658da 100644
--- a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java
+++ b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java
@@ -362,10 +362,12 @@
      * Creates a new PDCIDFont instance with the appropriate subclass.
      *
      * @param dictionary descendant font dictionary
+     * @param resourceCache ResourceCache, can be null.
+     * 
      * @return a PDCIDFont instance, based on the SubType entry of the dictionary
      * @throws IOException if something goes wrong
      */
-    static PDCIDFont createDescendantFont(COSDictionary dictionary)
+    static PDCIDFont createDescendantFont(COSDictionary dictionary, ResourceCache resourceCache)
             throws IOException
     {
         COSName type = dictionary.getCOSName(COSName.TYPE, COSName.FONT);
@@ -376,11 +378,11 @@
         COSName subType = dictionary.getCOSName(COSName.SUBTYPE);
         if (COSName.CID_FONT_TYPE0.equals(subType))
         {
-            return new PDCIDFontType0(dictionary);
+            return new PDCIDFontType0(dictionary, resourceCache);
         }
         if (COSName.CID_FONT_TYPE2.equals(subType))
         {
-            return new PDCIDFontType2(dictionary);
+            return new PDCIDFontType2(dictionary, resourceCache);
         }
         throw new IOException("Invalid font type: " + type);
     }
diff --git a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
index 07e4a47..82a54d3 100644
--- a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
+++ b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
@@ -108,7 +108,7 @@
         if (cachedCIDFont == null)
         {
             cachedCIDFont = PDFontFactory
-                    .createDescendantFont((COSDictionary) descendantFontDictBase);
+                    .createDescendantFont((COSDictionary) descendantFontDictBase, resourceCache);
             if (resourceCache != null && descendantFontBaseObject instanceof COSObject)
             {
                 resourceCache.put((COSObject) descendantFontBaseObject, cachedCIDFont);