From 3656774aa2b654f3c26c188c45a1d284962e9c43 Mon Sep 17 00:00:00 2001 From: Jane Liu Date: Thu, 6 Jul 2017 11:13:35 -0400 Subject: Generalized annotation APIs to support image and text objects Generalized the following annotation APIs to support working with image and text objects: FPDFAnnot_AppendPathObject() -> FPDFAnnot_AppendObject() FPDFAnnot_UpdatePathObject() -> FPDFAnnot_UpdateObject() FPDFAnnot_GetPathObjectCount() -> FPDFAnnot_GetObjectCount() FPDFAnnot_GetPathObject() -> FPDFAnnot_GetObject() Also added two embeddertests to test appending, retrieving, editting, and updating image and text objects in annotations. Bug=pdfium:737 Change-Id: If3ea5846d5abec7dc195291bb1a0ef4b17f0d604 Reviewed-on: https://pdfium-review.googlesource.com/7210 Commit-Queue: Jane Liu Reviewed-by: dsinclair --- fpdfsdk/fpdfannot_embeddertest.cpp | 177 +++++++++++++++++++++++++++++++++++-- 1 file changed, 169 insertions(+), 8 deletions(-) (limited to 'fpdfsdk/fpdfannot_embeddertest.cpp') diff --git a/fpdfsdk/fpdfannot_embeddertest.cpp b/fpdfsdk/fpdfannot_embeddertest.cpp index beaedf91af..7d174ff11d 100644 --- a/fpdfsdk/fpdfannot_embeddertest.cpp +++ b/fpdfsdk/fpdfannot_embeddertest.cpp @@ -486,15 +486,16 @@ TEST_F(FPDFAnnotEmbeddertest, AddAndModifyPath) { ASSERT_TRUE(annot); // Check that this annotation has one path object and retrieve it. - EXPECT_EQ(1, FPDFAnnot_GetPathObjectCount(annot)); - FPDF_PAGEOBJECT path = FPDFAnnot_GetPathObject(annot, 1); + EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot)); + FPDF_PAGEOBJECT path = FPDFAnnot_GetObject(annot, 1); EXPECT_FALSE(path); - path = FPDFAnnot_GetPathObject(annot, 0); + path = FPDFAnnot_GetObject(annot, 0); + EXPECT_EQ(FPDF_PAGEOBJ_PATH, FPDFPageObj_GetType(path)); EXPECT_TRUE(path); // Modify the color of the path object. EXPECT_TRUE(FPDFPath_SetStrokeColor(path, 0, 0, 0, 255)); - EXPECT_TRUE(FPDFAnnot_UpdatePathObject(annot, path)); + EXPECT_TRUE(FPDFAnnot_UpdateObject(annot, path)); FPDFPage_CloseAnnot(annot); // Check that the page with the modified annotation renders correctly. @@ -521,8 +522,8 @@ TEST_F(FPDFAnnotEmbeddertest, AddAndModifyPath) { EXPECT_TRUE(FPDFPath_SetStrokeColor(check, 0, 255, 255, 180)); EXPECT_TRUE(FPDFPath_SetStrokeWidth(check, 8.35f)); EXPECT_TRUE(FPDFPath_SetDrawMode(check, 0, 1)); - EXPECT_TRUE(FPDFAnnot_AppendPathObject(annot, check)); - EXPECT_EQ(1, FPDFAnnot_GetPathObjectCount(annot)); + EXPECT_TRUE(FPDFAnnot_AppendObject(annot, check)); + EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot)); // Check that the annotation's bounding box came from its rectangle. FS_RECTF new_rect = FPDFAnnot_GetRect(annot); @@ -539,11 +540,11 @@ TEST_F(FPDFAnnotEmbeddertest, AddAndModifyPath) { // Open the saved document. TestSaved(595, 842, md5_3); - // Check that the saved document has a correct count of annotations and paths. + // Check that the document has a correct count of annotations and objects. EXPECT_EQ(3, FPDFPage_GetAnnotCount(m_SavedPage)); annot = FPDFPage_GetAnnot(m_SavedPage, 2); ASSERT_TRUE(annot); - EXPECT_EQ(1, FPDFAnnot_GetPathObjectCount(annot)); + EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot)); // Check that the new annotation's rectangle is as defined. new_rect = FPDFAnnot_GetRect(annot); @@ -605,3 +606,163 @@ TEST_F(FPDFAnnotEmbeddertest, ModifyAnnotationFlags) { FPDFPage_CloseAnnot(annot); UnloadPage(page); } + +TEST_F(FPDFAnnotEmbeddertest, AddAndModifyImage) { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + const char md5[] = "c35408717759562d1f8bf33d317483d2"; + const char md5_2[] = "ff012f5697436dfcaec25b32d1333596"; + const char md5_3[] = "86cf8cb2755a7a2046a543e66d9c1e61"; +#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + const char md5[] = "bdf96279ab82d9f484874db3f0c03429"; + const char md5_2[] = "048a9af8b6239b59a19dacd8e1688e0a"; + const char md5_3[] = "3be8aa2ebc927e32060e7116dd937a14"; +#else + const char md5[] = "07d4168715553b4294525f840c40aa1c"; + const char md5_2[] = "9685b2a0cf11ee730125f88ab10ff1d0"; + const char md5_3[] = "0763407baf3656b8061bbbe698e9fd89"; +#endif + + // Open a file with two annotations and load its first page. + ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf")); + FPDF_PAGE page = FPDF_LoadPage(document(), 0); + ASSERT_TRUE(page); + EXPECT_EQ(2, FPDFPage_GetAnnotCount(page)); + + // Check that the page renders correctly. + FPDF_BITMAP bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT); + CompareBitmap(bitmap, 595, 842, md5); + FPDFBitmap_Destroy(bitmap); + + // Create a stamp annotation and set its annotation rectangle. + FPDF_ANNOTATION annot = FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP); + ASSERT_TRUE(annot); + FS_RECTF rect; + rect.left = 200.f; + rect.bottom = 600.f; + rect.right = 400.f; + rect.top = 800.f; + EXPECT_TRUE(FPDFAnnot_SetRect(annot, &rect)); + + // Add a solid-color translucent image object to the new annotation. + constexpr int kBitmapSize = 200; + FPDF_BITMAP image_bitmap = FPDFBitmap_Create(kBitmapSize, kBitmapSize, 1); + FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize, kBitmapSize, 0xeeeecccc); + EXPECT_EQ(kBitmapSize, FPDFBitmap_GetWidth(image_bitmap)); + EXPECT_EQ(kBitmapSize, FPDFBitmap_GetHeight(image_bitmap)); + FPDF_PAGEOBJECT image_object = FPDFPageObj_NewImageObj(document()); + ASSERT_TRUE(FPDFImageObj_SetBitmap(&page, 0, image_object, image_bitmap)); + ASSERT_TRUE(FPDFImageObj_SetMatrix(image_object, kBitmapSize, 0, 0, + kBitmapSize, 0, 0)); + FPDFPageObj_Transform(image_object, 1, 0, 0, 1, 200, 600); + EXPECT_TRUE(FPDFAnnot_AppendObject(annot, image_object)); + FPDFPage_CloseAnnot(annot); + + // Check that the page renders correctly with the new image object. + bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT); + CompareBitmap(bitmap, 595, 842, md5_2); + FPDFBitmap_Destroy(bitmap); + + // Retrieve the newly added stamp annotation and its image object. + annot = FPDFPage_GetAnnot(page, 2); + ASSERT_TRUE(annot); + EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot)); + image_object = FPDFAnnot_GetObject(annot, 0); + EXPECT_EQ(FPDF_PAGEOBJ_IMAGE, FPDFPageObj_GetType(image_object)); + + // Modify the image in the new annotation. + FPDFBitmap_FillRect(image_bitmap, 0, 0, kBitmapSize, kBitmapSize, 0xff000000); + ASSERT_TRUE(FPDFImageObj_SetBitmap(&page, 0, image_object, image_bitmap)); + EXPECT_TRUE(FPDFAnnot_UpdateObject(annot, image_object)); + FPDFPage_CloseAnnot(annot); + + // Save the document, closing the page and document. + EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0)); + FPDF_ClosePage(page); + + // Test that the saved document renders the modified image object correctly. + TestSaved(595, 842, md5_3); + + FPDFBitmap_Destroy(image_bitmap); + CloseSaved(); +} + +TEST_F(FPDFAnnotEmbeddertest, AddAndModifyText) { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + const char md5[] = "c35408717759562d1f8bf33d317483d2"; + const char md5_2[] = "e5680ed048c2cfd9a1d27212cdf41286"; + const char md5_3[] = "79f5cfb0b07caaf936f65f6a7a57ce77"; +#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + const char md5[] = "bdf96279ab82d9f484874db3f0c03429"; + const char md5_2[] = "fa5709c115d4ebd502df91841b44b3ef"; + const char md5_3[] = "9f6fa52dc477ccf52be4184d8589ef3f"; +#else + const char md5[] = "07d4168715553b4294525f840c40aa1c"; + const char md5_2[] = "40a4c5e0561b062882b47253be3393ef"; + const char md5_3[] = "f8ce0682add01f6d273890ac64d90fa6"; +#endif + + // Open a file with two annotations and load its first page. + ASSERT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf")); + FPDF_PAGE page = FPDF_LoadPage(document(), 0); + ASSERT_TRUE(page); + EXPECT_EQ(2, FPDFPage_GetAnnotCount(page)); + + // Check that the page renders correctly. + FPDF_BITMAP bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT); + CompareBitmap(bitmap, 595, 842, md5); + FPDFBitmap_Destroy(bitmap); + + // Create a stamp annotation and set its annotation rectangle. + FPDF_ANNOTATION annot = FPDFPage_CreateAnnot(page, FPDF_ANNOT_STAMP); + ASSERT_TRUE(annot); + FS_RECTF rect; + rect.left = 200.f; + rect.bottom = 550.f; + rect.right = 450.f; + rect.top = 650.f; + EXPECT_TRUE(FPDFAnnot_SetRect(annot, &rect)); + + // Add a translucent text object to the new annotation. + FPDF_PAGEOBJECT text_object = + FPDFPageObj_NewTextObj(document(), "Arial", 12.0f); + EXPECT_TRUE(text_object); + std::unique_ptr text = + GetFPDFWideString(L"I'm a translucent text laying on other text."); + EXPECT_TRUE(FPDFText_SetText(text_object, text.get())); + EXPECT_TRUE(FPDFText_SetFillColor(text_object, 0, 0, 255, 150)); + FPDFPageObj_Transform(text_object, 1, 0, 0, 1, 200, 600); + EXPECT_TRUE(FPDFAnnot_AppendObject(annot, text_object)); + FPDFPage_CloseAnnot(annot); + + // Check that the page renders correctly with the new text object. + bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT); + CompareBitmap(bitmap, 595, 842, md5_2); + FPDFBitmap_Destroy(bitmap); + + // Retrieve the newly added stamp annotation and its text object. + annot = FPDFPage_GetAnnot(page, 2); + ASSERT_TRUE(annot); + EXPECT_EQ(1, FPDFAnnot_GetObjectCount(annot)); + text_object = FPDFAnnot_GetObject(annot, 0); + EXPECT_EQ(FPDF_PAGEOBJ_TEXT, FPDFPageObj_GetType(text_object)); + + // Modify the text in the new annotation. + std::unique_ptr new_text = + GetFPDFWideString(L"New text!"); + EXPECT_TRUE(FPDFText_SetText(text_object, new_text.get())); + EXPECT_TRUE(FPDFAnnot_UpdateObject(annot, text_object)); + FPDFPage_CloseAnnot(annot); + + // Check that the page renders correctly with the modified text object. + bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT); + CompareBitmap(bitmap, 595, 842, md5_3); + FPDFBitmap_Destroy(bitmap); + + // Remove the new annotation, and check that the page renders as before. + EXPECT_TRUE(FPDFPage_RemoveAnnot(page, 2)); + bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT); + CompareBitmap(bitmap, 595, 842, md5); + FPDFBitmap_Destroy(bitmap); + + UnloadPage(page); +} -- cgit v1.2.3