empira / PDFsharp

PDFsharp and MigraDoc Foundation for .NET 6 and .NET Framework
https://docs.pdfsharp.net/
Other
518 stars 127 forks source link

Filled AcroForm fields do not respect newlines #67

Open TechnoPorg opened 10 months ago

TechnoPorg commented 10 months ago

Expected Behavior

When setting the Text of an AcroForm PdfTextField, it is expected that one should be able to write newlines by including \n in the string - for example, "Test line 1\nTest Line 2" should display on two separate lines in the resulting PDF.

Actual Behavior

PDFSharp still recognizes newlines when they are loaded in from a file. However, when trying to save a PDF yourself which has newlines in the text, they get removed, and all text ends up on one line.

Steps to Reproduce the Behavior

Loading the attached example PDF with pre-filled form text will clearly show the \ns in the Text property are present and loaded:

PdfDocument load_example = PdfReader.Open("path/to/load_file_example.pdf");
Console.WriteLine((load_example.AcroForm.Fields["Test Field"] as PdfTextField).Text);

But when an empty field's text is changed, note that when looking at the resulting PDF output in a browser, it will not contain any of the newlines that were added to it.

PdfDocument save_example = PdfReader.Open("path/to/save_file_example.pdf");
(save_example.AcroForm.Fields["Test Field"] as PdfTextField).Text = "Test Line 1\nTest Line 2";
save_example.Save("path/to/modified_save_example.pdf");

load_file_example.pdf save_file_example.pdf

SvenLx commented 2 months ago

We also stumbled across this bug and it took us a long time to investigate as we assumed to have a problem in the input PDF. In PdfSharp.Pdf.AcroForms.PdfTextField, XTextFormatter.DrawString(...) needs to be used instead of gfx.DrawString(...) in order to support newlines. This is the whole fix:

private void RenderAppearance()
{
  ...
  string text = Text;
  if (text.Length > 0)
  {
        XTextFormatter tf = new XTextFormatter(gfx);
        tf.DrawString(Text, Font, new XSolidBrush(ForeColor),
            rect.ToXRect() - rect.Location + new XPoint(2, 0), XStringFormats.TopLeft);
  }
  form.DrawingFinished();
  ...
}

May I set up a pull request or can someone please do so?