Skip to content

Commit 0561dc4

Browse files
committed
Fix a bug in copying annotations using a GoToR action
Add test for copying a PDF with annotations DEVSIX-7411
1 parent 0d38c7b commit 0561dc4

File tree

8 files changed

+191
-1
lines changed

8 files changed

+191
-1
lines changed

kernel/src/main/java/com/itextpdf/kernel/pdf/DestinationResolverCopyFilter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ private boolean processLinkAnnotion(PdfObject newParent, PdfObject value, PdfDic
8383
});
8484
return false;
8585
}
86-
if (dict.getAsDictionary(PdfName.A) != null && dict.getAsDictionary(PdfName.A).get(PdfName.D) != null) {
86+
if (dict.getAsDictionary(PdfName.A) != null && dict.getAsDictionary(PdfName.A).get(PdfName.D) != null
87+
&& !PdfName.GoToR.equals(dict.getAsDictionary(PdfName.A).get(PdfName.S))) {
8788
fromDocument.storeDestinationToReaddress(
8889
PdfDestination.makeDestination(dict.getAsDictionary(PdfName.A).get(PdfName.D)),
8990
(PdfDestination nd) -> {
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
package com.itextpdf.kernel.pdf.annot;
2+
3+
import com.itextpdf.kernel.pdf.PdfDictionary;
4+
import com.itextpdf.kernel.pdf.PdfDocument;
5+
import com.itextpdf.kernel.pdf.PdfName;
6+
import com.itextpdf.kernel.pdf.PdfReader;
7+
import com.itextpdf.kernel.pdf.PdfWriter;
8+
import com.itextpdf.test.ExtendedITextTest;
9+
import com.itextpdf.test.annotations.type.IntegrationTest;
10+
11+
import org.junit.Assert;
12+
import org.junit.BeforeClass;
13+
import org.junit.Test;
14+
import org.junit.experimental.categories.Category;
15+
16+
import java.io.IOException;
17+
import java.util.List;
18+
19+
20+
@Category(IntegrationTest.class)
21+
public class CopyAnnotationsTest extends ExtendedITextTest {
22+
23+
public static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/kernel/pdf/annot"
24+
+ "/CopyAnnotationsTest/";
25+
public static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/kernel/pdf/annot/CopyAnnotationsTest/";
26+
27+
@BeforeClass
28+
public static void beforeClass() {
29+
createDestinationFolder(DESTINATION_FOLDER);
30+
}
31+
32+
@Test
33+
public void copyGoToRDestinationTest() throws IOException {
34+
String outFile = DESTINATION_FOLDER + "CopiedGoToRAnnotation.pdf";
35+
try (PdfDocument out = new PdfDocument(new PdfWriter(outFile))) {
36+
try (PdfDocument input = new PdfDocument(new PdfReader(SOURCE_FOLDER + "GoToRAnnotation.pdf"))) {
37+
input.copyPagesTo(1, input.getNumberOfPages(), out);
38+
}
39+
}
40+
List<PdfAnnotation> annotations = getAnnotationsFromPdf(outFile, 1);
41+
Assert.assertEquals("Destination is not copied", 1, annotations.size());
42+
}
43+
44+
@Test
45+
public void copyMultipleGoToRDestinationTest() throws IOException {
46+
String outFile = DESTINATION_FOLDER + "CopiedMultiGoToRAnnotation.pdf";
47+
try (PdfDocument out = new PdfDocument(new PdfWriter(outFile))) {
48+
try (PdfDocument input = new PdfDocument(new PdfReader(SOURCE_FOLDER + "MultiDestinations.pdf"))) {
49+
input.copyPagesTo(1, input.getNumberOfPages(), out);
50+
}
51+
}
52+
List<PdfAnnotation> annotations = getAnnotationsFromPdf(outFile, 1);
53+
Assert.assertEquals("Not all destinations are copied", 2, annotations.size());
54+
}
55+
56+
@Test
57+
public void copyGoToRWithoutTargetTest() throws IOException {
58+
String outFile = DESTINATION_FOLDER + "CopiedGoToRNoTarget.pdf";
59+
try (PdfDocument out = new PdfDocument(new PdfWriter(outFile))) {
60+
try (PdfDocument input = new PdfDocument(new PdfReader(SOURCE_FOLDER + "namedDest.pdf"))) {
61+
input.copyPagesTo(2, 6, out);
62+
}
63+
}
64+
List<PdfAnnotation> annotations = getAnnotationsFromPdf(outFile, 5);
65+
Assert.assertTrue("Destinations are copied but should not", annotations.isEmpty());
66+
}
67+
68+
@Test
69+
public void copyGoToRNamedDestinationTest() throws IOException {
70+
String outFile = DESTINATION_FOLDER + "CopiedGoToRNamedDest.pdf";
71+
try (PdfDocument out = new PdfDocument(new PdfWriter(outFile))) {
72+
try (PdfDocument input = new PdfDocument(new PdfReader(SOURCE_FOLDER + "namedDest.pdf"))) {
73+
input.copyPagesTo(1, 6, out);
74+
}
75+
}
76+
List<PdfAnnotation> annotations = getAnnotationsFromPdf(outFile, 6);
77+
Assert.assertFalse("Annotation is copied", annotations.isEmpty());
78+
String destination = (annotations.get(0)).getPdfObject().get(PdfName.Dest).toString();
79+
Assert.assertEquals("Destination is different from expected", "Destination_1", destination);
80+
}
81+
82+
@Test
83+
public void fileAttachmentTargetTest() throws IOException {
84+
String outFile = DESTINATION_FOLDER + "CopiedFileAttachmentTarget.pdf";
85+
try (PdfDocument out = new PdfDocument(new PdfWriter(outFile))) {
86+
try (PdfDocument input = new PdfDocument(new PdfReader(SOURCE_FOLDER + "fileAttachmentTargetTest.pdf"))) {
87+
input.copyPagesTo(1, input.getNumberOfPages(), out);
88+
}
89+
}
90+
List<PdfAnnotation> annotations = getAnnotationsFromPdf(outFile, 2);
91+
Assert.assertFalse("Annotation is not copied", annotations.isEmpty());
92+
String nm = annotations.get(0).getPdfObject().getAsString(PdfName.NM).toString();
93+
Assert.assertEquals("File attachment name is different from expected", "FileAttachmentAnnotation1", nm);
94+
}
95+
96+
@Test
97+
public void copyLinkWidgetTest() throws IOException {
98+
String outFile = DESTINATION_FOLDER + "CopiedLinkWidget.pdf";
99+
try (PdfDocument out = new PdfDocument(new PdfWriter(outFile))) {
100+
try (PdfDocument input = new PdfDocument(
101+
new PdfReader(SOURCE_FOLDER + "LinkWidgetExplicitDestination.pdf"))) {
102+
input.copyPagesTo(1, input.getNumberOfPages(), out);
103+
}
104+
}
105+
List<PdfAnnotation> annotations = getAnnotationsFromPdf(outFile, 1);
106+
Assert.assertFalse("Annotation is not copied", annotations.isEmpty());
107+
Assert.assertEquals("Annotation is of a different subtype", PdfName.Widget, annotations.get(0).getSubtype());
108+
}
109+
110+
@Test
111+
public void noPdfNameATest() throws IOException {
112+
String outFile = DESTINATION_FOLDER + "CopiedNoPdfNameA.pdf";
113+
try (PdfDocument out = new PdfDocument(new PdfWriter(outFile))) {
114+
try (PdfDocument input = new PdfDocument(new PdfReader(SOURCE_FOLDER + "GoToRAnnotation.pdf"))) {
115+
PdfAnnotation pdfAnnotation = input.getPage(1).getAnnotations().get(0);
116+
pdfAnnotation.getPdfObject().remove(PdfName.A);
117+
input.copyPagesTo(1, input.getNumberOfPages(), out);
118+
}
119+
}
120+
List<PdfAnnotation> annotations = getAnnotationsFromPdf(outFile, 1);
121+
Assert.assertFalse("Annotation is not copied", annotations.isEmpty());
122+
}
123+
124+
@Test
125+
public void noPdfNameDTest() throws IOException {
126+
String outFile = DESTINATION_FOLDER + "CopiedNoPdfNameD.pdf";
127+
try (PdfDocument out = new PdfDocument(new PdfWriter(outFile))) {
128+
try (PdfDocument input = new PdfDocument(new PdfReader(SOURCE_FOLDER + "GoToRAnnotation.pdf"))) {
129+
PdfAnnotation pdfAnnotation = input.getPage(1).getAnnotations().get(0);
130+
pdfAnnotation.getPdfObject().getAsDictionary(PdfName.A).remove(PdfName.D);
131+
132+
input.copyPagesTo(1, input.getNumberOfPages(), out);
133+
}
134+
}
135+
List<PdfAnnotation> annotations = getAnnotationsFromPdf(outFile, 1);
136+
Assert.assertFalse("Annotation is not copied", annotations.isEmpty());
137+
}
138+
139+
@Test
140+
public void noPdfNameSTest() throws IOException {
141+
String outFile = DESTINATION_FOLDER + "CopiedNoPdfNameS.pdf";
142+
try (PdfDocument out = new PdfDocument(new PdfWriter(outFile))) {
143+
try (PdfDocument input = new PdfDocument(new PdfReader(SOURCE_FOLDER + "GoToRAnnotation.pdf"))) {
144+
PdfAnnotation pdfAnnotation = input.getPage(1).getAnnotations().get(0);
145+
pdfAnnotation.getPdfObject().getAsDictionary(PdfName.A).remove(PdfName.S);
146+
input.copyPagesTo(1, input.getNumberOfPages(), out);
147+
}
148+
}
149+
List<PdfAnnotation> annotations = getAnnotationsFromPdf(outFile, 1);
150+
Assert.assertTrue("Annotation is copied", annotations.isEmpty());
151+
}
152+
153+
@Test
154+
public void noPdfNameDWithGoToRTest() throws IOException {
155+
String outFile = DESTINATION_FOLDER + "CopiedNoPdfNameDGoToR.pdf";
156+
try (PdfDocument out = new PdfDocument(new PdfWriter(outFile))) {
157+
try (PdfDocument input = new PdfDocument(new PdfReader(SOURCE_FOLDER + "GoToRAnnotation.pdf"))) {
158+
PdfAnnotation pdfAnnotation = input.getPage(1).getAnnotations().get(0);
159+
PdfDictionary aDictionary = pdfAnnotation.getPdfObject().getAsDictionary(PdfName.A);
160+
aDictionary.remove(PdfName.D);
161+
aDictionary.remove(PdfName.S);
162+
aDictionary.put(PdfName.S, PdfName.GoToR);
163+
input.copyPagesTo(1, input.getNumberOfPages(), out);
164+
}
165+
}
166+
List<PdfAnnotation> annotations = getAnnotationsFromPdf(outFile, 1);
167+
Assert.assertFalse("Annotation is not copied", annotations.isEmpty());
168+
}
169+
170+
@Test
171+
public void linkInsideArray() throws IOException {
172+
String outFile = DESTINATION_FOLDER + "CopiedLinkInArray.pdf";
173+
try (PdfDocument out = new PdfDocument(new PdfWriter(outFile))) {
174+
try (PdfDocument input = new PdfDocument(new PdfReader(SOURCE_FOLDER + "LinkInArray.pdf"))) {
175+
input.copyPagesTo(1, 1, out);
176+
}
177+
}
178+
List<PdfAnnotation> annotations = getAnnotationsFromPdf(outFile, 1);
179+
Assert.assertTrue("Annotation is copied", annotations.isEmpty());
180+
}
181+
182+
private List<PdfAnnotation> getAnnotationsFromPdf(String outFilePath, int pageNumber) throws IOException {
183+
List<PdfAnnotation> annotations;
184+
try (PdfDocument result = new PdfDocument(new PdfReader(outFilePath))) {
185+
annotations = result.getPage(pageNumber).getAnnotations();
186+
}
187+
return annotations;
188+
}
189+
}

0 commit comments

Comments
 (0)