Add tests for FPDFLink_Enumerate() and friends
1. Validate that FPDFLink_Enumerate() is consistent with links as found
through enumerating all annotations with Subtype set to Link
2. Tests for FPDFLink_GetAnnotRect() and FPDFLink_CountQuadPoints()
Bug: pdfium:1243
Change-Id: I00d0023690a67485fc80c04246c7face8ff68bf4
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/56710
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_text_embeddertest.cpp b/fpdfsdk/fpdf_text_embeddertest.cpp
index 12b09a7..d0e63ac 100644
--- a/fpdfsdk/fpdf_text_embeddertest.cpp
+++ b/fpdfsdk/fpdf_text_embeddertest.cpp
@@ -533,7 +533,8 @@
"http://example.com/test-foo", // from "http://example.com/test-\r\nfoo"
"http://abc.com/test-foo", // from "http://abc.com/test-\r\n\r\nfoo"
// Next two links from "http://www.example.com/\r\nhttp://www.abc.com/"
- "http://example.com/", "http://www.abc.com",
+ "http://example.com/",
+ "http://www.abc.com",
};
static const int kNumLinks = static_cast<int>(FX_ArraySize(kExpectedUrls));
@@ -630,6 +631,71 @@
UnloadPage(page);
}
+TEST_F(FPDFTextEmbedderTest, AnnotLinks) {
+ ASSERT_TRUE(OpenDocument("link_annots.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ // Get link count via checking annotation subtype
+ int annot_count = FPDFPage_GetAnnotCount(page);
+ ASSERT_EQ(8, annot_count);
+ int annot_subtype_link_count = 0;
+ for (int i = 0; i < annot_count; ++i) {
+ ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, i));
+ if (FPDFAnnot_GetSubtype(annot.get()) == FPDF_ANNOT_LINK) {
+ ++annot_subtype_link_count;
+ }
+ }
+ EXPECT_EQ(4, annot_subtype_link_count);
+
+ // Validate that FPDFLink_Enumerate() returns same number of links
+ int start_pos = 0;
+ FPDF_LINK link_annot;
+ int link_count = 0;
+ while (FPDFLink_Enumerate(page, &start_pos, &link_annot)) {
+ ASSERT_TRUE(link_annot);
+ if (start_pos == 1 || start_pos == 2) {
+ // First two links point to first and second page within the document
+ // respectively
+ FPDF_DEST link_dest = FPDFLink_GetDest(document(), link_annot);
+ EXPECT_TRUE(link_dest);
+ EXPECT_EQ(start_pos - 1,
+ FPDFDest_GetDestPageIndex(document(), link_dest));
+ } else if (start_pos == 3) { // points to PDF Spec URL
+ FS_RECTF link_rect;
+ EXPECT_TRUE(FPDFLink_GetAnnotRect(link_annot, &link_rect));
+ EXPECT_NEAR(66.0, link_rect.left, 0.001);
+ EXPECT_NEAR(544.0, link_rect.top, 0.001);
+ EXPECT_NEAR(196.0, link_rect.right, 0.001);
+ EXPECT_NEAR(529.0, link_rect.bottom, 0.001);
+ } else if (start_pos == 4) { // this link has quad points
+ int quad_point_count = FPDFLink_CountQuadPoints(link_annot);
+ EXPECT_EQ(1, quad_point_count);
+ FS_QUADPOINTSF quad_points;
+ EXPECT_TRUE(FPDFLink_GetQuadPoints(link_annot, 0, &quad_points));
+ EXPECT_NEAR(83.0, quad_points.x1, 0.001);
+ EXPECT_NEAR(453.0, quad_points.y1, 0.001);
+ EXPECT_NEAR(178.0, quad_points.x2, 0.001);
+ EXPECT_NEAR(453.0, quad_points.y2, 0.001);
+ EXPECT_NEAR(83.0, quad_points.x3, 0.001);
+ EXPECT_NEAR(440.0, quad_points.y3, 0.001);
+ EXPECT_NEAR(178.0, quad_points.x4, 0.001);
+ EXPECT_NEAR(440.0, quad_points.y4, 0.001);
+ // AnnotRect is same as quad points for this link
+ FS_RECTF link_rect;
+ EXPECT_TRUE(FPDFLink_GetAnnotRect(link_annot, &link_rect));
+ EXPECT_NEAR(link_rect.left, quad_points.x1, 0.001);
+ EXPECT_NEAR(link_rect.top, quad_points.y1, 0.001);
+ EXPECT_NEAR(link_rect.right, quad_points.x4, 0.001);
+ EXPECT_NEAR(link_rect.bottom, quad_points.y4, 0.001);
+ }
+ ++link_count;
+ }
+ EXPECT_EQ(annot_subtype_link_count, link_count);
+
+ UnloadPage(page);
+}
+
TEST_F(FPDFTextEmbedderTest, GetFontSize) {
ASSERT_TRUE(OpenDocument("hello_world.pdf"));
FPDF_PAGE page = LoadPage(0);
@@ -1037,7 +1103,9 @@
{60.0f, 150.0f, 150.0f, 60.0f},
};
static constexpr const char* kExpectedText[kPageCount] = {
- " world!\r\ndbye, world!", " world!\r\ndbye, world!", "bye, world!",
+ " world!\r\ndbye, world!",
+ " world!\r\ndbye, world!",
+ "bye, world!",
"bye, world!",
};
diff --git a/testing/resources/link_annots.in b/testing/resources/link_annots.in
new file mode 100644
index 0000000..c80b32b
--- /dev/null
+++ b/testing/resources/link_annots.in
@@ -0,0 +1,333 @@
+{{header}}
+{{object 1 0}} <<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+ /Type /Pages
+ /Count 2
+ /Kids [3 0 R 4 0 R]
+ /MediaBox [0 0 612 792]
+ /CropBox [0 0 612 792]
+ /Resources <<
+ /Font <<
+ /F1 7 0 R
+ /F2 8 0 R
+ >>
+ /ProcSet [/PDF /Text /ImageC]
+ /ExtGState <<
+ /GS0 23 0 R
+ >>
+ >>
+>>
+endobj
+{{object 3 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /Contents 5 0 R
+ /Annots [15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R]
+>>
+endobj
+{{object 4 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /Contents 6 0 R
+ /Annots [15 0 R 16 0 R]
+>>
+endobj
+{{object 5 0}} <<
+ {{streamlen}}
+>>
+stream
+BT
+70 700 Td
+/F1 18 Tf
+(Link Annotations - Page 1) Tj
+0 -65 Td
+/F2 14 Tf
+(1. Link with destination to first page) Tj
+10 -20 Td
+/F2 14 Tf
+(2. Link with destination to second page) Tj
+-12 -84 Td
+/F2 10 Tf
+(PDF Reference, Version 1.7, Section 8.4.5 defines Annotations) Tj
+2 -53 Td
+(3. An example of Highlight with text notes) Tj
+0 -18 Td
+(https://pdfium.googlesource.com/pdfium is link in plain text, not link annotation. These are referred to) Tj
+0 -17 Td
+(as WebLinks in PDFium.)Tj
+ET
+endstream
+endobj
+{{object 6 0}} <<
+ {{streamlen}}
+>>
+stream
+BT
+70 700 Td
+/F1 18 Tf
+(Link Annotations - Page 2) Tj
+0 -65 Td
+/F2 14 Tf
+(1. Link with destination to first page) Tj
+10 -20 Td
+/F2 14 Tf
+(2. Link with destination to second page) Tj
+ET
+endstream
+endobj
+{{object 7 0}} <<
+ /Type /Font
+ /Subtype /Type1
+ /BaseFont /Times-Roman
+>>
+endobj
+{{object 8 0}} <<
+ /Type /Font
+ /Subtype /Type1
+ /BaseFont /Helvetica
+>>
+endobj
+{{object 9 0}} <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ {{streamlen}}
+ /BBox [293 530 349 542]
+ /Resources <<
+ /XObject <<
+ /Form0 10 0 R
+ >>
+ /ExtGState <<
+ /GS0 24 0 R
+ >>
+ >>
+>>
+stream
+/GS0 gs
+/Form0 Do
+endstream
+endobj
+{{object 10 0}} <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ /Group <<
+ /S /Transparency
+ >>
+ {{streamlen}}
+ /BBox [293 530 349 542]
+>>
+stream
+1.0 1.0 0.0 rg
+293 530 m
+349 530 l
+349 542 l
+293 542 l
+h f
+endstream
+endobj
+{{object 11 0}} <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ {{streamlen}}
+ /BBox [83 440 178 453]
+ /Resources <<
+ /XObject <<
+ /Form0 12 0 R
+ >>
+ /ExtGState <<
+ /GS0 24 0 R
+ >>
+ >>
+>>
+stream
+/GS0 gs
+/Form0 Do
+endstream
+endobj
+{{object 12 0}} <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ /Group <<
+ /S /Transparency
+ >>
+ {{streamlen}}
+ /BBox [83 440 178 453]
+>>
+stream
+0.0 1.0 1.0 rg
+83 440 m
+178 440 l
+178 453 l
+83 453 l
+h f
+endstream
+endobj
+{{object 13 0}} <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ {{streamlen}}
+ /BBox [149 476 191 487]
+ /Resources <<
+ /XObject <<
+ /Form0 14 0 R
+ >>
+ /ExtGState <<
+ /GS0 24 0 R
+ >>
+ >>
+>>
+stream
+/GS0 gs
+/Form0 Do
+endstream
+endobj
+{{object 14 0}} <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ /Group <<
+ /S /Transparency
+ >>
+ {{streamlen}}
+ /BBox [149 476 191 487]
+>>
+stream
+0.0 1.0 0.0 rg
+149 476 m
+191 476 l
+191 487 l
+149 487 l
+h f
+endstream
+endobj
+{{object 15 0}} <<
+ /Type /Annot
+ /Subtype /Link
+ /BS <<
+ /W 0
+ >>
+ /Rect [69 633 542 653]
+ /Dest [3 0 R /XYZ 200 725 0]
+ /F 4
+>>
+endobj
+{{object 16 0}} <<
+ /Type /Annot
+ /Subtype /Link
+ /BS <<
+ /W 0
+ >>
+ /Rect [80 613 542 633]
+ /Dest [4 0 R /XYZ 200 725 0]
+ /F 4
+>>
+endobj
+{{object 17 0}} <<
+ /Type /Annot
+ /Subtype /Link
+ /BS <<
+ /W 0
+ >>
+ /Rect [66 529 196 544]
+ /A <<
+ /Type /Action
+ /URI (https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf)
+ /S /URI
+ >>
+ /F 4
+>>
+endobj
+{{object 18 0}} <<
+ /Type /Annot
+ /Subtype /Link
+ /BS <<
+ /W 0
+ >>
+ /Rect [83 440 178 453]
+ /QuadPoints [83 453 178 453 83 440 178 440]
+ /A <<
+ /Type /Action
+ /URI (https://cs.chromium.org/chromium/src/third_party/pdfium/public/fpdf_text.h)
+ /S /URI
+ >>
+ /F 4
+>>
+endobj
+{{object 19 0}} <<
+ /Type /Annot
+ /Subtype /Highlight
+ /AP <<
+ /N 9 0 R
+ >>
+ /NM (Highlight-1)
+ /F 4
+ /QuadPoints [293 542 349 542 293 530 349 530]
+ /P 3 0 R
+ /C [1 0.90196 0]
+ /Rect [293 530 349 542]
+>>
+endobj
+{{object 20 0}} <<
+ /Type /Annot
+ /Subtype /Highlight
+ /AP <<
+ /N 11 0 R
+ >>
+ /NM (Highlight-2)
+ /F 4
+ /QuadPoints [83 453 178 453 83 440 178 440]
+ /P 3 0 R
+ /C [0.26667 0.78431 0.96078]
+ /Rect [83 440 178 453]
+>>
+endobj
+{{object 21 0}} <<
+ /Type /Annot
+ /Subtype /Popup
+ /Parent 22 0 R
+ /Rect [191 377 443 488]
+>>
+endobj
+{{object 22 0}} <<
+ /Type /Annot
+ /Subtype /Highlight
+ /Popup 21 0 R
+ /AP <<
+ /N 13 0 R
+ >>
+ /NM (Highlight-With-Popup-1)
+ /Contents (Text Note)
+ /QuadPoints [149 487 191 487 149 476 191 476]
+ /P 3 0 R
+ /C [0.14902 0.90196 0]
+ /Rect [149 476 191 487]
+ /F 4
+>>
+endobj
+{{object 23 0}} <<
+ /ca 1
+ /Type /ExtGState
+ /CA 1
+ /BM /Normal
+>>
+endobj
+{{object 24 0}} <<
+ /ca 1
+ /Type /ExtGState
+ /CA 1
+ /AIS false
+ /BM /Multiply
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/link_annots.pdf b/testing/resources/link_annots.pdf
new file mode 100644
index 0000000..f7e3802
--- /dev/null
+++ b/testing/resources/link_annots.pdf
@@ -0,0 +1,364 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+ /Type /Pages
+ /Count 2
+ /Kids [3 0 R 4 0 R]
+ /MediaBox [0 0 612 792]
+ /CropBox [0 0 612 792]
+ /Resources <<
+ /Font <<
+ /F1 7 0 R
+ /F2 8 0 R
+ >>
+ /ProcSet [/PDF /Text /ImageC]
+ /ExtGState <<
+ /GS0 23 0 R
+ >>
+ >>
+>>
+endobj
+3 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /Contents 5 0 R
+ /Annots [15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R]
+>>
+endobj
+4 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /Contents 6 0 R
+ /Annots [15 0 R 16 0 R]
+>>
+endobj
+5 0 obj <<
+ /Length 486
+>>
+stream
+BT
+70 700 Td
+/F1 18 Tf
+(Link Annotations - Page 1) Tj
+0 -65 Td
+/F2 14 Tf
+(1. Link with destination to first page) Tj
+10 -20 Td
+/F2 14 Tf
+(2. Link with destination to second page) Tj
+-12 -84 Td
+/F2 10 Tf
+(PDF Reference, Version 1.7, Section 8.4.5 defines Annotations) Tj
+2 -53 Td
+(3. An example of Highlight with text notes) Tj
+0 -18 Td
+(https://pdfium.googlesource.com/pdfium is link in plain text, not link annotation. These are referred to) Tj
+0 -17 Td
+(as WebLinks in PDFium.)Tj
+ET
+endstream
+endobj
+6 0 obj <<
+ /Length 185
+>>
+stream
+BT
+70 700 Td
+/F1 18 Tf
+(Link Annotations - Page 2) Tj
+0 -65 Td
+/F2 14 Tf
+(1. Link with destination to first page) Tj
+10 -20 Td
+/F2 14 Tf
+(2. Link with destination to second page) Tj
+ET
+endstream
+endobj
+7 0 obj <<
+ /Type /Font
+ /Subtype /Type1
+ /BaseFont /Times-Roman
+>>
+endobj
+8 0 obj <<
+ /Type /Font
+ /Subtype /Type1
+ /BaseFont /Helvetica
+>>
+endobj
+9 0 obj <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ /Length 20
+ /BBox [293 530 349 542]
+ /Resources <<
+ /XObject <<
+ /Form0 10 0 R
+ >>
+ /ExtGState <<
+ /GS0 24 0 R
+ >>
+ >>
+>>
+stream
+/GS0 gs
+/Form0 Do
+endstream
+endobj
+10 0 obj <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ /Group <<
+ /S /Transparency
+ >>
+ /Length 64
+ /BBox [293 530 349 542]
+>>
+stream
+1.0 1.0 0.0 rg
+293 530 m
+349 530 l
+349 542 l
+293 542 l
+h f
+endstream
+endobj
+11 0 obj <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ /Length 20
+ /BBox [83 440 178 453]
+ /Resources <<
+ /XObject <<
+ /Form0 12 0 R
+ >>
+ /ExtGState <<
+ /GS0 24 0 R
+ >>
+ >>
+>>
+stream
+/GS0 gs
+/Form0 Do
+endstream
+endobj
+12 0 obj <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ /Group <<
+ /S /Transparency
+ >>
+ /Length 62
+ /BBox [83 440 178 453]
+>>
+stream
+0.0 1.0 1.0 rg
+83 440 m
+178 440 l
+178 453 l
+83 453 l
+h f
+endstream
+endobj
+13 0 obj <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ /Length 20
+ /BBox [149 476 191 487]
+ /Resources <<
+ /XObject <<
+ /Form0 14 0 R
+ >>
+ /ExtGState <<
+ /GS0 24 0 R
+ >>
+ >>
+>>
+stream
+/GS0 gs
+/Form0 Do
+endstream
+endobj
+14 0 obj <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ /Group <<
+ /S /Transparency
+ >>
+ /Length 65
+ /BBox [149 476 191 487]
+>>
+stream
+0.0 1.0 0.0 rg
+149 476 m
+191 476 l
+191 487 l
+149 487 l
+h f
+endstream
+endobj
+15 0 obj <<
+ /Type /Annot
+ /Subtype /Link
+ /BS <<
+ /W 0
+ >>
+ /Rect [69 633 542 653]
+ /Dest [3 0 R /XYZ 200 725 0]
+ /F 4
+>>
+endobj
+16 0 obj <<
+ /Type /Annot
+ /Subtype /Link
+ /BS <<
+ /W 0
+ >>
+ /Rect [80 613 542 633]
+ /Dest [4 0 R /XYZ 200 725 0]
+ /F 4
+>>
+endobj
+17 0 obj <<
+ /Type /Annot
+ /Subtype /Link
+ /BS <<
+ /W 0
+ >>
+ /Rect [66 529 196 544]
+ /A <<
+ /Type /Action
+ /URI (https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf)
+ /S /URI
+ >>
+ /F 4
+>>
+endobj
+18 0 obj <<
+ /Type /Annot
+ /Subtype /Link
+ /BS <<
+ /W 0
+ >>
+ /Rect [83 440 178 453]
+ /QuadPoints [83 453 178 453 83 440 178 440]
+ /A <<
+ /Type /Action
+ /URI (https://cs.chromium.org/chromium/src/third_party/pdfium/public/fpdf_text.h)
+ /S /URI
+ >>
+ /F 4
+>>
+endobj
+19 0 obj <<
+ /Type /Annot
+ /Subtype /Highlight
+ /AP <<
+ /N 9 0 R
+ >>
+ /NM (Highlight-1)
+ /F 4
+ /QuadPoints [293 542 349 542 293 530 349 530]
+ /P 3 0 R
+ /C [1 0.90196 0]
+ /Rect [293 530 349 542]
+>>
+endobj
+20 0 obj <<
+ /Type /Annot
+ /Subtype /Highlight
+ /AP <<
+ /N 11 0 R
+ >>
+ /NM (Highlight-2)
+ /F 4
+ /QuadPoints [83 453 178 453 83 440 178 440]
+ /P 3 0 R
+ /C [0.26667 0.78431 0.96078]
+ /Rect [83 440 178 453]
+>>
+endobj
+21 0 obj <<
+ /Type /Annot
+ /Subtype /Popup
+ /Parent 22 0 R
+ /Rect [191 377 443 488]
+>>
+endobj
+22 0 obj <<
+ /Type /Annot
+ /Subtype /Highlight
+ /Popup 21 0 R
+ /AP <<
+ /N 13 0 R
+ >>
+ /NM (Highlight-With-Popup-1)
+ /Contents (Text Note)
+ /QuadPoints [149 487 191 487 149 476 191 476]
+ /P 3 0 R
+ /C [0.14902 0.90196 0]
+ /Rect [149 476 191 487]
+ /F 4
+>>
+endobj
+23 0 obj <<
+ /ca 1
+ /Type /ExtGState
+ /CA 1
+ /BM /Normal
+>>
+endobj
+24 0 obj <<
+ /ca 1
+ /Type /ExtGState
+ /CA 1
+ /AIS false
+ /BM /Multiply
+>>
+endobj
+xref
+0 25
+0000000000 65535 f
+0000000015 00000 n
+0000000068 00000 n
+0000000340 00000 n
+0000000477 00000 n
+0000000572 00000 n
+0000001110 00000 n
+0000001347 00000 n
+0000001425 00000 n
+0000001501 00000 n
+0000001761 00000 n
+0000001993 00000 n
+0000002253 00000 n
+0000002482 00000 n
+0000002743 00000 n
+0000002976 00000 n
+0000003122 00000 n
+0000003267 00000 n
+0000003519 00000 n
+0000003811 00000 n
+0000004038 00000 n
+0000004275 00000 n
+0000004377 00000 n
+0000004664 00000 n
+0000004739 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 25
+>>
+startxref
+4825
+%%EOF