From 8ce58f522e046ae3b1561d592ca7b3cd7c894731 Mon Sep 17 00:00:00 2001 From: Jane Liu Date: Thu, 29 Jun 2017 13:40:22 -0400 Subject: Added FPDFAnnot_RemoveAnnot() Added an API for removing annotation and an embedder test for it. Bug=pdfium:737 Change-Id: I6f01625e8103078b83967a57a5c1a7a26bc0c70a Reviewed-on: https://pdfium-review.googlesource.com/7039 Commit-Queue: Jane Liu Reviewed-by: Lei Zhang --- fpdfsdk/fpdfannot.cpp | 13 +++++++ fpdfsdk/fpdfannot_embeddertest.cpp | 69 ++++++++++++++++++++++++++++++++++++++ fpdfsdk/fpdfview_c_api_test.c | 1 + public/fpdf_annot.h | 20 +++++++---- 4 files changed, 97 insertions(+), 6 deletions(-) diff --git a/fpdfsdk/fpdfannot.cpp b/fpdfsdk/fpdfannot.cpp index 4a288b7df7..3d003d738e 100644 --- a/fpdfsdk/fpdfannot.cpp +++ b/fpdfsdk/fpdfannot.cpp @@ -201,6 +201,19 @@ DLLEXPORT void STDCALL FPDFPage_CloseAnnot(FPDF_ANNOTATION annot) { delete CPDFAnnotContextFromFPDFAnnotation(annot); } +DLLEXPORT FPDF_BOOL STDCALL FPDFPage_RemoveAnnot(FPDF_PAGE page, int index) { + CPDF_Page* pPage = CPDFPageFromFPDFPage(page); + if (!pPage || !pPage->m_pFormDict || index < 0) + return false; + + CPDF_Array* pAnnots = pPage->m_pFormDict->GetArrayFor("Annots"); + if (!pAnnots || static_cast(index) >= pAnnots->GetCount()) + return false; + + pAnnots->RemoveAt(index); + return true; +} + DLLEXPORT FPDF_ANNOTATION_SUBTYPE STDCALL FPDFAnnot_GetSubtype(FPDF_ANNOTATION annot) { if (!annot) diff --git a/fpdfsdk/fpdfannot_embeddertest.cpp b/fpdfsdk/fpdfannot_embeddertest.cpp index 9d9e2d365f..85fe1326bc 100644 --- a/fpdfsdk/fpdfannot_embeddertest.cpp +++ b/fpdfsdk/fpdfannot_embeddertest.cpp @@ -392,3 +392,72 @@ TEST_F(FPDFAnnotEmbeddertest, ModifyRectQuadpointsWithAP) { FPDFPage_CloseAnnot(annot); UnloadPage(page); } + +TEST_F(FPDFAnnotEmbeddertest, RemoveAnnotation) { + // Open a file with 3 annotations on its first page. + ASSERT_TRUE(OpenDocument("annotation_ink_multiple.pdf")); + FPDF_PAGE page = FPDF_LoadPage(document(), 0); + ASSERT_TRUE(page); + EXPECT_EQ(3, FPDFPage_GetAnnotCount(page)); + + // Check that the annotations have the expected rectangle coordinates. + FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0); + FS_RECTF rect = FPDFAnnot_GetRect(annot); + EXPECT_NEAR(86.1971f, rect.left, 0.001f); + FPDFPage_CloseAnnot(annot); + + annot = FPDFPage_GetAnnot(page, 1); + rect = FPDFAnnot_GetRect(annot); + EXPECT_NEAR(149.8127f, rect.left, 0.001f); + FPDFPage_CloseAnnot(annot); + + annot = FPDFPage_GetAnnot(page, 2); + rect = FPDFAnnot_GetRect(annot); + EXPECT_NEAR(351.8204f, rect.left, 0.001f); + FPDFPage_CloseAnnot(annot); + + // Check that nothing happens when attempting to remove an annotation with an + // out-of-bound index. + EXPECT_FALSE(FPDFPage_RemoveAnnot(page, 4)); + EXPECT_FALSE(FPDFPage_RemoveAnnot(page, -1)); + EXPECT_EQ(3, FPDFPage_GetAnnotCount(page)); + + // Remove the second annotation. + EXPECT_TRUE(FPDFPage_RemoveAnnot(page, 1)); + EXPECT_EQ(2, FPDFPage_GetAnnotCount(page)); + EXPECT_FALSE(FPDFPage_GetAnnot(page, 2)); + + // Save the document, closing the page and document. + EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0)); + FPDF_ClosePage(page); + + // Open the saved document. + std::string new_file = GetString(); + FPDF_FILEACCESS file_access; + memset(&file_access, 0, sizeof(file_access)); + file_access.m_FileLen = new_file.size(); + file_access.m_GetBlock = GetBlockFromString; + file_access.m_Param = &new_file; + FPDF_DOCUMENT new_doc = FPDF_LoadCustomDocument(&file_access, nullptr); + ASSERT_TRUE(new_doc); + FPDF_PAGE new_page = FPDF_LoadPage(new_doc, 0); + ASSERT_TRUE(new_page); + + // Check that the saved document has 2 annotations on the first page. + EXPECT_EQ(2, FPDFPage_GetAnnotCount(new_page)); + + // Check that the remaining 2 annotations are the original 1st and 3rd ones by + // verifying their rectangle coordinates. + annot = FPDFPage_GetAnnot(new_page, 0); + rect = FPDFAnnot_GetRect(annot); + EXPECT_NEAR(86.1971f, rect.left, 0.001f); + FPDFPage_CloseAnnot(annot); + + annot = FPDFPage_GetAnnot(new_page, 1); + rect = FPDFAnnot_GetRect(annot); + EXPECT_NEAR(351.8204f, rect.left, 0.001f); + FPDFPage_CloseAnnot(annot); + + FPDF_ClosePage(new_page); + FPDF_CloseDocument(new_doc); +} diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c index 05242c6fe1..f9a3c387c2 100644 --- a/fpdfsdk/fpdfview_c_api_test.c +++ b/fpdfsdk/fpdfview_c_api_test.c @@ -40,6 +40,7 @@ int CheckPDFiumCApi() { CHK(FPDFPage_GetAnnotCount); CHK(FPDFPage_GetAnnot); CHK(FPDFPage_CloseAnnot); + CHK(FPDFPage_RemoveAnnot); CHK(FPDFAnnot_GetSubtype); CHK(FPDFAnnot_SetColor); CHK(FPDFAnnot_GetColor); diff --git a/public/fpdf_annot.h b/public/fpdf_annot.h index d997927f64..9e349bdd5e 100644 --- a/public/fpdf_annot.h +++ b/public/fpdf_annot.h @@ -62,7 +62,7 @@ typedef enum FPDFANNOT_TEXTTYPE { // // subtype - the subtype to be checked. // -// Returns true if this subtype supported, false otherwise. +// Returns true if this subtype supported. DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_IsSupportedSubtype(FPDF_ANNOTATION_SUBTYPE subtype); @@ -98,6 +98,14 @@ DLLEXPORT FPDF_ANNOTATION STDCALL FPDFPage_GetAnnot(FPDF_PAGE page, int index); // annot - handle to an annotation. DLLEXPORT void STDCALL FPDFPage_CloseAnnot(FPDF_ANNOTATION annot); +// Remove the annotation in |page| at |index|. +// +// page - handle to a page. +// index - the index of the annotation. +// +// Returns true if successful. +DLLEXPORT FPDF_BOOL STDCALL FPDFPage_RemoveAnnot(FPDF_PAGE page, int index); + // Get the subtype of an annotation. // // annot - handle to an annotation. @@ -115,7 +123,7 @@ FPDFAnnot_GetSubtype(FPDF_ANNOTATION annot); // R, G, B - buffer to hold the RGB value of the color. Ranges from 0 to 255. // A - buffer to hold the opacity. Ranges from 0 to 255. // -// Returns true if successful, false otherwise. +// Returns true if successful. DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetColor(FPDF_ANNOTATION annot, FPDFANNOT_COLORTYPE type, unsigned int R, @@ -133,7 +141,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetColor(FPDF_ANNOTATION annot, // R, G, B - buffer to hold the RGB value of the color. Ranges from 0 to 255. // A - buffer to hold the opacity. Ranges from 0 to 255. // -// Returns true if successful, false otherwise. +// Returns true if successful. DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_GetColor(FPDF_ANNOTATION annot, FPDFANNOT_COLORTYPE type, unsigned int* R, @@ -162,7 +170,7 @@ FPDFAnnot_HasAttachmentPoints(FPDF_ANNOTATION annot); // annot - handle to an annotation. // quadPoints - the quadpoints to be set. // -// Returns true if successful, false otherwise. +// Returns true if successful. DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetAttachmentPoints(FPDF_ANNOTATION annot, const FS_QUADPOINTSF* quadPoints); @@ -184,7 +192,7 @@ FPDFAnnot_GetAttachmentPoints(FPDF_ANNOTATION annot); // annot - handle to an annotation. // rect - the annotation rectangle to be set. // -// Returns true if successful, false otherwise. +// Returns true if successful. DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetRect(FPDF_ANNOTATION annot, const FS_RECTF* rect); @@ -203,7 +211,7 @@ DLLEXPORT FS_RECTF STDCALL FPDFAnnot_GetRect(FPDF_ANNOTATION annot); // type - type of the text to be set. // text - the text to be set. // -// Returns true if successful, false otherwise. +// Returns true if successful. DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetText(FPDF_ANNOTATION annot, FPDFANNOT_TEXTTYPE type, FPDF_WIDESTRING text); -- cgit v1.2.3