You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2026/10/18 14:05:02 UTC

svn commit: r1939249 - pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font

Author: lehmi
Date: Sun Oct 18 14:05:02 2026
New Revision: 1939249

Log:
PDFBOX-6287: move codeToBytesMap cache from PDType1Font to PDFont, so that all kind of fonts benefit from using it

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/PDFont.java
   pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java
   pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
   pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java
   pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.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 Oct 18 13:29:50 2026	(r1939248)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java	Sun Oct 18 14:05:02 2026	(r1939249)
@@ -52,6 +52,7 @@ public abstract class PDCIDFont implemen
     private static final Logger LOG = LogManager.getLogger(PDCIDFont.class);
 
     private final Map<Integer, Float> widths = new HashMap<>();
+    private final Map<Integer, Float> codeToWidth = new HashMap<>();
     private float defaultWidth;
     private float averageWidth;
 
@@ -496,10 +497,16 @@ public abstract class PDCIDFont implemen
      */
     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, parent));
+        Float width = codeToWidth.get(code);
+        if (width == null)
+        {
+            // 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
+            width = getWidthForCID(codeToCID(code, parent));
+            codeToWidth.put(code, width);
+        }
+        return width;
     }
 
     // todo: this method is highly suspicious, the average glyph width is not usually a good metric

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java	Sun Oct 18 13:29:50 2026	(r1939248)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java	Sun Oct 18 14:05:02 2026	(r1939249)
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -67,6 +68,7 @@ public abstract class PDFont implements
     private float avgFontWidth;
     private float fontWidthOfSpace = -1f;
     private final Map<Integer, Float> codeToWidthMap;
+    protected final Map<Integer, byte[]> codepointEncoding = new HashMap<>();
 
     /**
      * Constructor for embedding.
@@ -343,16 +345,11 @@ public abstract class PDFont implements
     public final byte[] encode(String text) throws IOException
     {
         ByteArrayOutputStream out = new ByteArrayOutputStream(Math.max(32, text.length()));
-        int offset = 0;
-        while (offset < text.length())
+        Iterator<Integer> codePoints = text.codePoints().iterator();
+        while (codePoints.hasNext())
         {
-            int codePoint = text.codePointAt(offset);
-
-            // multi-byte encoding with 1 to 4 bytes
-            byte[] bytes = encode(codePoint);
+            byte[] bytes = encode(codePoints.next());
             out.writeBytes(bytes);
-
-            offset += Character.charCount(codePoint);
         }
         return out.toByteArray();
     }

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java	Sun Oct 18 13:29:50 2026	(r1939248)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java	Sun Oct 18 14:05:02 2026	(r1939249)
@@ -390,6 +390,11 @@ public class PDTrueTypeFont extends PDSi
     @Override
     protected byte[] encode(int unicode) throws IOException
     {
+        byte[] encodedCodepoint = codepointEncoding.get(unicode);
+        if (encodedCodepoint != null)
+        {
+            return encodedCodepoint;
+        }
         if (encoding != null)
         {
             if (!encoding.contains(getGlyphList().codePointToName(unicode)))
@@ -413,7 +418,7 @@ public class PDTrueTypeFont extends PDSi
             }
 
             int code = encoding.getCode(name);
-            return new byte[] { (byte)code };
+            encodedCodepoint = new byte[] { (byte) code };
         }
         else
         {
@@ -434,8 +439,10 @@ public class PDTrueTypeFont extends PDSi
                     String.format("U+%04X is not available in font %s encoding", unicode, getName()));
             }
             
-            return new byte[] { (byte)(int)code };
+            encodedCodepoint = new byte[] { (byte) code.intValue() };
         }
+        codepointEncoding.put(unicode, encodedCodepoint);
+        return encodedCodepoint;
     }
 
     /**

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 Oct 18 13:29:50 2026	(r1939248)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java	Sun Oct 18 14:05:02 2026	(r1939249)
@@ -499,7 +499,14 @@ public class PDType0Font extends PDFont
     @Override
     protected byte[] encode(int unicode) throws IOException
     {
-        return descendantFont.encode(unicode, this);
+        byte[] encodedCodepoint = codepointEncoding.get(unicode);
+        if (encodedCodepoint != null)
+        {
+            return encodedCodepoint;
+        }
+        encodedCodepoint = descendantFont.encode(unicode, this);
+        codepointEncoding.put(unicode, encodedCodepoint);
+        return encodedCodepoint;
     }
 
     @Override

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java	Sun Oct 18 13:29:50 2026	(r1939248)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java	Sun Oct 18 14:05:02 2026	(r1939249)
@@ -23,6 +23,7 @@ import java.awt.geom.Point2D;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import org.apache.logging.log4j.Logger;
@@ -394,6 +395,12 @@ public class PDType1CFont extends PDSimp
     @Override
     protected byte[] encode(int unicode) throws IOException
     {
+        byte[] encodedCodepoint = codepointEncoding.get(unicode);
+        if (encodedCodepoint != null)
+        {
+            return encodedCodepoint;
+        }
+
         String name = getGlyphList().codePointToName(unicode);
         if (!encoding.contains(name))
         {
@@ -411,7 +418,9 @@ public class PDType1CFont extends PDSimp
         }
 
         int code = encoding.getCode(name);
-        return new byte[] { (byte)code };
+        encodedCodepoint = new byte[] { (byte) code };
+        codepointEncoding.put(unicode, encodedCodepoint);
+        return encodedCodepoint;
     }
 
     @Override
@@ -423,9 +432,10 @@ public class PDType1CFont extends PDSimp
             return 0;
         }
         float width = 0;
-        for (int i = 0; i < string.length(); i++)
+        Iterator<Integer> codePoints = string.codePoints().iterator();
+        while (codePoints.hasNext())
         {
-            int codePoint = string.codePointAt(i);
+            int codePoint = codePoints.next();
             String name = getGlyphList().codePointToName(codePoint);
             if (!cffFont.hasGlyph(name))
             {
@@ -433,7 +443,7 @@ public class PDType1CFont extends PDSimp
                     String.format("U+%04X ('%s') is not available in font %s",
                                   codePoint, name, getName()));
             }
-            width += cffFont.getType1CharString(name).getWidth();
+            width += cffFont.getWidth(name);
         }
         return width;
     }

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java	Sun Oct 18 13:29:50 2026	(r1939248)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1Font.java	Sun Oct 18 14:05:02 2026	(r1939249)
@@ -90,10 +90,6 @@ public class PDType1Font extends PDSimpl
     private final boolean isEmbedded;
     private final boolean isDamaged;
     private final AffineTransform fontMatrixTransform;
-    /**
-     * to improve encoding speed.
-     */
-    private final Map<Integer, byte[]> codeToBytesMap = new HashMap<>();
     private Matrix fontMatrix;
     private BoundingBox fontBBox;
 
@@ -393,7 +389,7 @@ public class PDType1Font extends PDSimpl
     @Override
     protected byte[] encode(int unicode) throws IOException
     {
-        byte[] bytes = codeToBytesMap.get(unicode);
+        byte[] bytes = codepointEncoding.get(unicode);
         if (bytes != null)
         {
             return bytes;
@@ -442,7 +438,7 @@ public class PDType1Font extends PDSimpl
                             unicode, name, getName(), genericFont.getName(), encoding.getEncodingName()));
         }
         bytes = new byte[] { (byte)code };
-        codeToBytesMap.put(unicode, bytes);
+        codepointEncoding.put(unicode, bytes);
         return bytes;
     }