Detecting text field overflow

2019-05-18 06:24发布

问题:

Assuming I have a PDF document with a text field with some font and size defined, is there a way to determine if some text will fit inside the field rectangle using PDFBox?

I'm trying to avoid cases where text is not fully displayed inside the field, so in case the text overflows given the font and size, I would like to change the font size to Auto (0).

回答1:

This code recreates the appearance stream to be sure that it exists so that there is a bbox (which can be a little bit smaller than the rectangle).

public static void main(String[] args) throws IOException
{
    // file can be found at https://issues.apache.org/jira/browse/PDFBOX-142
    // https://issues.apache.org/jira/secure/attachment/12742551/Testformular1.pdf
    try (PDDocument doc = PDDocument.load(new File("Testformular1.pdf")))
    {
        PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
        PDTextField field = (PDTextField) acroForm.getField("Name");
        PDAnnotationWidget widget = field.getWidgets().get(0);
        // force generation of appearance stream
        field.setValue(field.getValue());
        PDRectangle rectangle = widget.getRectangle();
        PDAppearanceEntry ap = widget.getAppearance().getNormalAppearance();
        PDAppearanceStream appearanceStream = ap.getAppearanceStream();
        PDRectangle bbox = appearanceStream.getBBox();
        float fieldWidth = Math.min(bbox.getWidth(), rectangle.getWidth());
        String defaultAppearance = field.getDefaultAppearance();
        System.out.println(defaultAppearance);

        // Pattern must be improved, font may have numbers
        // /Helv 12 Tf 0 g
        final Pattern p = Pattern.compile("\\/([A-z]+) (\\d+).+");
        Matcher m = p.matcher(defaultAppearance);
        if (!m.find() || m.groupCount() != 2)
        {
            System.out.println("oh-oh");
            System.exit(-1);
        }
        String fontName = m.group(1);
        int fontSize = Integer.parseInt(m.group(2));
        PDResources resources = appearanceStream.getResources();
        if (resources == null)
        {
            resources = acroForm.getDefaultResources();
        }
        PDFont font = resources.getFont(COSName.getPDFName(fontName));
        float stringWidth = font.getStringWidth("Tilman Hausherr Tilman Hausherr");
        System.out.println("stringWidth: " + stringWidth * fontSize / 1000);
        System.out.println("field width: " + fieldWidth);
    }
}

The output is:

/Helv 12 Tf 0 g
stringWidth: 180.7207
field width: 169.29082


标签: java pdf pdfbox