You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlgraphics.apache.org by ss...@apache.org on 2023/07/21 10:36:27 UTC

[xmlgraphics-fop-pdf-images] branch main updated: FOP-3140: Merge form fields

This is an automated email from the ASF dual-hosted git repository.

ssteiner pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/xmlgraphics-fop-pdf-images.git


The following commit(s) were added to refs/heads/main by this push:
     new ed4a942  FOP-3140: Merge form fields
ed4a942 is described below

commit ed4a9422e67fe41791a7728ea857a38598d88aa2
Author: Simon Steiner <ss...@apache.org>
AuthorDate: Tue Jun 13 08:24:51 2023 +0100

    FOP-3140: Merge form fields
---
 .../render/pdf/pdfbox/AbstractPDFBoxHandler.java   |   4 +-
 .../fop/render/pdf/pdfbox/CloneAnnotations.java    |   3 +-
 .../fop/render/pdf/pdfbox/MergeAnnotations.java    | 145 +++++++++++++++++++++
 .../fop/render/pdf/pdfbox/PDFBoxAdapter.java       |  38 +++---
 .../fop/render/pdf/pdfbox/PDFBoxImageHandler.java  |   2 +-
 .../apache/fop/render/pdf/pdfbox/PDFCloner.java    |  10 +-
 .../render/pdf/pdfbox/PDFBoxAdapterTestCase.java   |  56 +++++++-
 .../fop/render/pdf/pdfbox/PDFClonerTestCase.java   |  12 +-
 .../org/apache/fop/render/pdf/pdfbox/annot2.pdf    | Bin 0 -> 50267 bytes
 .../org/apache/fop/render/pdf/pdfbox/annot3.pdf    | Bin 0 -> 50438 bytes
 10 files changed, 239 insertions(+), 31 deletions(-)

diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java b/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java
index 3bd5d14..6965d7c 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/AbstractPDFBoxHandler.java
@@ -51,7 +51,7 @@ public abstract class AbstractPDFBoxHandler {
 
     protected Object createStreamForPDF(ImagePDF image, PDFPage targetPage, FOUserAgent userAgent,
                                         AffineTransform pageAdjust, FontInfo fontinfo, Rectangle destRect,
-                                        Map<Integer, PDFArray> pageNumbers,
+                                        Map<String, Object> usedFieldNames, Map<Integer, PDFArray> pageNumbers,
                                         PDFLogicalStructureHandler handler,
                                         PDFStructElem curentSessionElem) throws IOException {
 
@@ -103,7 +103,7 @@ public abstract class AbstractPDFBoxHandler {
 
         Map<Object, Object> objectCache = getObjectCache(getClass().getName(), userAgent);
         PDFBoxAdapter adapter =
-                new PDFBoxAdapter(targetPage, objectCachePerFile, pageNumbers, objectCache);
+                new PDFBoxAdapter(targetPage, objectCachePerFile, usedFieldNames, pageNumbers, objectCache);
         if (handler != null) {
             adapter.setCurrentMCID(handler.getPageParentTree().length());
         }
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/CloneAnnotations.java b/src/java/org/apache/fop/render/pdf/pdfbox/CloneAnnotations.java
index 1e08c84..7beaeba 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/CloneAnnotations.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/CloneAnnotations.java
@@ -82,8 +82,7 @@ public class CloneAnnotations implements HandleAnnotations<COSObject> {
             COSDictionary dictionary = (COSDictionary) ((COSObject) annot).getObject();
             COSBase parent = dictionary.getItem(COSName.PARENT);
             if (parent != null) {
-                clonedAnnot.put(COSName.PARENT.getName(),
-                        new PDFCloner(pdfBoxAdapter).cloneForNewDocument(parent, parent, exclude));
+                clonedAnnot.put(COSName.PARENT.getName(), pdfBoxAdapter.cloneForNewDocument(parent, parent, exclude));
             }
         }
     }
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/MergeAnnotations.java b/src/java/org/apache/fop/render/pdf/pdfbox/MergeAnnotations.java
new file mode 100644
index 0000000..0f98b1d
--- /dev/null
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/MergeAnnotations.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+package org.apache.fop.render.pdf.pdfbox;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSObject;
+import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
+
+import org.apache.fop.pdf.PDFArray;
+import org.apache.fop.pdf.PDFDictionary;
+import org.apache.fop.pdf.PDFDocument;
+
+public class MergeAnnotations implements HandleAnnotations<Object> {
+    private PDFBoxAdapter pdfBoxAdapter;
+    private Map<String, Object> fields;
+
+    public MergeAnnotations(PDFBoxAdapter pdfBoxAdapter, Map<String, Object> fields) {
+        this.pdfBoxAdapter = pdfBoxAdapter;
+        this.fields = fields;
+    }
+
+    public Set<Object> getFields() {
+        return new HashSet<>(fields.values());
+    }
+
+    public void load(COSObject annot, PDAcroForm srcAcroForm) {
+        //not used
+    }
+
+    public void cloneAnnotParent(COSBase annot, PDFDictionary clonedAnnot, Collection<COSName> exclude)
+        throws IOException {
+        if (clonedAnnot.containsKey("T")) {
+            List<String> nameList = new ArrayList<>();
+            addToTree(clonedAnnot, nameList);
+            PDFDictionary node = (PDFDictionary) fields.get(nameList.remove(0));
+            while (!nameList.isEmpty()) {
+                String name = nameList.remove(0);
+                PDFDictionary nextNode = findKid(name, node);
+                if (nextNode == null) {
+                    if (nameList.isEmpty()) {
+                        nextNode = node;
+                    } else {
+                        nextNode = new PDFDictionary();
+                        pdfBoxAdapter.pdfDoc.registerTrailerObject(nextNode);
+                        nextNode.put("Kids", new PDFArray());
+                        nextNode.put("T", name);
+                        nextNode.put("Parent", node);
+                        PDFArray kids = (PDFArray) node.get("Kids");
+                        kids.add(nextNode);
+                    }
+                }
+                node = nextNode;
+            }
+            if (node != clonedAnnot) {
+                insert(node, clonedAnnot);
+            }
+        }
+    }
+
+    private void insert(PDFDictionary parent, PDFDictionary clonedAnnot) throws IOException {
+        if (parent.containsKey("Kids")) {
+            PDFArray kids = (PDFArray) parent.get("Kids");
+            kids.add(clonedAnnot);
+        } else {
+            PDFDictionary grandParent = (PDFDictionary) parent.get("Parent");
+            PDFDictionary child = parent;
+            parent = new PDFDictionary();
+            if (grandParent != null) {
+                PDFArray kids = (PDFArray) grandParent.get("Kids");
+                kids.add(parent);
+            }
+            pdfBoxAdapter.pdfDoc.registerTrailerObject(parent);
+            List<String> excludeCopy = Arrays.asList("Subtype", "Type", "Rect", "MK", "F");
+            for (String key : child.keySet()) {
+                if (!excludeCopy.contains(key)) {
+                    parent.put(key, child.get(key));
+                }
+            }
+            child.remove("T");
+            child.put("Parent", parent);
+            parent.put("Kids", new PDFArray(clonedAnnot, child));
+
+        }
+        if (getT(clonedAnnot).equals(getT(parent))) {
+            clonedAnnot.remove("T");
+        }
+        clonedAnnot.put("Parent", parent);
+    }
+
+    private PDFDictionary findKid(String name, PDFDictionary node) throws IOException {
+        PDFArray kids = (PDFArray) node.get("Kids");
+        for (int i = 0; i < kids.length(); i++) {
+            PDFDictionary kid = (PDFDictionary) kids.get(i);
+            if (name.equals(getT(kid))) {
+                return kid;
+            }
+        }
+        return null;
+    }
+
+    private void addToTree(PDFDictionary clonedAnnot, List<String> nameList) throws IOException {
+        String tStr = getT(clonedAnnot);
+        nameList.add(0, tStr);
+        Object parent = clonedAnnot.get("Parent");
+        if (parent instanceof PDFDictionary) {
+            addToTree((PDFDictionary) parent, nameList);
+        } else if (!fields.containsKey(tStr)) {
+            fields.put(tStr, clonedAnnot);
+        }
+    }
+
+    private String getT(PDFDictionary clonedAnnot) throws IOException {
+        Object tStr = clonedAnnot.get("T");
+        if (tStr instanceof byte[]) {
+            tStr = new String((byte[]) tStr, PDFDocument.ENCODING);
+        }
+        return (String) tStr;
+    }
+}
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java b/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
index 5ad2a3b..ac40acd 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
@@ -43,7 +43,6 @@ import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.cos.COSObject;
 import org.apache.pdfbox.cos.COSStream;
-
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
 import org.apache.pdfbox.pdmodel.PDPage;
@@ -96,17 +95,21 @@ public class PDFBoxAdapter {
      */
     public PDFBoxAdapter(PDFPage targetPage, Map<Object, Object> objectCachePerFile,
                          Map<Integer, PDFArray> pageNumbers) {
-        this(targetPage, objectCachePerFile, pageNumbers, new HashMap<Object, Object>());
+        this(targetPage, objectCachePerFile, null, pageNumbers, new HashMap<>());
     }
 
-    public PDFBoxAdapter(PDFPage targetPage, Map<Object, Object> objectCachePerFile,
+    public PDFBoxAdapter(PDFPage targetPage, Map<Object, Object> objectCachePerFile, Map<String, Object> usedFields,
                          Map<Integer, PDFArray> pageNumbers, Map<Object, Object> objectCache) {
         this.targetPage = targetPage;
         this.pdfDoc = this.targetPage.getDocument();
         this.clonedVersion = objectCachePerFile;
         this.pageNumbers = pageNumbers;
         this.objectCache = objectCache;
-        handleAnnotations = new CloneAnnotations(this);
+        if (pdfDoc.isMergeFormFieldsEnabled()) {
+            handleAnnotations = new MergeAnnotations(this, usedFields);
+        } else {
+            handleAnnotations = new CloneAnnotations(this);
+        }
     }
 
     public PDFPage getTargetPage() {
@@ -131,19 +134,19 @@ public class PDFBoxAdapter {
     }
 
     protected Object cloneForNewDocument(Object base) throws IOException {
-        return new PDFCloner(this).cloneForNewDocument(base);
+        return new PDFCloner(this, false).cloneForNewDocument(base);
     }
 
     protected Object cloneResourcesForNewDocument(Object base, Object keyBase, Collection exclude) throws IOException {
-        return new PDFCloner(this).cloneResourcesForNewDocument(base, keyBase, exclude);
+        return new PDFCloner(this, false).cloneResourcesForNewDocument(base, keyBase, exclude);
     }
 
     protected Object cloneForNewDocument(Object base, Object keyBase, Collection exclude) throws IOException {
-        return new PDFCloner(this).cloneForNewDocument(base, keyBase, exclude);
+        return new PDFCloner(this, false).cloneForNewDocument(base, keyBase, exclude);
     }
 
     protected void cacheClonedObject(Object base, Object cloned) throws IOException {
-        new PDFCloner(this).cacheClonedObject(base, cloned);
+        new PDFCloner(this, false).cacheClonedObject(base, cloned);
     }
 
     protected void transferDict(COSDictionary orgDict, PDFStream targetDict, Set filter) throws IOException {
@@ -554,8 +557,7 @@ public class PDFBoxAdapter {
             throw new IOException("Illegal PDF. Page not part of parent page node.");
         }
 
-        Set<COSObject> fields = copyAnnotations(page, srcAcroForm);
-
+        Set<?> fields = copyAnnotations(page, srcAcroForm);
         boolean formAlreadyCopied = getCachedClone(srcAcroForm) != null;
         PDFRoot catalog = this.pdfDoc.getRoot();
         PDFDictionary destAcroForm = (PDFDictionary)catalog.get(COSName.ACRO_FORM.getName());
@@ -584,13 +586,17 @@ public class PDFBoxAdapter {
             clonedFields = new PDFArray();
             destAcroForm.put(COSName.FIELDS.getName(), clonedFields);
         }
-        for (COSObject field : fields) {
-            PDFDictionary clone = (PDFDictionary) cloneForNewDocument(field, field, Arrays.asList(COSName.KIDS));
-            clonedFields.add(clone);
+        for (Object field : fields) {
+            if (field instanceof COSBase) {
+                field = cloneForNewDocument(field, field, Arrays.asList(COSName.KIDS));
+            }
+            if (!clonedFields.contains(field)) {
+                clonedFields.add(field);
+            }
         }
     }
 
-    private Set<COSObject> copyAnnotations(PDPage page, PDAcroForm srcAcroForm) throws IOException {
+    private Set<?> copyAnnotations(PDPage page, PDAcroForm srcAcroForm) throws IOException {
         COSArray annots = (COSArray) page.getCOSObject().getDictionaryObject(COSName.ANNOTS);
         if (annots != null) {
             for (COSBase annotBase : annots) {
@@ -603,8 +609,8 @@ public class PDFBoxAdapter {
                         exclude.add(COSName.PARENT);
                     }
                 }
-
-                PDFObject clonedAnnot = (PDFObject) cloneForNewDocument(annotBase, annotBase, exclude);
+                PDFObject clonedAnnot = (PDFObject)new PDFCloner(this, pdfDoc.isMergeFormFieldsEnabled())
+                        .cloneForNewDocument(annotBase, annotBase, exclude);
                 if (clonedAnnot instanceof PDFDictionary) {
                     handleAnnotations.cloneAnnotParent(annotBase, (PDFDictionary) clonedAnnot, exclude);
                     clonedAnnot.setParent(targetPage);
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java b/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java
index 99a784e..6c2d813 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxImageHandler.java
@@ -75,7 +75,7 @@ public class PDFBoxImageHandler extends AbstractPDFBoxHandler implements ImageHa
             }
             FontInfo fontinfo = (FontInfo)context.getHint("fontinfo");
             Object stream = createStreamForPDF(pdfImage, targetPage, pdfContext.getUserAgent(),
-                    pageAdjust, fontinfo, destRect, pdfContext.getPageNumbers(),
+                    pageAdjust, fontinfo, destRect, pdfContext.getUsedFieldNames(), pdfContext.getPageNumbers(),
                     pdfContext.getPdfLogicalStructureHandler(), pdfContext.getCurrentSessionStructElem());
 
             if (stream == null) {
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/PDFCloner.java b/src/java/org/apache/fop/render/pdf/pdfbox/PDFCloner.java
index c560782..b013238 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/PDFCloner.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/PDFCloner.java
@@ -52,10 +52,12 @@ import org.apache.fop.pdf.PDFObject;
 import org.apache.fop.pdf.PDFStream;
 
 public class PDFCloner {
+    private boolean trailer;
     private PDFBoxAdapter adapter;
 
-    PDFCloner(PDFBoxAdapter adapter) {
+    PDFCloner(PDFBoxAdapter adapter, boolean trailer) {
         this.adapter = adapter;
+        this.trailer = trailer;
     }
 
     protected Object cloneForNewDocument(Object base) throws IOException {
@@ -234,7 +236,11 @@ public class PDFCloner {
         }
         PDFObject pdfobj = (PDFObject) cloned;
         if (pdfobj != null && !pdfobj.hasObjectNumber() && !(base instanceof COSDictionary)) {
-            adapter.pdfDoc.registerObject(pdfobj);
+            if (trailer) {
+                adapter.pdfDoc.registerTrailerObject(pdfobj);
+            } else {
+                adapter.pdfDoc.registerObject(pdfobj);
+            }
         }
         adapter.clonedVersion.put(key, cloned);
         if (key instanceof Integer) {
diff --git a/test/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterTestCase.java b/test/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterTestCase.java
index 500889d..a00afc5 100644
--- a/test/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapterTestCase.java
@@ -121,6 +121,8 @@ public class PDFBoxAdapterTestCase {
     protected static final String Type1Subset4 = "t1subset4.pdf";
     protected static final String ROTATE = "rotate.pdf";
     protected static final String ANNOT = "annot.pdf";
+    protected static final String ANNOT2 = "annot2.pdf";
+    protected static final String ANNOT3 = "annot3.pdf";
     protected static final String SHADING = "shading.pdf";
     protected static final String LINK = "link.pdf";
     protected static final String IMAGE = "image.pdf";
@@ -144,13 +146,19 @@ public class PDFBoxAdapterTestCase {
     }
 
     protected static PDFBoxAdapter getPDFBoxAdapter(boolean mergeFonts, boolean formXObject) {
-        PDFDocument doc = new PDFDocument("");
+        return getPDFBoxAdapter(new PDFDocument(""), mergeFonts, formXObject, false, new HashMap<String, Object>());
+    }
+
+    private static PDFBoxAdapter getPDFBoxAdapter(PDFDocument doc, boolean mergeFonts, boolean formXObject,
+                                                    boolean mergeFormFields, Map<String, Object> usedFields) {
         PDFPage pdfpage = getPDFPage(doc);
         doc.setMergeFontsEnabled(mergeFonts);
         doc.setFormXObjectEnabled(formXObject);
+        doc.setMergeFormFieldsEnabled(mergeFormFields);
         pdfpage.setDocument(doc);
         pdfpage.setObjectNumber(1);
-        return new PDFBoxAdapter(pdfpage, new HashMap<>(), new HashMap<Integer, PDFArray>());
+        return new PDFBoxAdapter(pdfpage, new HashMap<>(), usedFields, new HashMap<Integer, PDFArray>(),
+                new HashMap<>());
     }
 
     public static PDDocument load(String pdf) throws IOException {
@@ -702,7 +710,7 @@ public class PDFBoxAdapterTestCase {
             pdfdoc.assignObjectNumber(pdfpage);
             pdfpage.setDocument(pdfdoc);
             PDFBoxAdapter adapter = new PDFBoxAdapter(
-                    pdfpage, objectCachePerFile, new HashMap<Integer, PDFArray>(), pdfCache);
+                    pdfpage, objectCachePerFile, null, new HashMap<Integer, PDFArray>(), pdfCache);
             PDDocument doc = load(pdf);
             PDPage page = doc.getPage(0);
             PDFArray targetPageMediaBox = new PDFArray(0d, 0d, 100d, 100d);
@@ -934,4 +942,46 @@ public class PDFBoxAdapterTestCase {
         }
         Assert.assertEquals(sb.toString(), ".notdef uni00A0 trademark uni003B uniFB00 ");
     }
+
+    private String getAnnotationsID(PDFPage page) throws IOException {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        page.getAnnotations().output(os);
+        return os.toString("UTF-8").split("\n")[1];
+    }
+
+    private PDFPage drawAnnot(PDFDocument pdfDoc, Map<String, Object> usedFields, String pdf) throws Exception {
+        PDFBoxAdapter adapter = getPDFBoxAdapter(pdfDoc, false, false, true, usedFields);
+        PDDocument input = load(pdf);
+        PDPage srcPage = input.getPage(0);
+        AffineTransform at = new AffineTransform();
+        Rectangle r = new Rectangle(0, 1650, 842000, 595000);
+        adapter.createStreamFromPDFBoxPage(input, srcPage, "key", at, new PDFArray(0d, 0d, 0d, 0d), null, r);
+        input.close();
+        return adapter.getTargetPage();
+    }
+
+    @Test
+    public void testMergeAnnotsTree() throws Exception {
+        PDFDocument pdfDoc = new PDFDocument("");
+        Map<String, Object> usedFields = new HashMap<>();
+        PDFPage page1 = drawAnnot(pdfDoc, usedFields, ANNOT2);
+        PDFPage page2 = drawAnnot(pdfDoc, usedFields, ANNOT3);
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        pdfDoc.outputHeader(os);
+        pdfDoc.output(os);
+        pdfDoc.outputTrailer(os);
+        PDDocument out = PDDocument.load(new ByteArrayInputStream(os.toByteArray()));
+        out.close();
+        String id1 = "29 0 R";
+        Assert.assertEquals(getAnnotationsID(page1), id1);
+        String id2 = "32 0 R";
+        Assert.assertEquals(getAnnotationsID(page2), id2);
+        String outStr = os.toString("UTF-8").replaceAll("\\s\\s/", "/");
+        Assert.assertTrue(outStr.contains("<< /Kids [31 0 R] /T ([Signer1) >>"));
+        Assert.assertTrue(outStr.contains("<<\n"
+                + "/Kids [" + id1 + " " + id2 + "]\n"
+                + "/Parent 33 0 R\n"
+                + "/T (Fullname1)\n"
+                + ">>"));
+    }
 }
diff --git a/test/java/org/apache/fop/render/pdf/pdfbox/PDFClonerTestCase.java b/test/java/org/apache/fop/render/pdf/pdfbox/PDFClonerTestCase.java
index cd2317e..4aa7cf4 100644
--- a/test/java/org/apache/fop/render/pdf/pdfbox/PDFClonerTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/pdfbox/PDFClonerTestCase.java
@@ -38,6 +38,7 @@ import org.apache.pdfbox.cos.COSObject;
 import org.apache.pdfbox.cos.COSStream;
 import org.apache.pdfbox.cos.COSString;
 
+import org.apache.fop.pdf.PDFArray;
 import org.apache.fop.pdf.PDFDocument;
 import org.apache.fop.pdf.PDFPage;
 import org.apache.fop.pdf.PDFResources;
@@ -67,8 +68,9 @@ public class PDFClonerTestCase {
         PDFDocument doc = new PDFDocument("");
         Rectangle2D r = new Rectangle2D.Double();
         PDFPage page = new PDFPage(new PDFResources(doc), 0, r, r, r, r);
-        PDFBoxAdapter adapter = new PDFBoxAdapter(page, new HashMap<>(), null, new HashMap<>());
-        String cloned = (String) new PDFCloner(adapter).cloneForNewDocument(string);
+        page.setDocument(doc);
+        PDFBoxAdapter adapter = new PDFBoxAdapter(page, new HashMap<>(), new HashMap<Integer, PDFArray>());
+        String cloned = (String) new PDFCloner(adapter, false).cloneForNewDocument(string);
         Assert.assertArrayEquals(cloned.getBytes(PDFDocument.ENCODING), string.getBytes());
     }
 
@@ -78,16 +80,16 @@ public class PDFClonerTestCase {
         Rectangle2D rectangle = new Rectangle2D.Double();
         PDFPage page = new PDFPage(new PDFResources(doc), 0, rectangle, rectangle, rectangle, rectangle);
         page.setDocument(doc);
-        PDFBoxAdapter adapter = new PDFBoxAdapter(page, new HashMap<>(), null, new HashMap<>());
+        PDFBoxAdapter adapter = new PDFBoxAdapter(page, new HashMap<>(), new HashMap<Integer, PDFArray>());
         COSDictionary res = new COSDictionary();
         COSDictionary child = new COSDictionary();
         child.setBoolean("a", true);
         res.setItem("a", child);
         Rectangle rect = new Rectangle(0, 0, 100, 100);
         adapter.uniqueName = new UniqueName("a", res, null, false, rect);
-        PDFStream cloneda = (PDFStream) new PDFCloner(adapter).cloneForNewDocument(getStream());
+        PDFStream cloneda = (PDFStream) new PDFCloner(adapter, false).cloneForNewDocument(getStream());
         adapter.uniqueName = new UniqueName("b", res, null, false, rect);
-        PDFStream clonedb = (PDFStream) new PDFCloner(adapter).cloneForNewDocument(getStream());
+        PDFStream clonedb = (PDFStream) new PDFCloner(adapter, false).cloneForNewDocument(getStream());
         Assert.assertNotSame(cloneda, clonedb);
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         cloneda.setDocument(doc);
diff --git a/test/resources/org/apache/fop/render/pdf/pdfbox/annot2.pdf b/test/resources/org/apache/fop/render/pdf/pdfbox/annot2.pdf
new file mode 100755
index 0000000..d9c20ec
Binary files /dev/null and b/test/resources/org/apache/fop/render/pdf/pdfbox/annot2.pdf differ
diff --git a/test/resources/org/apache/fop/render/pdf/pdfbox/annot3.pdf b/test/resources/org/apache/fop/render/pdf/pdfbox/annot3.pdf
new file mode 100755
index 0000000..0c81d9c
Binary files /dev/null and b/test/resources/org/apache/fop/render/pdf/pdfbox/annot3.pdf differ


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: commits-help@xmlgraphics.apache.org