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;
}