Add a test case for FPDFAnnot_SetBorder() to test rendering. The existing test case that exercises FPDFAnnot_SetBorder() cannot render the line annotations in its test PDF. Rather than waiting for that issue to get resolved, just leave the existing test case alone and write a second test that uses a different annotation type which is known to have support for borders. Add a new square annotation to annots.pdf, and use that in a new test case to make sure FPDFAnnot_SetBorder() calls reflect in the rendered in-memory PDF and in the saved PDF. With only the new test by itself, it fails, which shows FPDFAnnot_SetBorder() does not work properly. To make the test pass, change FPDFAnnot_SetBorder() to remove appearance streams. Change-Id: I0f34832c545f8d29350542bb57ab1de5f14b39f4 Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/79533 Reviewed-by: Daniel Hosseinian <dhoss@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp index 8545459..d68983c 100644 --- a/fpdfsdk/fpdf_annot.cpp +++ b/fpdfsdk/fpdf_annot.cpp
@@ -933,6 +933,10 @@ if (!annot_dict) return false; + // Remove the appearance stream. Otherwise PDF viewers will render that and + // not use the border values. + annot_dict->RemoveFor(pdfium::annotation::kAP); + CPDF_Array* border = annot_dict->SetNewFor<CPDF_Array>(pdfium::annotation::kBorder); border->AppendNew<CPDF_Number>(horizontal_radius);
diff --git a/fpdfsdk/fpdf_annot_embeddertest.cpp b/fpdfsdk/fpdf_annot_embeddertest.cpp index c5fef24..987605c 100644 --- a/fpdfsdk/fpdf_annot_embeddertest.cpp +++ b/fpdfsdk/fpdf_annot_embeddertest.cpp
@@ -3565,3 +3565,59 @@ UnloadPage(page); } + +// Due to https://crbug.com/pdfium/570, the AnnotationBorder test above cannot +// actually render the line annotations inside line_annot.pdf. For now, use a +// square annotation in annots.pdf for testing. +TEST_F(FPDFAnnotEmbedderTest, AnnotationBorderRendering) { + ASSERT_TRUE(OpenDocument("annots.pdf")); + FPDF_PAGE page = LoadPage(1); + ASSERT_TRUE(page); + EXPECT_EQ(3, FPDFPage_GetAnnotCount(page)); + +#if defined(_SKIA_SUPPORT_) || defined(_SKIA_SUPPORT_PATHS_) + constexpr char kOriginalChecksum[] = "bc9ba381d6d46ff93ed0b5288b763b60"; + constexpr char kModifiedChecksum[] = "0f3e10336f67cb6a8731a06d26d01e50"; +#elif defined(OS_WIN) + constexpr char kOriginalChecksum[] = "f9fcab6ac610ee2347c4eba6be86a90c"; + constexpr char kModifiedChecksum[] = "e0e9ad5b67ef84288d446861265898b3"; +#elif defined(OS_APPLE) + constexpr char kOriginalChecksum[] = "1839f5df5fb4fae10cf3793568e73ede"; + constexpr char kModifiedChecksum[] = "abd4f5d1c3b8d8cfc572b389e589da5a"; +#else + constexpr char kOriginalChecksum[] = "ccf6667b34ec2452bea0b5f1a0194191"; + constexpr char kModifiedChecksum[] = "1bbdb473d0757843e82053b0bd3298bc"; +#endif + + { + ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 2)); + ASSERT_TRUE(annot); + EXPECT_EQ(FPDF_ANNOT_SQUARE, FPDFAnnot_GetSubtype(annot.get())); + + { + ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT); + CompareBitmap(bitmap.get(), 612, 792, kOriginalChecksum); + } + + EXPECT_TRUE(FPDFAnnot_SetBorder(annot.get(), /*horizontal_radius=*/2.0f, + /*vertical_radius=*/3.5f, + /*border_width=*/4.0f)); + + { + ScopedFPDFBitmap bitmap = RenderLoadedPageWithFlags(page, FPDF_ANNOT); + CompareBitmap(bitmap.get(), 612, 792, kModifiedChecksum); + } + } + + // Save the document and close the page. + EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0)); + UnloadPage(page); + + ASSERT_TRUE(OpenSavedDocument()); + page = LoadSavedPage(1); + ASSERT_TRUE(page); + VerifySavedRendering(page, 612, 792, kModifiedChecksum); + + CloseSavedPage(page); + CloseSavedDocument(); +}
diff --git a/public/fpdf_annot.h b/public/fpdf_annot.h index 04e411a..149fbf1 100644 --- a/public/fpdf_annot.h +++ b/public/fpdf_annot.h
@@ -471,7 +471,10 @@ // vertical_radius - vertical corner radius, in default user space units // border_width - border width, in default user space units // -// Returns true if |annot| is valid, false otherwise. +// Returns true if setting the border for |annot| succeeds, false otherwise. +// +// If |annot| contains an appearance stream that overrides the border values, +// then the appearance stream will be removed on success. FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetBorder(FPDF_ANNOTATION annot, float horizontal_radius, float vertical_radius,
diff --git a/testing/resources/annots.in b/testing/resources/annots.in index c68bd78..cf575f5 100644 --- a/testing/resources/annots.in +++ b/testing/resources/annots.in
@@ -41,7 +41,7 @@ /Type /Page /Parent 2 0 R /Contents 6 0 R - /Annots [15 0 R 16 0 R] + /Annots [15 0 R 16 0 R 26 0 R] >> endobj {{object 5 0}} << @@ -346,6 +346,16 @@ /BM /Multiply >> endobj +{{object 26 0}} << + /Type /Annot + /Subtype /Square + /Border [0 0 2] + /C [1 0 0] + /F 4 + /P 3 0 R + /Rect [50 100 60 120] +>> +endobj {{xref}} {{trailer}} {{startxref}}
diff --git a/testing/resources/annots.pdf b/testing/resources/annots.pdf index b514c7d..745346c 100644 --- a/testing/resources/annots.pdf +++ b/testing/resources/annots.pdf
@@ -42,7 +42,7 @@ /Type /Page /Parent 2 0 R /Contents 6 0 R - /Annots [15 0 R 16 0 R] + /Annots [15 0 R 16 0 R 26 0 R] >> endobj 5 0 obj << @@ -347,38 +347,49 @@ /BM /Multiply >> endobj +26 0 obj << + /Type /Annot + /Subtype /Square + /Border [0 0 2] + /C [1 0 0] + /F 4 + /P 3 0 R + /Rect [50 100 60 120] +>> +endobj xref -0 26 +0 27 0000000000 65535 f 0000000015 00000 n 0000000169 00000 n 0000000439 00000 n 0000000583 00000 n -0000000678 00000 n -0000001216 00000 n -0000001453 00000 n -0000001531 00000 n -0000001607 00000 n -0000001857 00000 n -0000002080 00000 n -0000002330 00000 n -0000002550 00000 n -0000002801 00000 n -0000003024 00000 n -0000003164 00000 n -0000003304 00000 n -0000003551 00000 n -0000003835 00000 n -0000004052 00000 n -0000004279 00000 n -0000004377 00000 n -0000004652 00000 n -0000004842 00000 n -0000004913 00000 n +0000000685 00000 n +0000001223 00000 n +0000001460 00000 n +0000001538 00000 n +0000001614 00000 n +0000001864 00000 n +0000002087 00000 n +0000002337 00000 n +0000002557 00000 n +0000002808 00000 n +0000003031 00000 n +0000003171 00000 n +0000003311 00000 n +0000003558 00000 n +0000003842 00000 n +0000004059 00000 n +0000004286 00000 n +0000004384 00000 n +0000004659 00000 n +0000004849 00000 n +0000004920 00000 n +0000005006 00000 n trailer << /Root 1 0 R - /Size 26 + /Size 27 >> startxref -4999 +5135 %%EOF