You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ms...@apache.org on 2017/05/11 06:05:07 UTC

svn commit: r1794785 - in /pdfbox/branches/2.0/pdfbox/src: main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormTest.java

Author: msahyoun
Date: Thu May 11 06:05:06 2017
New Revision: 1794785

URL: http://svn.apache.org/viewvc?rev=1794785&view=rev
Log:
PDFBOX-3732: ensure default entries for /DA and /DR when accessing an AcroForm and the form doesn't contain these

Modified:
    pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java
    pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormTest.java

Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java?rev=1794785&r1=1794784&r2=1794785&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java Thu May 11 06:05:06 2017
@@ -43,6 +43,7 @@ import org.apache.pdfbox.pdmodel.fdf.FDF
 import org.apache.pdfbox.pdmodel.fdf.FDFDictionary;
 import org.apache.pdfbox.pdmodel.fdf.FDFDocument;
 import org.apache.pdfbox.pdmodel.fdf.FDFField;
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
 import org.apache.pdfbox.pdmodel.graphics.PDXObject;
 import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
@@ -89,7 +90,45 @@ public final class PDAcroForm implements
     {
         document = doc;
         dictionary = form;
+        verifyOrCreateDefaults();
     }
+    
+    /*
+     * Verify that there are default entries for required 
+     * properties.
+     * 
+     * If these are missing create default entries similar to
+     * Adobe Reader / Adobe Acrobat
+     *  
+     */
+    private void verifyOrCreateDefaults()
+    {
+        // TODO: the handling of the missing properties is suitable
+        // if there are no entries at all. It might be necessary to enhance that
+        // if only parts are missing
+        
+        final String AdobeDefaultAppearanceString = "/Helv 0 Tf 0 g ";
+
+        // DA entry is required
+        if (getDefaultAppearance().length() == 0)
+        {
+            setDefaultAppearance(AdobeDefaultAppearanceString);
+        }
+        
+        // DR entry is required
+        if (getDefaultResources() == null)
+        {
+            // Adobe Acrobat uses Helvetica as a default font and 
+            // stores that under the name '/Helv' in the resources dictionary
+            // Zapf Dingbats is included per default for check boxes and 
+            // radio buttons as /ZaDb.
+            PDResources resources = new PDResources();
+            resources.put(COSName.getPDFName("Helv"), PDType1Font.HELVETICA);
+            resources.put(COSName.getPDFName("ZaDb"), PDType1Font.ZAPF_DINGBATS);
+            setDefaultResources(resources);
+        }
+    }
+    
 
     /**
      * This will get the document associated with this form.

Modified: pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormTest.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormTest.java?rev=1794785&r1=1794784&r2=1794785&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormTest.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormTest.java Thu May 11 06:05:06 2017
@@ -21,11 +21,17 @@ import static org.junit.Assert.assertNot
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 
+import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
 import org.apache.pdfbox.rendering.TestPDFToImage;
 import org.junit.After;
@@ -130,11 +136,109 @@ public class PDAcroFormTest
         }
     }
     
+    /*
+     * Test that we do not modify an AcroForm with missing resource information
+     * when loading the document only.
+     * (PDFBOX-3752)
+     */
+    @Test
+    public void testDontAddMissingInformationOnDocumentLoad()
+    {
+        try
+        {
+            byte[] pdfBytes =  createAcroFormWithMissingResourceInformation();
+            PDDocument pdfDocument = PDDocument.load(pdfBytes);
+            
+            // do a low level access to the AcroForm to avoid the generation of missing entries
+            PDDocumentCatalog documentCatalog = pdfDocument.getDocumentCatalog();
+            COSDictionary catalogDictionary = documentCatalog.getCOSObject();
+            COSDictionary acroFormDictionary = (COSDictionary) catalogDictionary.getDictionaryObject(COSName.ACRO_FORM);
+
+            // ensure that the missing information has not been generated
+            assertNull(acroFormDictionary.getDictionaryObject(COSName.DA));
+            assertNull(acroFormDictionary.getDictionaryObject(COSName.RESOURCES));
+            
+            pdfDocument.close();
+        }
+        catch (IOException e)
+        {
+            System.err.println("Couldn't create test document, test skipped");
+            return;
+        }
+    } 
+    
+    /*
+     * Test that we add missing ressouce information to an AcroForm 
+     * when accessing the AcroForm on the PD level
+     * (PDFBOX-3752)
+     */
+    @Test
+    public void testAddMissingInformationOnAcroFormAccess()
+    {
+        try
+        {
+            byte[] pdfBytes =  createAcroFormWithMissingResourceInformation();
+            PDDocument pdfDocument = PDDocument.load(pdfBytes);
+            PDDocumentCatalog documentCatalog = pdfDocument.getDocumentCatalog();
+            
+            // this call shall trigger the generation of missing information
+            PDAcroForm theAcroForm = documentCatalog.getAcroForm();
+            
+            // ensure that the missing information has been generated
+            // DA entry
+            assertEquals("/Helv 0 Tf 0 g ", theAcroForm.getDefaultAppearance());
+            assertNotNull(theAcroForm.getDefaultResources());
+            
+            // DR entry
+            PDResources acroFormResources = theAcroForm.getDefaultResources();
+            assertNotNull(acroFormResources.getFont(COSName.getPDFName("Helv")));
+            assertEquals("Helvetica", acroFormResources.getFont(COSName.getPDFName("Helv")).getName());
+            assertNotNull(acroFormResources.getFont(COSName.getPDFName("ZaDb")));
+            assertEquals("ZapfDingbats", acroFormResources.getFont(COSName.getPDFName("ZaDb")).getName());
+
+            pdfDocument.close();
+        }
+        catch (IOException e)
+        {
+            System.err.println("Couldn't create test document, test skipped");
+            return;
+        }
+    }
+    
     @After
     public void tearDown() throws IOException
     {
         document.close();
     }
 
+    private byte[] createAcroFormWithMissingResourceInformation() throws IOException
+    {
+        PDDocument document = new PDDocument();
+        PDPage page = new PDPage();
+        document.addPage(page);
+
+        PDAcroForm newAcroForm = new PDAcroForm(document);
+        document.getDocumentCatalog().setAcroForm(newAcroForm);
+
+        PDTextField textBox = new PDTextField(newAcroForm);
+        textBox.setPartialName("SampleField");
+        newAcroForm.getFields().add(textBox);
+
+        PDAnnotationWidget widget = textBox.getWidgets().get(0);
+        PDRectangle rect = new PDRectangle(50, 750, 200, 20);
+        widget.setRectangle(rect);
+        widget.setPage(page);
+
+        page.getAnnotations().add(widget);
+
+        // acroForm.setNeedAppearances(true);
+        // acroForm.getField("SampleField").getCOSObject().setString(COSName.V, "content");
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        document.save(baos); // this is a working PDF
+        document.close();
+        return baos.toByteArray();
+    }
+    
 }