Author: tilman
Date: Tue Mar  3 06:26:50 2026
New Revision: 1932118

Log:
PDFBOX-6172: catch otf fonts with cid != gid

Modified:
   
pdfbox/branches/3.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
   
pdfbox/branches/3.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java

Modified: 
pdfbox/branches/3.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
==============================================================================
--- 
pdfbox/branches/3.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
 Tue Mar  3 06:26:45 2026        (r1932117)
+++ 
pdfbox/branches/3.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFontType2Embedder.java
 Tue Mar  3 06:26:50 2026        (r1932118)
@@ -28,9 +28,13 @@ import java.util.TreeMap;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.fontbox.cff.CFFCIDFont;
+import org.apache.fontbox.cff.CFFCharset;
+import org.apache.fontbox.ttf.CFFTable;
 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/branches/3.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
==============================================================================
--- 
pdfbox/branches/3.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
    Tue Mar  3 06:26:45 2026        (r1932117)
+++ 
pdfbox/branches/3.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
    Tue Mar  3 06:26:50 2026        (r1932118)
@@ -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

Reply via email to