Uploaded image for project: 'PDFBox'
  1. PDFBox
  2. PDFBOX-4615

AppearanceGeneratorHelper.setAppearanceValue doesn't set the bounding box on the appearance stream correctly

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.0.16
    • Fix Version/s: 2.0.17, 3.0.0 PDFBox
    • Component/s: AcroForm
    • Labels:
      None

      Description

      Hello, thanks for all your effort with PDFBox. We use it heavily for parsing and flattening PDFs.

      BUG: In the attached PDF "resetboundingbox.pdf", we programmatically set the value of the text fields, then call pdAcroForm.flattten(), which produces the flattened PDF "flattenedboundingbox.pdf." I would expect that the text would entirely fill the text box (see textbox with green border in "flattenedboundingbox.pdf") but the text does not. Instead, the filled text area obeys another box instead (see text area with red border in "flattenedboundingbox.pdf").

      POTENTIAL FIX: We've traced the problem to AppearanceGeneratorHelper.setAppearanceValue, lines 200-210. As long as we always set the bounding box (line 243) like in AppearanceGeneratorHelper.prepareNormalAppearanceStream, regardless of the if/else at line 200, then the flattening works correctly:

      /** * replace AppearanceGeneratorHelper lines 199-210 with: */ 
      PDAppearanceStream appearanceStream = appearance != null && appearance.isStream() ? appearance.getAppearanceStream() : new PDAppearanceStream(field.getAcroForm().getDocument());
       
      // copied from lines 237-243 
      int rotation = resolveRotation(widget);
      PDRectangle rect = widget.getRectangle(); 
      Matrix matrix = Matrix.getRotateInstance(Math.toRadians(rotation), 0, 0); 
      Point2D.Float point2D = matrix.transformPoint(rect.getWidth(), rect.getHeight()); 
      PDRectangle bbox = new PDRectangle(Math.abs((float) point2D.getX()), Math.abs((float) point2D.getY())); 
      appearanceStream.setBBox(bbox); 
      
      appearanceDict.setNormalAppearance(appearanceStream);
      

      Something I'm not sure about: in method prepareNormalAppearanceStream, there is additional code for setting the matrix (lines 245-251), which we don't seem to need. Since it doesn't break anything, we just keep it too.

      Thanks again for your help!

        Attachments

        1. flattenedboundingbox.pdf
          264 kB
          Rosalind Douglas
        2. resetboundingbox.pdf
          263 kB
          Rosalind Douglas
        3. resetboundingbox-flattened-bugfix.pdf
          305 kB
          Tilman Hausherr
        4. resetboundingbox-flattened.pdf
          305 kB
          Tilman Hausherr
        5. resetboundingbox-filled.pdf
          308 kB
          Tilman Hausherr
        6. resetboundingbox-filled-acrobat.pdf
          263 kB
          Maruan Sahyoun
        7. resetboundingbox-filled-acrobat-flatten-js.pdf
          263 kB
          Maruan Sahyoun
        8. resetboundingbox-filled-acrobat-preflight.pdf
          262 kB
          Maruan Sahyoun
        9. resetboundingbox-filled-flatten-js.pdf
          262 kB
          Maruan Sahyoun
        10. resetboundingbox-filled-flatten.preflight.pdf
          302 kB
          Maruan Sahyoun

          Issue Links

            Activity

              People

              • Assignee:
                tilman Tilman Hausherr
                Reporter:
                rosalind.douglas Rosalind Douglas
              • Votes:
                1 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: