From 5500f93feb65157895bb0e5aea5800b9099f95b8 Mon Sep 17 00:00:00 2001 From: vk-github18 Date: Mon, 10 Aug 2026 21:31:45 +0200 Subject: [PATCH] Computing the stringWidth for a Form --- .../pdmodel/interactive/AppearanceStyle.java | 26 ++++++++++++++++++- .../interactive/PlainTextFormatter.java | 13 +++++++++- .../form/AppearanceGeneratorHelper.java | 5 +++- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/AppearanceStyle.java b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/AppearanceStyle.java index df04d44adbf..72b862103a9 100644 --- a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/AppearanceStyle.java +++ b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/AppearanceStyle.java @@ -16,6 +16,7 @@ */ package org.apache.pdfbox.pdmodel.interactive; +import org.apache.pdfbox.pdmodel.GlyphLayoutProcessorInterface; import org.apache.pdfbox.pdmodel.font.PDFont; /** @@ -38,7 +39,12 @@ public class AppearanceStyle * Defaulting to 1.2*fontSize to match Acrobats default. */ private float leading = 14.4f; - + + /** + * Glyph layout processor + */ + private GlyphLayoutProcessorInterface glyphLayoutProcessor; + /** * Get the font used for text formatting. * @@ -99,4 +105,22 @@ public void setLeading(float leading) { this.leading = leading; } + + /** + * + * @param glyphLayoutProcessor + */ + public void setGlyphLayoutProcessor(GlyphLayoutProcessorInterface glyphLayoutProcessor) + { + this.glyphLayoutProcessor = glyphLayoutProcessor; + } + + /** + * + * @return + */ + public GlyphLayoutProcessorInterface getGlyphLayoutProcessor() + { + return glyphLayoutProcessor; + } } diff --git a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/PlainTextFormatter.java b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/PlainTextFormatter.java index 3e41fe2ec76..90bf7de4d57 100644 --- a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/PlainTextFormatter.java +++ b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/PlainTextFormatter.java @@ -19,7 +19,10 @@ import java.io.IOException; import java.util.List; +import org.apache.pdfbox.pdmodel.GlyphLayoutProcessorInterface; import org.apache.pdfbox.pdmodel.PDAppearanceContentStream; +import org.apache.pdfbox.pdmodel.font.PDFont; +import org.apache.pdfbox.pdmodel.font.PDType0Font; import org.apache.pdfbox.pdmodel.interactive.PlainText.Line; import org.apache.pdfbox.pdmodel.interactive.PlainText.Paragraph; import org.apache.pdfbox.pdmodel.interactive.PlainText.TextAttribute; @@ -246,7 +249,15 @@ private void processLines(List lines, boolean isFirstParagraph) throws IOE for (Word word : words) { contents.showText(word.getText()); - wordWidth = (Float) word.getAttributes().getIterator().getAttribute(TextAttribute.WIDTH); + GlyphLayoutProcessorInterface glyphLayoutProcessor = appearanceStyle.getGlyphLayoutProcessor(); + PDFont font = appearanceStyle.getFont(); + if (glyphLayoutProcessor == null || !glyphLayoutProcessor.supportsFont(font)) + { + wordWidth = (Float) word.getAttributes().getIterator().getAttribute(TextAttribute.WIDTH); + } else { + wordWidth = glyphLayoutProcessor.getStringWidth( + (PDType0Font) font, appearanceStyle.getFontSize(), word.getText()); + } if (wordIndex != words.size() -1) { contents.newLineAtOffset(wordWidth + interWordSpacing, 0f); diff --git a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java index 29d21c86a3d..458dd17c42d 100644 --- a/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java +++ b/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java @@ -637,7 +637,10 @@ else if (field instanceof PDListBox) AppearanceStyle appearanceStyle = new AppearanceStyle(); appearanceStyle.setFont(font); appearanceStyle.setFontSize(fontSize); - + if (glyphLayoutProcessor != null) { + appearanceStyle.setGlyphLayoutProcessor(glyphLayoutProcessor); + } + // Adobe Acrobat uses the font's bounding box for the leading between the lines appearanceStyle.setLeading(font.getBoundingBox().getHeight() * fontScaleY);