I am currently struggling with withing a PDF form created from a LibreOffice document.
I created it like suggested in the book "iText in Action" and am now trying to pre-fill the embedded form with a few values, that can contain Unicode chars.
This includes a character that consist of base char with an addition combining char (e.G. M̂).
I have tried several different hints I found in in stackoverflow and the book, but I never got a PDF document with a form that works on all platforms: Linux (Okular, Evince, Acrobat DC, macOS Previewer, etc.)
I'm aware that I need to have a font, that covers the chars and embedded the font fully. Below there is the code I used to file the PDF document and the PDF file.
My questions are:
- Is the different behavior of the PDF readers specification weakness in the PDF specification and I have to live with it?
- Specially the Linux PDF readers and Acrobat behave badly. Are there known bugs?
- I'm not very familiar with internals of PDF, so any suggestions? Are the contents of my PDF files ok?
- Any suggestions on how to improve the code to get better results?
Code to fill the form:
BaseFont uniFont = BaseFont.createFont("./src/main/resources/UnicodeDoc.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, false, null, null, false);
uniFont.setSubset(false);
// Debugging code...
for (String codepage : uniFont.getCodePagesSupported()) {
System.out.println("Codepage = " + codepage);
}
FileInputStream fis = new FileInputStream(src);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfReader reader = new PdfReader(fis);
PdfStamper stamper = new PdfStamper(reader, baos);
// Fill all fields in PDF form
String text = "aM\u0302a"; // Same as "aM̂a"
com.itextpdf.text.pdf.AcroFields form = stamper.getAcroFields();
for (String fname : form.getFields().keySet()) {
System.out.println("form." + fname);
form.setField(fname, text);
form.setFieldProperty(fname, "textfont", uniFont, null);
}
form.setGenerateAppearances(true);
form.addSubstitutionFont(uniFont);
stamper.setFormFlattening(false);
stamper.close();
reader.close();
Thanks in advance, Mik86