diff --git a/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java b/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java index ace1b3b3a62..38d7c6ed836 100644 --- a/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java +++ b/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java @@ -369,6 +369,7 @@ public final class COSName extends COSBase implements Comparable public static final COSName LIGHTEN = getPDFName("Lighten"); public static final COSName LIMITS = getPDFName("Limits"); public static final COSName LINEARIZED = getPDFName("Linearized"); + public static final COSName LINK = getPDFName("Link"); public static final COSName LJ = getPDFName("LJ"); public static final COSName LL = getPDFName("LL"); public static final COSName LLE = getPDFName("LLE"); diff --git a/pdfbox/src/test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java b/pdfbox/src/test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java index a72e3baf807..17b93191d88 100644 --- a/pdfbox/src/test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java +++ b/pdfbox/src/test/java/org/apache/pdfbox/multipdf/PDFMergerUtilityTest.java @@ -46,12 +46,14 @@ import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureElement; import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureNode; import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot; +import org.apache.pdfbox.pdmodel.interactive.action.PDAction; import org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationPopup; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationText; import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget; +import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDNamedDestination; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageDestination; import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageFitDestination; @@ -915,10 +917,35 @@ else if (kdict.containsKey(COSName.NUMS)) { COSDictionary obj = (COSDictionary) kdict.getDictionaryObject(COSName.OBJ); COSBase type = obj.getDictionaryObject(COSName.TYPE); - if (COSName.ANNOT.equals(type)) + COSBase subtype = obj.getDictionaryObject(COSName.SUBTYPE); + if (COSName.ANNOT.equals(type) || COSName.LINK.equals(subtype)) { PDAnnotation annotation = PDAnnotation.createAnnotation(obj); PDPage page = annotation.getPage(); + if (annotation instanceof PDAnnotationLink) + { + PDAnnotationLink link = (PDAnnotationLink) annotation; + PDDestination destination = link.getDestination(); + if (destination == null) + { + PDAction action = link.getAction(); + if (action instanceof PDActionGoTo) + { + PDActionGoTo goToAction = (PDActionGoTo) action; + destination = goToAction.getDestination(); + } + } + if (destination instanceof PDPageDestination) + { + PDPageDestination pageDestination = (PDPageDestination) destination; + PDPage destPage = pageDestination.getPage(); + if (destPage != null) + { + assertNotEquals(-1, pageTree.indexOf(destPage), + "Annotation destination page is not in the page tree: " + destPage); + } + } + } if (page != null) { if (pageTree.indexOf(page) == -1) @@ -942,7 +969,7 @@ else if (kdict.containsKey(COSName.NUMS)) { //TODO needs to be investigated. Specification mentions // "such as an XObject or an annotation" - fail("Other type: " + type); + fail("Other type: " + type + ", obj: " + obj); } } }