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 2020/11/01 16:37:33 UTC

svn commit: r1883054 - in /pdfbox/branches/2.0/pdfbox/src: main/java/org/apache/pdfbox/pdmodel/fixup/processor/AcroFormOrphanWidgetsProcessor.java test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormFromAnnotsTest.java

Author: msahyoun
Date: Sun Nov  1 16:37:33 2020
New Revision: 1883054

URL: http://svn.apache.org/viewvc?rev=1883054&view=rev
Log:
PDFBOX-3891: add font resources from widget annotation to AcroForm if existing; add test

Modified:
    pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/fixup/processor/AcroFormOrphanWidgetsProcessor.java
    pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormFromAnnotsTest.java

Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/fixup/processor/AcroFormOrphanWidgetsProcessor.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/fixup/processor/AcroFormOrphanWidgetsProcessor.java?rev=1883054&r1=1883053&r2=1883054&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/fixup/processor/AcroFormOrphanWidgetsProcessor.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/fixup/processor/AcroFormOrphanWidgetsProcessor.java Sun Nov  1 16:37:33 2020
@@ -35,6 +35,7 @@ import org.apache.pdfbox.pdmodel.font.Fo
 import org.apache.pdfbox.pdmodel.font.PDType0Font;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
 import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
 import org.apache.pdfbox.pdmodel.interactive.form.PDField;
 import org.apache.pdfbox.pdmodel.interactive.form.PDFieldFactory;
@@ -104,10 +105,14 @@ public class AcroFormOrphanWidgetsProces
 
     private void handleAnnotations(PDAcroForm acroForm, List<PDField> fields, List<PDAnnotation> annotations, Map<String, PDField> nonTerminalFieldsMap)
     {
+        PDResources acroFormResources = acroForm.getDefaultResources();
+
         for (PDAnnotation annot : annotations)
         {
             if (annot instanceof PDAnnotationWidget)
             {
+                addFontFromWidget(acroFormResources, annot);
+
                 if (annot.getCOSObject().containsKey(COSName.PARENT))
                 {
                     PDField resolvedField = resolveNonRootField(acroForm, (PDAnnotationWidget) annot, nonTerminalFieldsMap);
@@ -122,6 +127,41 @@ public class AcroFormOrphanWidgetsProces
                 }
             }
         }
+    }
+
+    /*
+     *  Add font resources from the widget to the AcroForm to make sure embedded fonts are being
+     *  used and not added by ensureFontResources potentially using a fallback font
+     */
+    private void addFontFromWidget(PDResources acroFormResources, PDAnnotation annotation)
+    {
+        PDAppearanceStream normalAppearanceStream = annotation.getNormalAppearanceStream();
+        if (normalAppearanceStream != null && normalAppearanceStream.getResources() != null)    
+        {
+            PDResources widgetResources = normalAppearanceStream.getResources();
+            for (COSName fontName : widgetResources.getFontNames())
+            {
+                if (!fontName.getName().startsWith("+"))
+                {
+                    try
+                    {
+                        if (acroFormResources.getFont(fontName) == null)
+                        {
+                            acroFormResources.put(fontName, widgetResources.getFont(fontName));
+                            LOG.debug("qdded font resource to AcroForm from widget for font name " + fontName.getName());
+                        }
+                    }
+                    catch (IOException ioe)
+                    {
+                        LOG.debug("unable to add font to AcroForm for font name " + fontName.getName());
+                    }
+                }
+                else
+                {
+                    LOG.debug("font resource for widget was a subsetted font - ignored: " + fontName.getName());
+                }
+            }
+        }
     }
 
     /*

Modified: pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormFromAnnotsTest.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormFromAnnotsTest.java?rev=1883054&r1=1883053&r2=1883054&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormFromAnnotsTest.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroFormFromAnnotsTest.java Sun Nov  1 16:37:33 2020
@@ -30,9 +30,11 @@ import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.io.IOUtils;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
+import org.apache.pdfbox.pdmodel.PDResources;
 import org.apache.pdfbox.pdmodel.fixup.AbstractFixup;
 import org.apache.pdfbox.pdmodel.fixup.AcroFormDefaultFixup;
 import org.apache.pdfbox.pdmodel.fixup.processor.AcroFormOrphanWidgetsProcessor;
+import org.apache.pdfbox.pdmodel.font.PDFont;
 import org.junit.Test;
 
 /**
@@ -258,6 +260,82 @@ public class PDAcroFormFromAnnotsTest
             }
         }
         finally
+        {
+            IOUtils.closeQuietly(testPdf);
+        }
+    }
+
+    /**
+     * PDFBOX-3891 AcroForm with empty fields entry
+     * 
+     * Check if the font resources added by PDFBox matches these by Acrobat
+     * which are taken from the widget normal appearance resources
+     * 
+     * @throws IOException
+     */
+    @Test
+    public void testFromAnnots3891ValidateFont() throws IOException
+    {
+
+        String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12881055/merge-test.pdf";
+        String acrobatSourceUrl = "https://issues.apache.org/jira/secure/attachment/13014447/merge-test-na-acrobat.pdf";
+
+        // will build the expected font respurce names and font decriptor names using the acrobat source document
+        Map<String, String> fontNames = new HashMap<String, String>();
+
+        PDDocument testPdf = null;
+        try
+        {
+            testPdf = PDDocument.load(new URL(acrobatSourceUrl).openStream());
+            PDDocumentCatalog catalog = testPdf.getDocumentCatalog();
+            PDAcroForm acroForm = catalog.getAcroForm(null);
+            PDResources acroFormResources = acroForm.getDefaultResources();
+            if (acroFormResources != null)
+            {
+                for (COSName fontName : acroFormResources.getFontNames())
+                {
+                    try
+                    {
+                        PDFont font = acroFormResources.getFont(fontName);
+                        font.getFontDescriptor().getFontName();
+                        fontNames.put(fontName.getName(), font.getName());
+                    }
+                    catch (IOException ioe)
+                    {
+                        //ignoring
+                    }
+                }
+            }
+        }
+        finally
+        {
+            IOUtils.closeQuietly(testPdf);
+        }
+
+        try
+        {
+            testPdf = PDDocument.load(new URL(sourceUrl).openStream());
+            PDDocumentCatalog catalog = testPdf.getDocumentCatalog();
+            PDAcroForm acroForm = catalog.getAcroForm(new CreateFieldsFixup(testPdf));
+            PDResources acroFormResources = acroForm.getDefaultResources();
+            if (acroFormResources != null)
+            {
+                for (COSName fontName : acroFormResources.getFontNames())
+                {
+                    try
+                    {
+                        PDFont font = acroFormResources.getFont(fontName);
+                        String pdfBoxFontName = font.getFontDescriptor().getFontName();
+                        assertEquals("font resource added by Acrobat shall match font resource added by PDFBox", fontNames.get(fontName.getName()), pdfBoxFontName);
+                    }
+                    catch (IOException ioe)
+                    {
+                        //ignoring
+                    }
+                }
+            }
+        }
+        finally
         {
             IOUtils.closeQuietly(testPdf);
         }