PdfBox-Android icon indicating copy to clipboard operation
PdfBox-Android copied to clipboard

Freetext Annotations use AcroForm resource for font loading instead of PDPage resource.

Open JaseElder opened this issue 1 year ago • 1 comments

Freetext annotations have a font associated, and the font is set by a default appearance string:

PDAnnotationMarkup textAnnotation = new PDAnnotationMarkup();
textAnnotation.getCOSObject().setName(COSName.SUBTYPE, PDAnnotationMarkup.SUB_TYPE_FREETEXT);
textAnnotation.setDefaultAppearance("/Helv 12 Tf 1 0 0 rg");

This sets a size 12 Helvetica font, where Helvetica is a default font provided by the PDF.

Fonts can be added to a PDF through the page resources:

PDPage page = document.getPage(pageNo);
PDResources res = page.getResources();
Encoding encoding = Encoding.getInstance(COSName.WIN_ANSI_ENCODING);
InputStream inStream = getAssets().open("Roboto-Regular.ttf");
PDFont font = PDTrueTypeFont.load(document, inStream, encoding);
COSName cosFontName = res.add(font);

The annotation doesn't display the font even though it is now in the resources.

After a lot of banging my head against the wall to get the DA string to accept the new font, I trawled through the source, and discovered that the Freetext annotation gets its fonts from the AcroForm resources. The method to add is similar to above, except the resource is created this way:

PDResources res = document.getDocumentCatalog().getAcroForm().getDefaultResources();

and now the font is reachable.

The font is set in com.tom_roush.pdfbox.pdmodel.interactive.annotation.handlers.PDFreeTextAppearanceHandler, lines 244-258.

My question is why does a text annotation rely on an AcroForm for its font resources? I'm not using forms in my project, so it seems like a crossover of concerns. Also the pages resources are where the other fonts reside, including the default fonts. Is this a bug, or intentional?

Related question: Is there any other way to set the font face and size for a freetext annotation? To use a DA string, it's necessary to find out what the COSName is for an installed font, and use that in the string, usually something along the lines of F4, F5 etc. Is it possible to change the COSName for the font?

Environment details:

  • PdfBox-Android version: 2.0.27.0
  • Android API version: API 31

JaseElder avatar Mar 07 '23 20:03 JaseElder

My question is why does a text annotation rely on an AcroForm for its font resources?

I did that one 4 years ago in PDFBox for desktop. IIRC I was trying to mirror the behavior from Adobe Reader. You need to use the names that are in these resources. Use PDFDebugger to discover more on your PDFs.

THausherr avatar May 20 '23 14:05 THausherr