Author: tilman
Date: Thu Feb 27 09:58:11 2025
New Revision: 1924076
URL: http://svn.apache.org/viewvc?rev=1924076&view=rev
Log:
PDFBOX-5230: improve javadoc and optimizations by Daniel Gredler
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDAbstractContentStream.java
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDAbstractContentStream.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDAbstractContentStream.java?rev=1924076&r1=1924075&r2=1924076&view=diff
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDAbstractContentStream.java
(original)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/PDAbstractContentStream.java
Thu Feb 27 09:58:11 2025
@@ -199,13 +199,12 @@ abstract class PDAbstractContentStream i
// complex text layout
if (font instanceof PDType0Font)
{
- PDType0Font pdType0Font = (PDType0Font) font;
- GsubData gsubData = pdType0Font.getGsubData();
+ PDType0Font type0Font = (PDType0Font) font;
+ GsubData gsubData = type0Font.getGsubData();
if (gsubData != GsubData.NO_DATA_FOUND)
{
- GsubWorker gsubWorker =
gsubWorkerFactory.getGsubWorker(pdType0Font.getCmapLookup(),
- gsubData);
- gsubWorkers.put((PDType0Font) font, gsubWorker);
+ GsubWorker gsubWorker =
gsubWorkerFactory.getGsubWorker(type0Font.getCmapLookup(), gsubData);
+ gsubWorkers.put(type0Font, gsubWorker);
}
else
{
@@ -292,16 +291,15 @@ abstract class PDAbstractContentStream i
byte[] encodedText = null;
if (font instanceof PDType0Font)
{
-
GsubWorker gsubWorker = gsubWorkers.get(font);
if (gsubWorker != null)
{
- PDType0Font pdType0Font = (PDType0Font) font;
+ PDType0Font type0Font = (PDType0Font) font;
Set<Integer> glyphIds = new HashSet<>();
- encodedText = encodeForGsub(gsubWorker, glyphIds, pdType0Font,
text);
- if (pdType0Font.willBeSubset())
+ encodedText = encodeForGsub(gsubWorker, glyphIds, type0Font,
text);
+ if (type0Font.willBeSubset())
{
- pdType0Font.addGlyphsToSubset(glyphIds);
+ type0Font.addGlyphsToSubset(glyphIds);
}
}
}
@@ -706,7 +704,7 @@ abstract class PDAbstractContentStream i
/**
* Set the stroking color in the DeviceRGB color space. Range is 0..1.
*
- * @param r The red value
+ * @param r The red value.
* @param g The green value.
* @param b The blue value.
* @throws IOException If an IO error occurs while writing to the stream.
@@ -1641,41 +1639,61 @@ abstract class PDAbstractContentStream i
writeOperator(OperatorName.SET_TEXT_RISE);
}
+ /**
+ * Retrieve the encoded glyph IDs for the characters in the specified
text, after applying any
+ * relevant GSUB rules. The glyph IDs used are also added to the specified
glyph ID set.
+ *
+ * @param gsubWorker The GSUB worker which defines the GSUB
transformations to apply.
+ * @param glyphIds The set of glyph IDs which is to be populated with the
glyph IDs found in the
+ * text.
+ * @param font The font whose cmap table will be used to map characters to
glyph IDs.
+ * @param text The text which is being converted from characters to glyph
IDs.
+ * @return The encoded glyph IDs for the characters in the specified text,
after applying any
+ * relevant GSUB rules.
+ * @throws IOException If there is an error during encoding.
+ * @throws IllegalStateException If we cannot find a glyph ID for any
characters in the
+ * specified text.
+ */
private byte[] encodeForGsub(GsubWorker gsubWorker,
- Set<Integer> glyphIds, PDType0Font font,
String text) throws IOException
+ Set<Integer> glyphIds, PDType0Font font, String text) throws
IOException
{
- // break the entire chunk of text into words by splitting it with space
+ ByteArrayOutputStream out = new ByteArrayOutputStream(2 *
text.length());
String[] words = StringUtil.tokenizeOnSpace(text);
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
for (String word : words)
{
- if (word == null)
+ if (word.length() == 1 && word.isBlank()) // PDFBOX-5823:
optimization
{
- continue;
- }
- if (word.length() == 1 && word.isBlank())
- {
- out.write(font.encode(word));
+ out.writeBytes(font.encode(word));
}
else
{
glyphIds.addAll(applyGSUBRules(gsubWorker, out, font, word));
}
}
-
return out.toByteArray();
}
- private List<Integer> applyGSUBRules(GsubWorker gsubWorker,
ByteArrayOutputStream out, PDType0Font font, String word) throws IOException
+ /**
+ * Retrieve the glyph IDs for the characters in the specified word, after
applying any relevant
+ * GSUB rules. The encoded glyph IDs are also written to the specified
output stream.
+ *
+ * @param gsubWorker The GSUB worker which defines the GSUB
transformations to apply.
+ * @param out The output stream to write the glyph IDs to.
+ * @param font The font whose cmap table will be used to map characters to
glyph IDs.
+ * @param word The word which is being converted from characters to glyph
IDs.
+ * @return The glyph IDs for the characters in the specified word, after
applying any relevant
+ * GSUB rules.
+ * @throws IllegalStateException If we cannot find a glyph ID for any
characters in the
+ * specified word.
+ */
+ private List<Integer> applyGSUBRules(GsubWorker gsubWorker,
ByteArrayOutputStream out, PDType0Font font, String word)
{
- int[] codePointArray = word.codePoints().toArray();
- List<Integer> originalGlyphIds = new
ArrayList<>(word.codePointCount(0, word.length()));
+ int[] codePoints = word.codePoints().toArray();
+ List<Integer> originalGlyphIds = new ArrayList<>(codePoints.length);
CmapLookup cmapLookup = font.getCmapLookup();
- // convert characters into glyphIds
- for (int codePoint : codePointArray)
+ // convert characters into glyph IDs
+ for (int codePoint : codePoints)
{
int glyphId = cmapLookup.getGlyphId(codePoint);
if (glyphId <= 0)
@@ -1700,14 +1718,13 @@ abstract class PDAbstractContentStream i
originalGlyphIds.add(glyphId);
}
+ // transform glyph IDs, write them to the output stream
List<Integer> glyphIdsAfterGsub =
gsubWorker.applyTransforms(originalGlyphIds);
-
for (Integer glyphId : glyphIdsAfterGsub)
{
- out.write(font.encodeGlyphId(glyphId));
+ out.writeBytes(font.encodeGlyphId(glyphId));
}
return glyphIdsAfterGsub;
-
}
}