Author: tilman
Date: Tue Mar 3 06:26:40 2026
New Revision: 1932116
Log:
PDFBOX-6172: catch otf fonts with cid != gid
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/PDType0Font.java
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
Tue Mar 3 05:54:42 2026 (r1932115)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
Tue Mar 3 06:26:40 2026 (r1932116)
@@ -25,12 +25,16 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
+import org.apache.fontbox.cff.CFFCIDFont;
+import org.apache.fontbox.cff.CFFCharset;
+import org.apache.fontbox.ttf.CFFTable;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.fontbox.ttf.GlyphData;
import org.apache.fontbox.ttf.GlyphTable;
import org.apache.fontbox.ttf.HorizontalMetricsTable;
+import org.apache.fontbox.ttf.OpenTypeFont;
import org.apache.fontbox.ttf.TrueTypeFont;
import org.apache.fontbox.ttf.VerticalHeaderTable;
import org.apache.fontbox.ttf.VerticalMetricsTable;
@@ -214,12 +218,48 @@ final class PDCIDFontType2Embedder exten
buildVerticalMetrics(cidFont);
}
+ if (ttf instanceof OpenTypeFont && !needsSubset())
+ {
+ checkForCidGidIdentity();
+ }
+
// CIDToGIDMap
cidFont.setItem(COSName.CID_TO_GID_MAP, COSName.IDENTITY);
return cidFont;
}
+ private void checkForCidGidIdentity() throws IOException
+ {
+ // PDFBOX-6172: if somebody is using a not subsetted otf font, check
whether cid == gid
+ // (subsetted will fail anyway)
+ OpenTypeFont otf = (OpenTypeFont) ttf;
+ CFFTable cffTable = otf.getCFF();
+ if (cffTable == null)
+ {
+ return;
+ }
+ CFFCIDFont cff = (CFFCIDFont) cffTable.getFont();
+ if (cff == null)
+ {
+ return;
+ }
+ CFFCharset charset = cff.getCharset();
+ if (charset == null)
+ {
+ return;
+ }
+ int glyphCount = otf.getNumberOfGlyphs();
+ for (int gid = 0; gid < glyphCount; gid++)
+ {
+ int cid = charset.getCIDForGID(gid);
+ if (gid != cid)
+ {
+ throw new IllegalStateException("CID and GID not identical:
CID " + cid + " != GID " + gid + ", use a ttf font instead");
+ }
+ }
+ }
+
private void addNameTag(String tag)
{
String name = fontDescriptor.getFontName();
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
Tue Mar 3 05:54:42 2026 (r1932115)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
Tue Mar 3 06:26:40 2026 (r1932116)
@@ -207,11 +207,14 @@ public class PDType0Font extends PDFont
* Loads a TTF to be embedded into a document as a Type 0 font.
*
* @param doc The PDF document that will hold the embedded font.
- * @param ttf A TrueType font.
+ * @param ttf A TrueType font. Passing an OpenTypeFont font object is
possible, but not
+ * recommended (see exceptions).
* @param embedSubset True if the font will be subset before embedding.
Set this to false when creating a font for
* AcroForm.
* @return A Type0 font with a CIDFontType2 descendant.
* @throws IOException If there is an error reading the font stream.
+ * @throws UnsupportedOperationException if embedSubset is true for an OTF
font
+ * @throws IllegalStateException if an OTF font is used but GID != CID
*/
public static PDType0Font load(PDDocument doc, TrueTypeFont ttf, boolean
embedSubset)
throws IOException
@@ -264,10 +267,13 @@ public class PDType0Font extends PDFont
* Loads a TTF to be embedded into a document as a vertical Type 0 font.
*
* @param doc The PDF document that will hold the embedded font.
- * @param ttf A TrueType font.
+ * @param ttf A TrueType font. Passing an OpenTypeFont font object is
possible, but not
+ * recommended (see exceptions).
* @param embedSubset True if the font will be subset before embedding
* @return A Type0 font with a CIDFontType2 descendant.
* @throws IOException If there is an error reading the font stream.
+ * @throws UnsupportedOperationException if embedSubset is true for an OTF
font
+ * @throws IllegalStateException if an OTF font is used but GID != CID
*/
public static PDType0Font loadVertical(PDDocument doc, TrueTypeFont ttf,
boolean embedSubset)
throws IOException