pdf-lib icon indicating copy to clipboard operation
pdf-lib copied to clipboard

PDF form text field setText does not use font

Open psyanite opened this issue 2 years ago • 7 comments

Hi there, thanks for creating the best PDF library on the internet! I ran into some issues trying to fill text fields on my AcroForm

What were you trying to do?

I tried to use PDF-LIB form.getTextField('dateTaken').setText('hello this is my text') to set some text fields on my form. But the fonts I configured in Adobe Acrobat Pro is ignored.

I created a form using Adobe Acrobat Pro When creating the fields in Adobe Acrobat Pro I can edit the text field properties and set a font. Screen Shot 2023-01-13 at 10 29 44 am

When I fill the form in Adobe Acrobat it fills correctly, the font size, color, and font is maintained: Screen Shot 2023-01-13 at 10 25 46 am

But when I use the following code:

      form.getTextField('dateTaken').setText('hello this is my text')
      const pdfBytes = await pdfDoc.save()
      download(pdfBytes, "result.pdf", "application/pdf")

And save the pdf, the font is not maintained: Screen Shot 2023-01-13 at 10 26 49 am

How did you attempt to do it?

  <head>
    <meta charset="utf-8" />
    <script src="https://unpkg.com/[email protected]"></script>
    <script src="https://unpkg.com/[email protected]"></script>
  </head>

<script>
    const { PDFDocument } = PDFLib
    async function fillForm() {

      var myPdfInBytes = await document.getElementById("mypdf").files[0].arrayBuffer()
      const pdfDoc = await PDFDocument.load(myPdfInBytes)
      const form = pdfDoc.getForm()

      // Fill text fields
      form.getTextField('dateTaken').setText('hello this is my text')

      const pdfBytes = await pdfDoc.save()
      download(pdfBytes, "result.pdf", "application/pdf")
    }
  </script>

What actually happened?

The generated PDF shows the correct text, the correct font color and font size, but not the correct font.

All fonts are embedded: Screen Shot 2023-01-13 at 10 36 02 am

What did you expect to happen?

I expected the text fields to be in the correct font, like when I filled the form out using Adobe Acrobat.

How can we reproduce the issue?

JSFIDDLE: https://jsfiddle.net/psyanite/9vdeq2nt/35/

Test PDF: test.pdf

Version

latest version

What environment are you running pdf-lib in?

Browser

Checklist

  • [X] My report includes a Short, Self Contained, Correct (Compilable) Example.
  • [X] I have attached all PDFs, images, and other files needed to run my SSCCE.

Additional Notes

No response

psyanite avatar Jan 12 '23 23:01 psyanite

same problems... there is a solution?

pietrondo avatar Feb 06 '23 15:02 pietrondo

Edit: I found the problem when i scanned trough the code i think.

When the PDFTextField.setText('string') command i called it markes the field as "dirty" that somehow tells the library that the field needs updating in styling. If you tried to add the font by yourself with PDFDocument.embedFont(font) and then try to update the apperance with PDFTextField.updateAppearances() it still marks it as dirty and changes the font.

The solution i found was that the updateAppearances(font) command marks it as clean again so as long as you call the updateAppearances() after you call the setText() the field is marked as clean and the program wont change your font

I dont think i have the coding skills neccessary to make a fix for it but this is a half solution until someone smarter can fix it :)

Example

// Imports
const { PDFDocument } = require('pdf-lib')
const { readFile } = require('fs/promises')
const fontkit = require('@pdf-lib/fontkit')
// Import pdf document
const document = await PDFDocument.load(await readFile('/path/to/file.pdf'))
// Create a custom font
document.registerFontkit(fontkit)
const custonFont = await document.embedFont(await readFile('/custom/font.ttf'))
// Get form and field
const form = document.getForm()
const titleField = form.getTextField('form identifier')
// Set the text and after update to font
titleField.setText(object.title)
titleField.updateAppearances(custonFont)

coffedahl avatar Apr 27 '23 21:04 coffedahl

I was doing textField.updateAppearances(font) and then textField.setAlignment(alignment). This caused the same problem. So I believe the final word is: just use updateAppearances after you did all setters

yepMad avatar Jul 27 '23 20:07 yepMad

I do not see the needed font even after the updateAppearances in the pdf the field is marked as using the right font, but opening the file I do not see the right font.

gioppoluca avatar Nov 05 '23 17:11 gioppoluca

I'm having similar problem. Another issue mentioned it working only after form.flatten() is called. Unfortunately this makes the fields uneditable (additionally I am facing issue where text is garbled when using {subset: true} when embedding the font, but it's probably not related to use of flatten).

tacomanator avatar Jan 08 '24 23:01 tacomanator

I'm having the same issue. Thanks coffedahl for the workaround. FYI: calling form.updateFieldAppearances(pdfFont) on the entire form also solved the issue and maybe easier to achieve in some cases.

morbalint avatar Feb 13 '24 10:02 morbalint

Hello,

Facing same issue, i don't understand why if i have a font already embedded and used for the whole PDF and its forms fields i have to embed the same font again, this is clearly a BUG. Anyone knows how to force form text fields to use the same font and style already set for the whole PDF and its form fields without embed another one? The thing about dirty and clear is riducolous, why the lib should force using Helvetica when form fields already have their style set?

p3pp8 avatar May 10 '24 08:05 p3pp8