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 2024/12/24 12:05:35 UTC
svn commit: r1922670 - in /pdfbox/branches/2.0/pdfbox/src: main/java/org/apache/pdfbox/multipdf/Splitter.java test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java
Author: tilman
Date: Tue Dec 24 12:05:35 2024
New Revision: 1922670
URL: http://svn.apache.org/viewvc?rev=1922670&view=rev
Log:
PDFBOX-5929: remove orphan annotations from the structure tree if annotations were removed from the page
Modified:
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/multipdf/Splitter.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/Splitter.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/multipdf/Splitter.java?rev=1922670&r1=1922669&r2=1922670&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/multipdf/Splitter.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/multipdf/Splitter.java Tue Dec 24 12:05:35 2024
@@ -455,6 +455,10 @@ public class Splitter
// replace annotation with clone
dstDict.setItem(COSName.OBJ, dstObj);
}
+ else
+ {
+ removePossibleOrphanAnnotation(srcObj, srcDict, currentPageDict, dstDict);
+ }
}
else
{
@@ -493,6 +497,35 @@ public class Splitter
}
return dstDict;
}
+
+ private void removePossibleOrphanAnnotation(COSDictionary srcObj, COSDictionary srcDict,
+ COSDictionary currentPageDict, COSDictionary dstDict)
+ {
+ // PDFBOX-5929: Check whether this is an "orphan" annotation that isn't in the page
+ COSBase objType = srcObj.getDictionaryObject(COSName.TYPE);
+ COSBase objSubtype = srcObj.getDictionaryObject(COSName.SUBTYPE);
+ if (COSName.ANNOT.equals(objType) || COSName.LINK.equals(objSubtype))
+ {
+ COSDictionary srcPageDict = srcDict.getCOSDictionary(COSName.PG);
+ if (srcPageDict == null)
+ {
+ // /Pg entry is not always on this level
+ srcPageDict = currentPageDict;
+ }
+ if (srcPageDict != null)
+ {
+ COSArray annotationArray = srcPageDict.getCOSArray(COSName.ANNOTS);
+ if (annotationArray == null || annotationArray.indexOfObject(srcObj) == -1)
+ {
+ // Ideally the entire OBJR entry should be removed.
+ // Removing the OBJ entry is done to avoid potential page orphans
+ // from the annotation destination.
+ LOG.warn("An annotation OBJ that isn't in the page has been removed from the structure tree");
+ dstDict.removeItem(COSName.OBJ);
+ }
+ }
+ }
+ }
}
// Look for /StructParent and /StructParents and add them to the destination tree
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=1922670&r1=1922669&r2=1922670&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 Tue Dec 24 12:05:35 2024
@@ -894,6 +894,7 @@ public class PDFMergerUtilityTest extend
PDPage page = annotation.getPage();
if (annotation instanceof PDAnnotationLink)
{
+ // PDFBOX-5928: check whether the destination of a link annotation is an orphan
PDAnnotationLink link = (PDAnnotationLink) annotation;
PDDestination destination = link.getDestination();
if (destination == null)
@@ -1085,6 +1086,33 @@ public class PDFMergerUtilityTest extend
dstDoc.close();
doc.close();
}
+
+ /**
+ * PDFBOX-5929: Check that orphan annotations are removed from the structure tree if annotations
+ * were removed from the pages (don't do that!).
+ *
+ * @throws IOException
+ */
+ public void testSplitWithStructureTreeAndDestinationsAndRemovedAnnotations() throws IOException
+ {
+ PDDocument doc = PDDocument.load(new File(SRCDIR, "PDFBOX-5762-722238.pdf"));
+ Splitter splitter = new Splitter();
+ for (PDPage page : doc.getPages())
+ {
+ page.setAnnotations(Collections.EMPTY_LIST);
+ }
+ splitter.setStartPage(1);
+ splitter.setEndPage(2);
+ splitter.setSplitAtPage(2);
+ List<PDDocument> splitResult = splitter.split(doc);
+ assertEquals(1, splitResult.size());
+ PDDocument dstDoc = splitResult.get(0);
+
+ assertEquals(2, dstDoc.getNumberOfPages());
+ checkForPageOrphans(dstDoc);
+ dstDoc.close();
+ doc.close();
+ }
/**
* Check for the bug that happened in PDFBOX-5792, where a destination was outside a target