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