Author: lehmi
Date: Sun Aug 2 15:58:22 2026
New Revision: 1936798
Log:
PDFBOX-6175: enable caching for the FontDecriptor of a Type0 font
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.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/PDFontFactory.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java
Sun Aug 2 10:59:48 2026 (r1936797)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDPage.java
Sun Aug 2 15:58:22 2026 (r1936798)
@@ -168,13 +168,28 @@ public class PDPage implements COSObject
{
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))
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
Sun Aug 2 10:59:48 2026 (r1936797)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
Sun Aug 2 15:58:22 2026 (r1936798)
@@ -32,7 +32,9 @@ import org.apache.pdfbox.cos.COSBase;
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 @@ public abstract class PDCIDFont implemen
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 abstract class PDCIDFont implemen
*/
public PDFontDescriptor getFontDescriptor()
{
- if (fontDescriptor == null)
- {
- COSDictionary fd = dict.getCOSDictionary(COSName.FONT_DESC);
- if (fd != null)
- {
- fontDescriptor = new PDFontDescriptor(fd);
- }
- }
return fontDescriptor;
}
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
Sun Aug 2 10:59:48 2026 (r1936797)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
Sun Aug 2 15:58:22 2026 (r1936798)
@@ -34,6 +34,7 @@ import org.apache.fontbox.cff.Type2CharS
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 @@ public class PDCIDFontType0 extends PDCI
* 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 @@ public class PDCIDFontType0 extends PDCI
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 @@ public class PDCIDFontType0 extends PDCI
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 ||
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
Sun Aug 2 10:59:48 2026 (r1936797)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
Sun Aug 2 15:58:22 2026 (r1936798)
@@ -37,6 +37,7 @@ import org.apache.fontbox.ttf.TrueTypeFo
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 @@ public class PDCIDFontType2 extends PDCI
* 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 @@ public class PDCIDFontType2 extends PDCI
*
* @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 @@ public class PDCIDFontType2 extends PDCI
{
boolean fontIsDamaged = false;
TrueTypeFont ttfFont = null;
-
PDStream stream = null;
+ PDFontDescriptor fd = getFontDescriptor();
if (fd != null)
{
stream = fd.getFontFile2();
@@ -155,9 +159,8 @@ public class PDCIDFontType2 extends PDCI
{
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 @@ public class PDCIDFontType2 extends PDCI
return width;
}
+ @Override
protected byte[] encode(int unicode, PDType0Font parent)
{
int cid = -1;
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
Sun Aug 2 10:59:48 2026 (r1936797)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
Sun Aug 2 15:58:22 2026 (r1936798)
@@ -733,6 +733,6 @@ final class PDCIDFontType2Embedder exten
*/
public PDCIDFont getCIDFont() throws IOException
{
- return new PDCIDFontType2(cidFont, ttf);
+ return new PDCIDFontType2(cidFont, ttf, null);
}
}
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java
Sun Aug 2 10:59:48 2026 (r1936797)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java
Sun Aug 2 15:58:22 2026 (r1936798)
@@ -362,10 +362,12 @@ public final class PDFontFactory
* 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 @@ public final class PDFontFactory
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);
}
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
Sun Aug 2 10:59:48 2026 (r1936797)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
Sun Aug 2 15:58:22 2026 (r1936798)
@@ -108,7 +108,7 @@ public class PDType0Font extends PDFont
if (cachedCIDFont == null)
{
cachedCIDFont = PDFontFactory
- .createDescendantFont((COSDictionary)
descendantFontDictBase);
+ .createDescendantFont((COSDictionary)
descendantFontDictBase, resourceCache);
if (resourceCache != null && descendantFontBaseObject instanceof
COSObject)
{
resourceCache.put((COSObject) descendantFontBaseObject,
cachedCIDFont);