Author: lehmi
Date: Sun Jul 26 11:12:29 2026
New Revision: 1936597
Log:
PDFBOX-6175: remove parent Type0 font from PDCIDFont
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/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/font/PDCIDFont.java
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
Sun Jul 26 08:54:41 2026 (r1936596)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java
Sun Jul 26 11:12:29 2026 (r1936597)
@@ -16,6 +16,7 @@
*/
package org.apache.pdfbox.pdmodel.font;
+import java.awt.geom.GeneralPath;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -23,6 +24,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.Logger;
+import org.apache.fontbox.util.BoundingBox;
import org.apache.logging.log4j.LogManager;
import org.apache.pdfbox.cos.COSArray;
@@ -32,6 +34,7 @@ import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSNumber;
import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.pdmodel.common.COSObjectable;
+import org.apache.pdfbox.util.Matrix;
import org.apache.pdfbox.util.Vector;
/**
@@ -42,12 +45,10 @@ import org.apache.pdfbox.util.Vector;
*
* @author Ben Litchfield
*/
-public abstract class PDCIDFont implements COSObjectable, PDFontLike,
PDVectorFont
+public abstract class PDCIDFont implements COSObjectable
{
private static final Logger LOG = LogManager.getLogger(PDCIDFont.class);
- protected final PDType0Font parent;
-
private final Map<Integer, Float> widths = new HashMap<>();
private float defaultWidth;
private float averageWidth;
@@ -62,6 +63,9 @@ public abstract class PDCIDFont implemen
private final float[] dw2 = { 880, -1000 };
protected final COSDictionary dict;
+ protected boolean isEmbedded;
+ protected boolean isDamaged;
+
private PDFontDescriptor fontDescriptor;
/**
@@ -69,10 +73,9 @@ public abstract class PDCIDFont implemen
*
* @param fontDictionary The font dictionary according to the PDF
specification.
*/
- PDCIDFont(COSDictionary fontDictionary, PDType0Font parent)
+ PDCIDFont(COSDictionary fontDictionary)
{
this.dict = fontDictionary;
- this.parent = parent;
readWidths();
readVerticalDisplacements();
}
@@ -209,13 +212,11 @@ public abstract class PDCIDFont implemen
return dict.getNameAsString(COSName.BASE_FONT);
}
- @Override
- public String getName()
- {
- return getBaseFont();
- }
-
- @Override
+ /**
+ * Returns the font descriptor, may be null.
+ *
+ * @return the font descriptor or null
+ */
public PDFontDescriptor getFontDescriptor()
{
if (fontDescriptor == null)
@@ -230,13 +231,100 @@ public abstract class PDCIDFont implemen
}
/**
- * Returns the Type 0 font which is the parent of this font.
+ * Returns the font matrix, which represents the transformation from glyph
space to text space.
+ *
+ * @return the font matrix
+ */
+ protected abstract Matrix getFontMatrix();
+
+ /**
+ * Returns the font's bounding box.
+ *
+ * @return the bounding box
+ *
+ * @throws IOException if the bounding box could not be read
+ */
+ protected abstract BoundingBox getBoundingBox() throws IOException;
+
+ /**
+ * Returns the width of a glyph in the embedded font file.
+ *
+ * @param code character code
+ * @param parent the parent Type0 font.
+ *
+ * @return width in glyph space
+ * @throws IOException if the font could not be read
+ */
+ protected abstract float getWidthFromFont(int code, PDType0Font parent)
throws IOException;
+
+ /**
+ * Returns the height of the given character, in glyph space. This can be
expensive to calculate. Results are only
+ * approximate.
+ *
+ * Warning: This method is deprecated in PDFBox 2.0 because there is no
meaningful value which it can return, see
+ * {@link PDFontLike#getHeight(int)}
+ *
+ * @param code character code
+ * @param parent the parent Type0 font.
+ * @return the height of the given character
+ * @throws IOException if the height could not be read
+ */
+ @Deprecated
+ protected abstract float getHeight(int code, PDType0Font parent) throws
IOException;
+
+ /**
+ * Returns the glyph path for the given character code.
+ *
+ * @param code character code in a PDF. Not to be confused with unicode.
+ * @param parent the parent Type0 font.
+ *
+ * @return the glyph path for the given character code
+ * @throws java.io.IOException if the font could not be read
+ */
+ protected abstract GeneralPath getPath(int code, PDType0Font parent)
throws IOException;
+
+ /**
+ * Returns the normalized glyph path for the given character code in a
PDF. The resulting path is normalized to the
+ * PostScript 1000 unit square, and fallback glyphs are returned where
appropriate, e.g. for missing glyphs.
+ *
+ * @param code character code in a PDF. Not to be confused with unicode.
+ * @param parent the parent Type0 font.
+ *
+ * @return the normalized glyph path for the given character code
+ * @throws java.io.IOException if the font could not be read
+ */
+ protected abstract GeneralPath getNormalizedPath(int code, PDType0Font
parent)
+ throws IOException;
+
+ /**
+ * Returns true if this font contains a glyph for the given character code
in a PDF.
*
- * @return parent Type 0 font
+ * @param code character code in a PDF. Not to be confused with unicode.
+ * @param parent the parent Type0 font.
+ *
+ * @return true if this font contains a glyph for the given character code
+ * @throws java.io.IOException if the font could not be read
+ */
+ protected abstract boolean hasGlyph(int code, PDType0Font parent) throws
IOException;
+
+ /**
+ * Returns true if the font file is embedded in the PDF.
+ *
+ * @return true if the font file is embedded in the PDF
+ */
+ public boolean isEmbedded()
+ {
+ return isEmbedded;
+ }
+
+ /**
+ * Returns true if the embedded font file is damaged.
+ *
+ * @return true if the embedded font file is damaged
*/
- public final PDType0Font getParent()
+ public boolean isDamaged()
{
- return parent;
+ return isDamaged;
}
/**
@@ -281,16 +369,34 @@ public abstract class PDCIDFont implemen
return width;
}
- @Override
- public boolean hasExplicitWidth(int code) throws IOException
+ /**
+ * Returns true if the Font dictionary specifies an explicit width for the
given glyph. This includes Width, W but
+ * not default widths entries.
+ *
+ * @param code character code
+ * @param parent the parent Type0 font.
+ *
+ * @return true if the Font dictionary specifies an explicit width for the
given glyph
+ * @throws IOException if the font could not be read
+ */
+ protected boolean hasExplicitWidth(int code, PDType0Font parent) throws
IOException
{
- return widths.get(codeToCID(code)) != null;
+ return widths.get(codeToCID(code, parent)) != null;
}
- @Override
- public Vector getPositionVector(int code)
+ /**
+ * Returns the position vector (v), in text space, for the given
character. This represents the position of vertical
+ * origin relative to horizontal origin, for horizontal writing it will
always be (0, 0). For vertical writing both
+ * x and y are set.
+ *
+ * @param code character code
+ * @param parent the parent Type0 font.
+ *
+ * @return position vector
+ */
+ protected Vector getPositionVector(int code, PDType0Font parent)
{
- int cid = codeToCID(code);
+ int cid = codeToCID(code, parent);
Vector v = positionVectors.get(cid);
if (v == null)
{
@@ -313,11 +419,13 @@ public abstract class PDCIDFont implemen
* Returns the y-component of the vertical displacement vector (w1).
*
* @param code character code
+ * @param parent the parent Type0 font.
+ *
* @return w1y
*/
- public float getVerticalDisplacementVectorY(int code)
+ protected float getVerticalDisplacementVectorY(int code, PDType0Font
parent)
{
- int cid = codeToCID(code);
+ int cid = codeToCID(code, parent);
Float w1y = verticalDisplacementY.get(cid);
if (w1y == null)
{
@@ -336,16 +444,28 @@ public abstract class PDCIDFont implemen
return w1y;
}
- @Override
- public float getWidth(int code) throws IOException
+ /**
+ * Returns the advance width of the given character, in glyph space.
+ * <p>
+ *
+ * If you want the visual bounds of the glyph then call getPath(..) on the
appropriate PDFont subclass to retrieve
+ * the glyph outline as a GeneralPath instead. See the cyan rectangles in
the <b>DrawPrintTextLocations.java</b>
+ * example to see this in action.
+ *
+ * @param code character code
+ * @param parent the parent Type0 font.
+ *
+ * @return the width of the given character
+ * @throws IOException if the width could not be read
+ */
+ protected float getWidth(int code, PDType0Font parent) throws IOException
{
// these widths are supposed to be consistent with the actual widths
given in the CIDFont
// program, but PDFBOX-563 shows that when they are not, Acrobat
overrides the embedded
// font widths with the widths given in the font dictionary
- return getWidthForCID(codeToCID(code));
+ return getWidthForCID(codeToCID(code, parent));
}
- @Override
// todo: this method is highly suspicious, the average glyph width is not
usually a good metric
public float getAverageFontWidth()
{
@@ -391,32 +511,48 @@ public abstract class PDCIDFont implemen
* Returns the CID for the given character code. If not found then CID 0
is returned.
*
* @param code character code
+ * @param parent the parent Type0 font.
+ *
* @return CID
*/
- public abstract int codeToCID(int code);
+ protected abstract int codeToCID(int code, PDType0Font parent);
/**
* Returns the GID for the given character code.
*
* @param code character code
+ * @param parent the parent Type0 font.
+ *
* @return GID
* @throws java.io.IOException if the mapping could not be read
*/
- public abstract int codeToGID(int code) throws IOException;
+ protected abstract int codeToGID(int code, PDType0Font parent) throws
IOException;
- public abstract byte[] encodeGlyphId(int glyphId);
+ protected abstract byte[] encodeGlyphId(int glyphId);
/**
- * Encodes the given Unicode code point for use in a PDF content stream.
- * Content streams use a multi-byte encoding with 1 to 4 bytes.
+ * Encodes the given Unicode code point for use in a PDF content stream.
Content streams use a multi-byte encoding
+ * with 1 to 4 bytes.
*
- * <p>This method is called when embedding text in PDFs and when filling
in fields.
+ * <p>
+ * This method is called when embedding text in PDFs and when filling in
fields.
*
* @param unicode Unicode code point.
+ * @param parent the parent Type0 font.
+ *
* @return Array of 1 to 4 PDF content stream bytes.
* @throws IOException If the text could not be encoded.
*/
- protected abstract byte[] encode(int unicode) throws IOException;
+ protected byte[] encode(int unicode, PDType0Font parent) throws IOException
+ {
+ if (this instanceof PDCIDFontType0)
+ {
+ // todo: we can use a known character collection CMap for a CIDFont
+ // and an Encoding for Type 1-equivalent
+ throw new UnsupportedOperationException();
+ }
+ return ((PDCIDFontType2) this).encode(unicode, parent);
+ }
final int[] readCIDToGIDMap() throws IOException
{
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 Jul 26 08:54:41 2026 (r1936596)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType0.java
Sun Jul 26 11:12:29 2026 (r1936597)
@@ -55,8 +55,6 @@ public class PDCIDFontType0 extends PDCI
private final FontBoxFont t1Font; // Top DICT that does not use CIDFont
operators
private final Map<Integer, Float> glyphHeights = new HashMap<>();
- private final boolean isEmbedded;
- private final boolean isDamaged;
private final AffineTransform fontMatrixTransform;
private Float avgWidth = null;
private Matrix fontMatrix;
@@ -67,13 +65,12 @@ public class PDCIDFontType0 extends PDCI
* Constructor.
*
* @param fontDictionary The font dictionary according to the PDF
specification.
- * @param parent The parent font.
*
* @throws IOException if the font could not be read
*/
- public PDCIDFontType0(COSDictionary fontDictionary, PDType0Font parent)
throws IOException
+ public PDCIDFontType0(COSDictionary fontDictionary) throws IOException
{
- super(fontDictionary, parent);
+ super(fontDictionary);
boolean fontIsDamaged = false;
CFFFont cffFont = null;
@@ -303,7 +300,7 @@ public class PDCIDFontType0 extends PDCI
* Returns the name of the glyph with the given character code. This is
done by looking up the
* code in the parent font's ToUnicode map and generating a glyph name
from that.
*/
- private String getGlyphName(int code)
+ private String getGlyphName(int code, PDType0Font parent)
{
String unicodes = parent.toUnicode(code);
if (unicodes == null)
@@ -314,9 +311,9 @@ public class PDCIDFontType0 extends PDCI
}
@Override
- public GeneralPath getPath(int code) throws IOException
+ protected GeneralPath getPath(int code, PDType0Font parent) throws
IOException
{
- int cid = codeToCID(code);
+ int cid = codeToCID(code, parent);
if (cid2gid != null && isEmbedded)
{
// PDFBOX-4093: despite being a type 0 font, there is a CIDToGIDMap
@@ -333,20 +330,20 @@ public class PDCIDFontType0 extends PDCI
}
else
{
- return t1Font.getPath(getGlyphName(code));
+ return t1Font.getPath(getGlyphName(code, parent));
}
}
@Override
- public GeneralPath getNormalizedPath(int code) throws IOException
+ protected GeneralPath getNormalizedPath(int code, PDType0Font parent)
throws IOException
{
- return getPath(code);
+ return getPath(code, parent);
}
@Override
- public boolean hasGlyph(int code) throws IOException
+ protected boolean hasGlyph(int code, PDType0Font parent) throws IOException
{
- int cid = codeToCID(code);
+ int cid = codeToCID(code, parent);
Type2CharString charstring = getType2CharString(cid);
if (charstring != null)
{
@@ -358,7 +355,7 @@ public class PDCIDFontType0 extends PDCI
}
else
{
- return t1Font.hasGlyph(getGlyphName(code));
+ return t1Font.hasGlyph(getGlyphName(code, parent));
}
}
@@ -369,15 +366,15 @@ public class PDCIDFontType0 extends PDCI
* @return CID
*/
@Override
- public int codeToCID(int code)
+ protected int codeToCID(int code, PDType0Font parent)
{
return parent.getCMap().toCID(code);
}
@Override
- public int codeToGID(int code)
+ protected int codeToGID(int code, PDType0Font parent)
{
- int cid = codeToCID(code);
+ int cid = codeToCID(code, parent);
if (cidFont != null)
{
// The CIDs shall be used to determine the GID value for the glyph
procedure using the
@@ -392,23 +389,15 @@ public class PDCIDFontType0 extends PDCI
}
@Override
- public byte[] encode(int unicode)
+ protected byte[] encodeGlyphId(int glyphId)
{
- // todo: we can use a known character collection CMap for a CIDFont
- // and an Encoding for Type 1-equivalent
throw new UnsupportedOperationException();
}
@Override
- public byte[] encodeGlyphId(int glyphId)
+ protected float getWidthFromFont(int code, PDType0Font parent) throws
IOException
{
- throw new UnsupportedOperationException();
- }
-
- @Override
- public float getWidthFromFont(int code) throws IOException
- {
- int cid = codeToCID(code);
+ int cid = codeToCID(code, parent);
float width;
if (cidFont != null)
{
@@ -420,7 +409,7 @@ public class PDCIDFontType0 extends PDCI
}
else
{
- width = t1Font.getWidth(getGlyphName(code));
+ width = t1Font.getWidth(getGlyphName(code, parent));
}
Point2D p = new Point2D.Float(width, 0);
@@ -429,21 +418,9 @@ public class PDCIDFontType0 extends PDCI
}
@Override
- public boolean isEmbedded()
- {
- return isEmbedded;
- }
-
- @Override
- public boolean isDamaged()
- {
- return isDamaged;
- }
-
- @Override
- public float getHeight(int code) throws IOException
+ protected float getHeight(int code, PDType0Font parent) throws IOException
{
- int cid = codeToCID(code);
+ int cid = codeToCID(code, parent);
float height;
if (!glyphHeights.containsKey(cid))
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 Jul 26 08:54:41 2026 (r1936596)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2.java
Sun Jul 26 11:12:29 2026 (r1936597)
@@ -53,8 +53,6 @@ public class PDCIDFontType2 extends PDCI
private final TrueTypeFont ttf;
private final OpenTypeFont otf;
private final int[] cid2gid;
- private final boolean isEmbedded;
- private final boolean isDamaged;
private final CmapLookup cmap; // may be null
private Matrix fontMatrix;
private BoundingBox fontBBox;
@@ -64,25 +62,24 @@ public class PDCIDFontType2 extends PDCI
* Constructor.
*
* @param fontDictionary The font dictionary according to the PDF
specification.
- * @param parent The parent font.
* @throws IOException if the font could not be read
*/
- public PDCIDFontType2(COSDictionary fontDictionary, PDType0Font parent)
throws IOException
+ public PDCIDFontType2(COSDictionary fontDictionary) throws IOException
{
- this(fontDictionary, parent, null);
+ this(fontDictionary, null);
}
/**
* Constructor.
*
* @param fontDictionary The font dictionary according to the PDF
specification.
- * @param parent The parent font.
* @param trueTypeFont The true type font used to create the parent font
* @throws IOException if the font could not be read
*/
- public PDCIDFontType2(COSDictionary fontDictionary, PDType0Font parent,
TrueTypeFont trueTypeFont) throws IOException
+ public PDCIDFontType2(COSDictionary fontDictionary, TrueTypeFont
trueTypeFont)
+ throws IOException
{
- super(fontDictionary, parent);
+ super(fontDictionary);
PDFontDescriptor fd = getFontDescriptor();
if (trueTypeFont != null)
@@ -222,7 +219,7 @@ public class PDCIDFontType2 extends PDCI
}
@Override
- public int codeToCID(int code)
+ protected int codeToCID(int code, PDType0Font parent)
{
CMap cMap = parent.getCMap();
@@ -247,7 +244,7 @@ public class PDCIDFontType2 extends PDCI
* @throws IOException if the mapping could not be read
*/
@Override
- public int codeToGID(int code) throws IOException
+ protected int codeToGID(int code, PDType0Font parent) throws IOException
{
if (!isEmbedded)
{
@@ -256,15 +253,15 @@ public class PDCIDFontType2 extends PDCI
// font's 'cmap' table. The means by which this is accomplished
are implementation-
// dependent.
// omit the CID2GID mapping if the embedded font is replaced by an
external font
- String name = getName();
+ String name = getBaseFont();
if (cid2gid != null && !isDamaged && name != null &&
name.equals(ttf.getName()))
{
// Acrobat allows non-embedded GIDs - todo: can we find a test
PDF for this?
// PDFBOX-5612: should happen only if it's really the same font
// this is not perfect, we may have to improve this because
some identical fonts
// have different names
- LOG.warn("Using non-embedded GIDs in font {}", getName());
- int cid = codeToCID(code);
+ LOG.warn("Using non-embedded GIDs in font {}", getBaseFont());
+ int cid = codeToCID(code, parent);
if (cid < cid2gid.length)
{
return cid2gid[cid];
@@ -285,11 +282,11 @@ public class PDCIDFontType2 extends PDCI
// we keep track of which warnings have been issued,
so we don't log multiple times
noMapping.add(code);
LOG.warn("Failed to find a character mapping for {} in
{}", code,
- getName());
+ getBaseFont());
}
// Acrobat is willing to use the CID as a GID, even when
the font isn't embedded
// see PDFBOX-2599
- return codeToCID(code);
+ return codeToCID(code, parent);
}
else if (unicode.length() > 1)
{
@@ -306,7 +303,7 @@ public class PDCIDFontType2 extends PDCI
// a CIDToGIDMap entry that maps CIDs to the glyph indices for the
appropriate glyph
// descriptions in that font program.
- int cid = codeToCID(code);
+ int cid = codeToCID(code, parent);
if (cid2gid != null)
{
// use CIDToGIDMap
@@ -333,7 +330,7 @@ public class PDCIDFontType2 extends PDCI
}
@Override
- public float getHeight(int code) throws IOException
+ protected float getHeight(int code, PDType0Font parent) throws IOException
{
// todo: really we want the BBox, (for text extraction:)
return (ttf.getHorizontalHeader().getAscender() +
-ttf.getHorizontalHeader().getDescender())
@@ -341,9 +338,9 @@ public class PDCIDFontType2 extends PDCI
}
@Override
- public float getWidthFromFont(int code) throws IOException
+ protected float getWidthFromFont(int code, PDType0Font parent) throws
IOException
{
- int gid = codeToGID(code);
+ int gid = codeToGID(code, parent);
float width = ttf.getAdvanceWidth(gid);
int unitsPerEM = ttf.getUnitsPerEm();
if (unitsPerEM != 1000)
@@ -353,8 +350,7 @@ public class PDCIDFontType2 extends PDCI
return width;
}
- @Override
- public byte[] encode(int unicode)
+ protected byte[] encode(int unicode, PDType0Font parent)
{
int cid = -1;
if (isEmbedded)
@@ -400,31 +396,20 @@ public class PDCIDFontType2 extends PDCI
if (cid == 0)
{
throw new IllegalArgumentException(
- String.format("No glyph for U+%04X (%c) in font %s",
unicode, (char) unicode, getName()));
+ String.format("No glyph for U+%04X (%c) in font %s",
unicode, (char) unicode,
+ getBaseFont()));
}
return encodeGlyphId(cid);
}
@Override
- public byte[] encodeGlyphId(int glyphId)
+ protected byte[] encodeGlyphId(int glyphId)
{
// CID is always 2-bytes (16-bit) for TrueType
return new byte[] { (byte)(glyphId >> 8 & 0xff), (byte)(glyphId &
0xff) };
}
- @Override
- public boolean isEmbedded()
- {
- return isEmbedded;
- }
-
- @Override
- public boolean isDamaged()
- {
- return isDamaged;
- }
-
/**
* Returns the embedded or substituted TrueType font. May be an OpenType
font if the font is not embedded.
*
@@ -436,14 +421,14 @@ public class PDCIDFontType2 extends PDCI
}
@Override
- public GeneralPath getPath(int code) throws IOException
+ protected GeneralPath getPath(int code, PDType0Font parent) throws
IOException
{
if (otf != null && otf.isPostScript())
{
- GeneralPath path = getPathFromOutlines(code);
+ GeneralPath path = getPathFromOutlines(code, parent);
return path == null ? new GeneralPath() : path;
}
- int gid = codeToGID(code);
+ int gid = codeToGID(code, parent);
GlyphData glyph = ttf.getGlyph().getGlyph(gid);
if (glyph != null)
{
@@ -453,17 +438,17 @@ public class PDCIDFontType2 extends PDCI
}
@Override
- public GeneralPath getNormalizedPath(int code) throws IOException
+ protected GeneralPath getNormalizedPath(int code, PDType0Font parent)
throws IOException
{
GeneralPath path = null;
if (otf != null && otf.isPostScript())
{
- path = getPathFromOutlines(code);
+ path = getPathFromOutlines(code, parent);
}
else
{
- int gid = codeToGID(code);
- path = getPath(code);
+ int gid = codeToGID(code, parent);
+ path = getPath(code, parent);
// Acrobat only draws GID 0 for embedded CIDFonts, see PDFBOX-2372
if (gid == 0 && !isEmbedded())
{
@@ -488,18 +473,18 @@ public class PDCIDFontType2 extends PDCI
return path;
}
- private GeneralPath getPathFromOutlines(int code) throws IOException
+ private GeneralPath getPathFromOutlines(int code, PDType0Font parent)
throws IOException
{
CFFFont cffFont = otf.getCFF().getFont();
- int gid = codeToGID(code);
+ int gid = codeToGID(code, parent);
Type2CharString type2CharString = cffFont.getType2CharString(gid);
return type2CharString != null ? type2CharString.getPath() : null;
}
@Override
- public boolean hasGlyph(int code) throws IOException
+ protected boolean hasGlyph(int code, PDType0Font parent) throws IOException
{
- return codeToGID(code) != 0;
+ return codeToGID(code, parent) != 0;
}
private TTFParser getParser(RandomAccessRead randomAccessRead, boolean
isEmbedded)
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 Jul 26 08:54:41 2026 (r1936596)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
Sun Jul 26 11:12:29 2026 (r1936597)
@@ -60,7 +60,6 @@ final class PDCIDFontType2Embedder exten
private static final Logger LOG =
LogManager.getLogger(PDCIDFontType2Embedder.class);
private final PDDocument document;
- private final PDType0Font parent;
private final COSDictionary dict;
private final COSDictionary cidFont;
private final boolean vertical;
@@ -71,16 +70,14 @@ final class PDCIDFontType2Embedder exten
* @param document parent document
* @param dict font dictionary
* @param ttf True Type Font
- * @param parent parent Type 0 font
* @throws IOException if the TTF could not be read
*/
PDCIDFontType2Embedder(PDDocument document, COSDictionary dict,
TrueTypeFont ttf,
- boolean embedSubset, PDType0Font parent, boolean vertical) throws
IOException
+ boolean embedSubset, boolean vertical) throws IOException
{
super(document, dict, ttf, embedSubset);
this.document = document;
this.dict = dict;
- this.parent = parent;
this.vertical = vertical;
// parent Type 0 font
@@ -736,6 +733,6 @@ final class PDCIDFontType2Embedder exten
*/
public PDCIDFont getCIDFont() throws IOException
{
- return new PDCIDFontType2(cidFont, parent, ttf);
+ return new PDCIDFontType2(cidFont, ttf);
}
}
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 Jul 26 08:54:41 2026 (r1936596)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFontFactory.java
Sun Jul 26 11:12:29 2026 (r1936597)
@@ -365,7 +365,7 @@ public final class PDFontFactory
* @return a PDCIDFont instance, based on the SubType entry of the
dictionary
* @throws IOException if something goes wrong
*/
- static PDCIDFont createDescendantFont(COSDictionary dictionary,
PDType0Font parent)
+ static PDCIDFont createDescendantFont(COSDictionary dictionary)
throws IOException
{
COSName type = dictionary.getCOSName(COSName.TYPE, COSName.FONT);
@@ -376,11 +376,11 @@ public final class PDFontFactory
COSName subType = dictionary.getCOSName(COSName.SUBTYPE);
if (COSName.CID_FONT_TYPE0.equals(subType))
{
- return new PDCIDFontType0(dictionary, parent);
+ return new PDCIDFontType0(dictionary);
}
if (COSName.CID_FONT_TYPE2.equals(subType))
{
- return new PDCIDFontType2(dictionary, parent);
+ return new PDCIDFontType2(dictionary);
}
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 Jul 26 08:54:41 2026 (r1936596)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
Sun Jul 26 11:12:29 2026 (r1936597)
@@ -108,7 +108,7 @@ public class PDType0Font extends PDFont
if (cachedCIDFont == null)
{
cachedCIDFont = PDFontFactory
- .createDescendantFont((COSDictionary)
descendantFontDictBase, this);
+ .createDescendantFont((COSDictionary)
descendantFontDictBase);
if (resourceCache != null && descendantFontBaseObject instanceof
COSObject)
{
resourceCache.put((COSObject) descendantFontBaseObject,
cachedCIDFont);
@@ -142,7 +142,7 @@ public class PDType0Font extends PDFont
gsubData = ttf.getGsubData();
cmapLookup = ttf.getUnicodeCmapLookup();
- embedder = new PDCIDFontType2Embedder(document, dict, ttf,
embedSubset, this, vertical);
+ embedder = new PDCIDFontType2Embedder(document, dict, ttf,
embedSubset, vertical);
descendantFont = embedder.getCIDFont();
readEncoding();
fetchCMapUCS2();
@@ -493,19 +493,19 @@ public class PDType0Font extends PDFont
@Override
public float getHeight(int code) throws IOException
{
- return descendantFont.getHeight(code);
+ return descendantFont.getHeight(code, this);
}
@Override
protected byte[] encode(int unicode) throws IOException
{
- return descendantFont.encode(unicode);
+ return descendantFont.encode(unicode, this);
}
@Override
public boolean hasExplicitWidth(int code) throws IOException
{
- return descendantFont.hasExplicitWidth(code);
+ return descendantFont.hasExplicitWidth(code, this);
}
@Override
@@ -518,7 +518,7 @@ public class PDType0Font extends PDFont
public Vector getPositionVector(int code)
{
// units are always 1/1000 text space, font matrix is not used, see
FOP-2252
- return descendantFont.getPositionVector(code).scale(-1 / 1000f);
+ return descendantFont.getPositionVector(code, this).scale(-1 / 1000f);
}
@Override
@@ -526,7 +526,7 @@ public class PDType0Font extends PDFont
{
if (isVertical())
{
- return new Vector(0,
descendantFont.getVerticalDisplacementVectorY(code) / 1000f);
+ return new Vector(0,
descendantFont.getVerticalDisplacementVectorY(code, this) / 1000f);
}
else
{
@@ -537,7 +537,7 @@ public class PDType0Font extends PDFont
@Override
public float getWidth(int code) throws IOException
{
- return descendantFont.getWidth(code);
+ return descendantFont.getWidth(code, this);
}
@Override
@@ -549,7 +549,7 @@ public class PDType0Font extends PDFont
@Override
public float getWidthFromFont(int code) throws IOException
{
- return descendantFont.getWidthFromFont(code);
+ return descendantFont.getWidthFromFont(code, this);
}
@Override
@@ -603,13 +603,13 @@ public class PDType0Font extends PDFont
if (descendantFont.isEmbedded())
{
// original PDFBOX-5324 supported only embedded
fonts
- gid = descendantFont.codeToGID(code);
+ gid = descendantFont.codeToGID(code, this);
}
else
{
// PDFBOX-5331: this bypasses the fallback attempt
in
// PDCIDFontType2.codeToGID() which would bring a
stackoverflow
- gid = descendantFont.codeToCID(code);
+ gid = descendantFont.codeToCID(code, this);
}
List<Integer> codes = cmap.getCharCodes(gid);
if (codes != null && !codes.isEmpty())
@@ -667,7 +667,7 @@ public class PDType0Font extends PDFont
*/
public int codeToCID(int code)
{
- return descendantFont.codeToCID(code);
+ return descendantFont.codeToCID(code, this);
}
/**
@@ -680,7 +680,7 @@ public class PDType0Font extends PDFont
*/
public int codeToGID(int code) throws IOException
{
- return descendantFont.codeToGID(code);
+ return descendantFont.codeToGID(code, this);
}
@Override
@@ -709,20 +709,19 @@ public class PDType0Font extends PDFont
@Override
public GeneralPath getPath(int code) throws IOException
{
- return descendantFont.getPath(code);
+ return descendantFont.getPath(code, this);
}
-
@Override
public GeneralPath getNormalizedPath(int code) throws IOException
{
- return descendantFont.getNormalizedPath(code);
+ return descendantFont.getNormalizedPath(code, this);
}
@Override
public boolean hasGlyph(int code) throws IOException
{
- return descendantFont.hasGlyph(code);
+ return descendantFont.hasGlyph(code, this);
}
/**