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 05:45:40 UTC
svn commit: r1794784 - in /pdfbox/trunk/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 05:45:40 2017
New Revision: 1794784
URL: http://svn.apache.org/viewvc?rev=1794784&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/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormTest.java
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java?rev=1794784&r1=1794783&r2=1794784&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java Thu May 11 05:45:40 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;
@@ -58,7 +59,7 @@ import org.apache.pdfbox.util.Matrix;
public final class PDAcroForm implements COSObjectable
{
private static final Log LOG = LogFactory.getLog(PDAcroForm.class);
-
+
private static final int FLAG_SIGNATURES_EXIST = 1;
private static final int FLAG_APPEND_ONLY = 1 << 1;
@@ -89,6 +90,43 @@ 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);
+ }
}
/**
Modified: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormTest.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormTest.java?rev=1794784&r1=1794783&r2=1794784&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormTest.java (original)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormTest.java Thu May 11 05:45:40 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,6 +136,76 @@ 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
@@ -137,5 +213,35 @@ public class PDAcroFormTest
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();
+ }
+
}