You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2017/10/21 17:08:34 UTC
svn commit: r1812834 - in /pdfbox/branches/2.0/pdfbox/src:
main/java/org/apache/pdfbox/multipdf/PDFMergerUtility.java
test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java
Author: tilman
Date: Sat Oct 21 17:08:34 2017
New Revision: 1812834
URL: http://svn.apache.org/viewvc?rev=1812834&view=rev
Log:
PDFBOX-3972: keep local destination page index to update page reference after cloning; add test
Modified:
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/multipdf/PDFMergerUtility.java
pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/multipdf/PDFMergerUtility.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/multipdf/PDFMergerUtility.java?rev=1812834&r1=1812833&r2=1812834&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/multipdf/PDFMergerUtility.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/multipdf/PDFMergerUtility.java Sat Oct 21 17:08:34 2017
@@ -48,13 +48,17 @@ import org.apache.pdfbox.pdmodel.PDDocum
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.PageMode;
+import org.apache.pdfbox.pdmodel.common.PDDestinationOrAction;
import org.apache.pdfbox.pdmodel.common.PDMetadata;
import org.apache.pdfbox.pdmodel.common.PDNumberTreeNode;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDMarkInfo;
import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot;
import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent;
+import org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
+import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination;
+import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageDestination;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
@@ -340,8 +344,29 @@ public class PDFMergerUtility
destination.setVersion(srcVersion);
}
+ int pageIndexOpenActionDest = -1;
if (destCatalog.getOpenAction() == null)
{
+ // PDFBOX-3972: get local dest page index, it must be reassigned after the page cloning
+ PDDestinationOrAction openAction = srcCatalog.getOpenAction();
+ PDDestination openActionDestination;
+ if (openAction instanceof PDActionGoTo)
+ {
+ openActionDestination = ((PDActionGoTo) openAction).getDestination();
+ }
+ else
+ {
+ openActionDestination = (PDDestination) openAction;
+ }
+ if (openActionDestination instanceof PDPageDestination)
+ {
+ PDPage page = ((PDPageDestination) openActionDestination).getPage();
+ if (page != null)
+ {
+ pageIndexOpenActionDest = srcCatalog.getPages().indexOf(page);
+ }
+ }
+
destCatalog.setOpenAction(srcCatalog.getOpenAction());
}
@@ -556,6 +581,7 @@ public class PDFMergerUtility
}
Map<COSDictionary, COSDictionary> objMapping = new HashMap<COSDictionary, COSDictionary>();
+ int pageIndex = 0;
for (PDPage page : srcCatalog.getPages())
{
PDPage newPage = new PDPage((COSDictionary) cloner.cloneForNewDocument(page.getCOSObject()));
@@ -585,6 +611,24 @@ public class PDFMergerUtility
// TODO update mapping for XObjects
}
destination.addPage(newPage);
+
+ if (pageIndex == pageIndexOpenActionDest)
+ {
+ // PDFBOX-3972: reassign the page.
+ // The openAction is either a PDActionGoTo or a PDPageDestination
+ PDDestinationOrAction openAction = destCatalog.getOpenAction();
+ PDPageDestination pageDestination;
+ if (destCatalog.getOpenAction() instanceof PDActionGoTo)
+ {
+ pageDestination = (PDPageDestination) ((PDActionGoTo) openAction).getDestination();
+ }
+ else
+ {
+ pageDestination = (PDPageDestination) openAction;
+ }
+ pageDestination.setPage(newPage);
+ }
+ ++pageIndex;
}
if (mergeStructTree)
{
Modified: pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java?rev=1812834&r1=1812833&r2=1812834&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java Sat Oct 21 17:08:34 2017
@@ -23,6 +23,10 @@ import junit.framework.TestCase;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageDestination;
+import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageFitDestination;
import org.apache.pdfbox.rendering.PDFRenderer;
/**
@@ -111,6 +115,43 @@ public class PDFMergerUtilityTest extend
MemoryUsageSetting.setupTempFileOnly());
}
+ /**
+ * PDFBOX-3972: Test that OpenAction page destination isn't lost after merge.
+ *
+ * @throws IOException
+ */
+ public void testPDFMergerOpenAction() throws IOException
+ {
+ PDDocument doc1 = new PDDocument();
+ doc1.addPage(new PDPage());
+ doc1.addPage(new PDPage());
+ doc1.addPage(new PDPage());
+ doc1.save(new File(TARGETTESTDIR,"MergerOpenActionTest1.pdf"));
+ doc1.close();
+
+ PDDocument doc2 = new PDDocument();
+ doc2.addPage(new PDPage());
+ doc2.addPage(new PDPage());
+ doc2.addPage(new PDPage());
+ PDPageDestination dest = new PDPageFitDestination();
+ dest.setPage(doc2.getPage(1));
+ doc2.getDocumentCatalog().setOpenAction(dest);
+ doc2.save(new File(TARGETTESTDIR,"MergerOpenActionTest2.pdf"));
+ doc2.close();
+
+ PDFMergerUtility pdfMergerUtility = new PDFMergerUtility();
+ pdfMergerUtility.addSource(new File(TARGETTESTDIR, "MergerOpenActionTest1.pdf"));
+ pdfMergerUtility.addSource(new File(TARGETTESTDIR, "MergerOpenActionTest2.pdf"));
+ pdfMergerUtility.setDestinationFileName(TARGETTESTDIR + "MergerOpenActionTestResult.pdf");
+ pdfMergerUtility.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
+
+ PDDocument mergedDoc = PDDocument.load(new File(TARGETTESTDIR, "MergerOpenActionTestResult.pdf"));
+ PDDocumentCatalog documentCatalog = mergedDoc.getDocumentCatalog();
+ dest = (PDPageDestination) documentCatalog.getOpenAction();
+ assertEquals(4, documentCatalog.getPages().indexOf(dest.getPage()));
+ mergedDoc.close();
+ }
+
// checks that the result file of a merge has the same rendering as the two
// source files
private void checkMergeIdentical(String filename1, String filename2, String mergeFilename,