Adobe Displays a Border when Annotation Border Width Zero

Question: I set the border for my annotation to 0 but it some viewers, such as Adobe, still displays the border.

Answer: This is a well-known compatibility issue between PDF generation logic and Adobe Acrobat’s form rendering behavior you are encountering, as Adobe Acrobat ignores thickness = 0 for form fields and defaults to a “Thin” border. This is Adobe-specific behavior, not standard PDF/ISO 32000. To resolve this here is an example to remove the annotation appearance stream and the optional appearance characteristics dictionary.

const { PDFNet } = require('@pdftron/pdfnet-node');

const main = async () => {
  const pdf_doc = await PDFNet.PDFDoc.createFromFilePath('./merged.xfdf.pdf');
  
  pdf_doc.initSecurityHandler();
  
  // Here we loop through the PDF pages to access the annotatons.
  const page_iterator = await pdf_doc.getPageIterator();
  for (; await page_iterator.hasNext(); page_iterator.next()) {
    const page = await page_iterator.current();

    // And for each annotation on the page remove the border color
    const num_annotations = await page.getNumAnnots();
    for (let i = 0; i < num_annotations; i++) {
      const annot = await page.getAnnot(i);

      // Access the annotations SDF/Cos objects
      const sdfObj = await annot.getSDFObj();

      // Remove the appearance stream for the annotation which has the
      // border color. A new default apperance stream will be created
      // when annotation apperances are refreshed below.
      const ap = await sdfObj.findObj('AP');
      if (ap) {
        await sdfObj.eraseFromKey('AP');
      }

      // Remove the border color from the optional appearance characteristcs
      // dictionary if present.
      const mkObj = await sdfObj.findObj('MK');
      if (mkObj && await mkObj.isDict()) {
        if (await mkObj.isDict()) {
          await mkObj.eraseFromKey('BC');   // Border Color
        }
      }
    }
  }

  // Refrest the annotation apperances in the output.
  pdf_doc.refreshAnnotAppearances();

  await pdf_doc.save('./output.field.pdf', PDFNet.SDFDoc.SaveOptions.e_remove_unused);
};

PDFNet.runWithCleanup(main, "[YOUR LICENSE HERE]")
  .catch(err => console.error(err))
  .then(() => PDFNet.shutdown());

Helpful Links:

1 Like