Search code examples
c#pdfitextadobe

Text content hidden behind PDF stamp after flattening form fields - iTextSharp, Adobe


If I don't flatten the form fields, the content appears over the stamp as expected. When I do flatten, the content is hidden behind the stamp. If I load the PDF into Adobe I can move the stamp and see the content behind it.

The PDF template was created in Adobe Acrobat Reader DC (see bottom for version details). I fill in the document fields with conditional data using iTextSharp and return the PDF bytes.

PDF Stamp, before move

PDF Stamp, after move

// flatten fields
pdfStamper.FormFlattening = true;
// stamping
var fields = stamper.AcroFields;

stamper.AcroFields.SetFieldProperty(fieldName, "textsize", fontSize, null);
fields.SetField(fieldName, value);
fields.SetFieldProperty(fieldName.ToString(),
    "setfflags",
    PdfFormField.FF_READ_ONLY,
    null); 

iTextSharp 5.5.12

Adobe Acrobat Reader DC 20.6.20042.371103


Solution

  • Why Is That Happening

    When a PDF page is displayed, its static content is drawn first and all kinds of annotations are drawn thereafter on that static content. The annotations are drawn in the order in which they occur in the annotations array of the page.

    Thus,

    If I don't flatten the form fields, the content appears over the stamp as expected.

    Apparently you here mean the content of the form fields, not the static page content. Then this means simply that the stamp annotation occurs in the annotation array before the form field widget annotations.

    When I do flatten, the content is hidden behind the stamp.

    As you only flatten the fields

    // flatten fields
    pdfStamper.FormFlattening = true;
    

    this is natural: Flattening the fields means adding their contents to the static page content and removing the field from the form and the field widgets from the annotations. Thus, the former field content is now part of the static page content and, therefore, drawn before any remaining annotations, in particular before the stamp.

    What To Do

    If you want the field contents to appear over the stamp, you have two options:

    • Don't flatten the form fields - If you don't flatten the form fields, their content remains in annotations which due to the order in the annotation array are drawn over the stamp

      To have a certain flattening-like effect you can set the form field read-only (as you already do) and their widget annotations locked.

    • Flatten the stamp first - If you flatten the non-field annotations first, their contents are added to the static page contents first. Thus, if you thereafter flatten the fields, the field contents will appear over the stamp contents.

      iText has another property to ask for flattening non-field annotations:

      pdfStamper.AnnotationFlattening = true;
      

      Unfortunately it does not have a built-in feature to simply flatten all annotations (form field widgets and other annotations) in one go in the order in which they occur on the page. Even if you set both FormFlattening and AnnotationFlattening to true, the form field widgets are flattened before the other annotations.

      Thus, you'll have to stamp your PDF twice: In the first stamping step you set only AnnotationFlattening to true and in the second stamping set you set FormFlattening to true.