diff options
author | Jane Liu <janeliulwq@google.com> | 2017-07-06 11:13:35 -0400 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-07-06 15:45:04 +0000 |
commit | 3656774aa2b654f3c26c188c45a1d284962e9c43 (patch) | |
tree | 4fd866138291c80ef06089da729c0b9eda1b7df0 | |
parent | 75e1ab05e731d99b9acdc86de47640720e848415 (diff) | |
download | pdfium-3656774aa2b654f3c26c188c45a1d284962e9c43.tar.xz |
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 <janeliulwq@google.com>
Reviewed-by: dsinclair <dsinclair@chromium.org>
-rw-r--r-- | fpdfsdk/fpdfannot.cpp | 90 | ||||
-rw-r--r-- | fpdfsdk/fpdfannot_embeddertest.cpp | 177 | ||||
-rw-r--r-- | fpdfsdk/fpdfview_c_api_test.c | 8 | ||||
-rw-r--r-- | public/fpdf_annot.h | 62 |
4 files changed, 248 insertions, 89 deletions
diff --git a/fpdfsdk/fpdfannot.cpp b/fpdfsdk/fpdfannot.cpp index d7ab8abac1..024c52bc10 100644 --- a/fpdfsdk/fpdfannot.cpp +++ b/fpdfsdk/fpdfannot.cpp @@ -236,12 +236,11 @@ FPDFAnnot_GetSubtype(FPDF_ANNOTATION annot) { CPDF_Annot::StringToAnnotSubtype(pAnnotDict->GetStringFor("Subtype"))); } -DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_UpdatePathObject(FPDF_ANNOTATION annot, - FPDF_PAGEOBJECT path) { +DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_UpdateObject(FPDF_ANNOTATION annot, + FPDF_PAGEOBJECT obj) { CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot); - CPDF_PageObject* pPathObj = CPDFPageObjectFromFPDFPageObject(path); - if (!pAnnot || !pAnnot->GetAnnotDict() || !pAnnot->HasForm() || !pPathObj || - !pPathObj->IsPath()) + CPDF_PageObject* pObj = CPDFPageObjectFromFPDFPageObject(obj); + if (!pAnnot || !pAnnot->GetAnnotDict() || !pAnnot->HasForm() || !pObj) return false; // Check that the annotation type is supported by this method. @@ -250,19 +249,19 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_UpdatePathObject(FPDF_ANNOTATION annot, return false; // Check that the annotation already has an appearance stream, since an - // existing path object is to be updated. + // existing object is to be updated. CPDF_Stream* pStream = FPDFDOC_GetAnnotAP(pAnnot->GetAnnotDict(), CPDF_Annot::AppearanceMode::Normal); if (!pStream) return false; - // Check that the path object is already in this annotation's object list. + // Check that the object is already in this annotation's object list. CPDF_PageObjectList* pObjList = pAnnot->GetForm()->GetPageObjectList(); - auto it = std::find_if( - pObjList->begin(), pObjList->end(), - [pPathObj](const std::unique_ptr<CPDF_PageObject>& candidate) { - return candidate.get() == pPathObj; - }); + auto it = + std::find_if(pObjList->begin(), pObjList->end(), + [pObj](const std::unique_ptr<CPDF_PageObject>& candidate) { + return candidate.get() == pObj; + }); if (it == pObjList->end()) return false; @@ -275,11 +274,11 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_UpdatePathObject(FPDF_ANNOTATION annot, return true; } -DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_AppendPathObject(FPDF_ANNOTATION annot, - FPDF_PAGEOBJECT path) { +DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_AppendObject(FPDF_ANNOTATION annot, + FPDF_PAGEOBJECT obj) { CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot); - CPDF_PageObject* pPathObj = CPDFPageObjectFromFPDFPageObject(path); - if (!pAnnot || !pPathObj || !pPathObj->IsPath()) + CPDF_PageObject* pObj = CPDFPageObjectFromFPDFPageObject(obj); + if (!pAnnot || !pObj) return false; CPDF_Dictionary* pAnnotDict = pAnnot->GetAnnotDict(); @@ -316,22 +315,22 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_AppendPathObject(FPDF_ANNOTATION annot, CPDF_Form* pForm = pAnnot->GetForm(); - // Check that the path object did not come from the same annotation. If this - // check succeeds, then it is assumed that the path object came from - // FPDFPageObj_CreateNewPath(). Note that a path object that came from a - // different annotation must not be passed here, since a path object cannot - // belong to more than one annotation. + // Check that the object did not come from the same annotation. If this check + // succeeds, then it is assumed that the object came from + // FPDFPageObj_CreateNew{Path|Rect}() or FPDFPageObj_New{Text|Image}Obj(). + // Note that an object that came from a different annotation must not be + // passed here, since an object cannot belong to more than one annotation. CPDF_PageObjectList* pObjList = pForm->GetPageObjectList(); - auto it = std::find_if( - pObjList->begin(), pObjList->end(), - [pPathObj](const std::unique_ptr<CPDF_PageObject>& candidate) { - return candidate.get() == pPathObj; - }); + auto it = + std::find_if(pObjList->begin(), pObjList->end(), + [pObj](const std::unique_ptr<CPDF_PageObject>& candidate) { + return candidate.get() == pObj; + }); if (it != pObjList->end()) return false; - // Append the path object to the object list. - std::unique_ptr<CPDF_PageObject> pPageObjHolder(pPathObj); + // Append the object to the object list. + std::unique_ptr<CPDF_PageObject> pPageObjHolder(pObj); pObjList->push_back(std::move(pPageObjHolder)); // Set the content stream data in the annotation's AP stream. @@ -343,9 +342,9 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_AppendPathObject(FPDF_ANNOTATION annot, return true; } -DLLEXPORT int STDCALL FPDFAnnot_GetPathObjectCount(FPDF_ANNOTATION annot) { +DLLEXPORT int STDCALL FPDFAnnot_GetObjectCount(FPDF_ANNOTATION annot) { CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot); - if (!pAnnot) + if (!pAnnot || !pAnnot->GetAnnotDict()) return 0; if (!pAnnot->HasForm()) { @@ -356,19 +355,13 @@ DLLEXPORT int STDCALL FPDFAnnot_GetPathObjectCount(FPDF_ANNOTATION annot) { pAnnot->SetForm(pStream); } - - int pathCount = 0; - for (const auto& pObj : *pAnnot->GetForm()->GetPageObjectList()) { - if (pObj && pObj->IsPath()) - ++pathCount; - } - return pathCount; + return pAnnot->GetForm()->GetPageObjectList()->size(); } -DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFAnnot_GetPathObject(FPDF_ANNOTATION annot, - int index) { +DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFAnnot_GetObject(FPDF_ANNOTATION annot, + int index) { CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot); - if (!pAnnot || index < 0) + if (!pAnnot || !pAnnot->GetAnnotDict() || index < 0) return nullptr; if (!pAnnot->HasForm()) { @@ -380,22 +373,7 @@ DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFAnnot_GetPathObject(FPDF_ANNOTATION annot, pAnnot->SetForm(pStream); } - const CPDF_PageObjectList* pObjList = pAnnot->GetForm()->GetPageObjectList(); - if (static_cast<size_t>(index) >= pObjList->size()) - return nullptr; - - // Retrieve the path object located at |index| in the list of path objects. - // Note that the list of path objects is a sublist of the page object list, - // consisting of only path objects specifically. - int pathCount = -1; - for (const auto& pObj : *pObjList) { - if (pObj && pObj->IsPath()) { - ++pathCount; - if (pathCount == index) - return pObj.get(); - } - } - return nullptr; + return pAnnot->GetForm()->GetPageObjectList()->GetPageObjectByIndex(index); } DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetColor(FPDF_ANNOTATION annot, 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<unsigned short, pdfium::FreeDeleter> 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<unsigned short, pdfium::FreeDeleter> 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); +} diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c index 01c318912f..0027aa4b52 100644 --- a/fpdfsdk/fpdfview_c_api_test.c +++ b/fpdfsdk/fpdfview_c_api_test.c @@ -42,10 +42,10 @@ int CheckPDFiumCApi() { CHK(FPDFPage_CloseAnnot); CHK(FPDFPage_RemoveAnnot); CHK(FPDFAnnot_GetSubtype); - CHK(FPDFAnnot_UpdatePathObject); - CHK(FPDFAnnot_AppendPathObject); - CHK(FPDFAnnot_GetPathObjectCount); - CHK(FPDFAnnot_GetPathObject); + CHK(FPDFAnnot_UpdateObject); + CHK(FPDFAnnot_AppendObject); + CHK(FPDFAnnot_GetObjectCount); + CHK(FPDFAnnot_GetObject); CHK(FPDFAnnot_SetColor); CHK(FPDFAnnot_GetColor); CHK(FPDFAnnot_HasAttachmentPoints); diff --git a/public/fpdf_annot.h b/public/fpdf_annot.h index 971662f8e8..7c3b7247c8 100644 --- a/public/fpdf_annot.h +++ b/public/fpdf_annot.h @@ -67,6 +67,7 @@ typedef enum FPDFANNOT_TEXTTYPE { FPDFANNOT_TEXTTYPE_Author } FPDFANNOT_TEXTTYPE; +// Experimental API. // Check if an annotation subtype is currently supported for creation. // Currently supported subtypes: circle, highlight, ink, popup, square, // squiggly, stamp, strikeout, text, and underline. @@ -77,6 +78,7 @@ typedef enum FPDFANNOT_TEXTTYPE { DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_IsSupportedSubtype(FPDF_ANNOTATION_SUBTYPE subtype); +// Experimental API. // Create an annotation in |page| of the subtype |subtype|. If the specified // subtype is illegal or unsupported, then a new annotation will not be created. // Must call FPDFPage_CloseAnnot() when the annotation returned by this @@ -89,6 +91,7 @@ FPDFAnnot_IsSupportedSubtype(FPDF_ANNOTATION_SUBTYPE subtype); DLLEXPORT FPDF_ANNOTATION STDCALL FPDFPage_CreateAnnot(FPDF_PAGE page, FPDF_ANNOTATION_SUBTYPE subtype); +// Experimental API. // Get the number of annotations in |page|. // // page - handle to a page. @@ -96,6 +99,7 @@ FPDFPage_CreateAnnot(FPDF_PAGE page, FPDF_ANNOTATION_SUBTYPE subtype); // Returns the number of annotations in |page|. DLLEXPORT int STDCALL FPDFPage_GetAnnotCount(FPDF_PAGE page); +// Experimental API. // Get annotation in |page| at |index|. Must call FPDFPage_CloseAnnot() when the // annotation returned by this function is no longer needed. // @@ -105,6 +109,7 @@ DLLEXPORT int STDCALL FPDFPage_GetAnnotCount(FPDF_PAGE page); // Returns a handle to the annotation object, or NULL on failure. DLLEXPORT FPDF_ANNOTATION STDCALL FPDFPage_GetAnnot(FPDF_PAGE page, int index); +// Experimental API. // Close an annotation. Must be called when the annotation returned by // FPDFPage_CreateAnnot() or FPDFPage_GetAnnot() is no longer needed. This // function does not remove the annotation from the document. @@ -112,6 +117,7 @@ DLLEXPORT FPDF_ANNOTATION STDCALL FPDFPage_GetAnnot(FPDF_PAGE page, int index); // annot - handle to an annotation. DLLEXPORT void STDCALL FPDFPage_CloseAnnot(FPDF_ANNOTATION annot); +// Experimental API. // Remove the annotation in |page| at |index|. // // page - handle to a page. @@ -120,6 +126,7 @@ DLLEXPORT void STDCALL FPDFPage_CloseAnnot(FPDF_ANNOTATION annot); // Returns true if successful. DLLEXPORT FPDF_BOOL STDCALL FPDFPage_RemoveAnnot(FPDF_PAGE page, int index); +// Experimental API. // Get the subtype of an annotation. // // annot - handle to an annotation. @@ -129,48 +136,53 @@ DLLEXPORT FPDF_ANNOTATION_SUBTYPE STDCALL FPDFAnnot_GetSubtype(FPDF_ANNOTATION annot); // Experimental API. -// Update |path| in |annot|. |path| must be in |annot| already and must have -// been retrieved by FPDFAnnot_GetPathObject(). Only ink and stamp annotations -// are supported currently. +// Update |obj| in |annot|. |obj| must be in |annot| already and must have +// been retrieved by FPDFAnnot_GetObject(). Currently, only ink and stamp +// annotations are supported by this API. Also note that only path, image, and +// text objects have APIs for modification; see FPDFPath_*(), FPDFText_*(), and +// FPDFImageObj_*(). // // annot - handle to an annotation. -// path - handle to the path that |annot| needs to update. +// obj - handle to the object that |annot| needs to update. // // Return true if successful. -DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_UpdatePathObject(FPDF_ANNOTATION annot, - FPDF_PAGEOBJECT path); +DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_UpdateObject(FPDF_ANNOTATION annot, + FPDF_PAGEOBJECT obj); // Experimental API. -// Add |path| to |annot|. |path| must have been created by -// FPDFPageObj_CreateNewPath(), and will be owned by |annot|. Note that a |path| -// cannot belong to more than one |annot|. Only ink and stamp annotations -// are supported currently. +// Add |obj| to |annot|. |obj| must have been created by +// FPDFPageObj_CreateNew{Path|Rect}() or FPDFPageObj_New{Text|Image}Obj(), and +// will be owned by |annot|. Note that an |obj| cannot belong to more than one +// |annot|. Currently, only ink and stamp annotations are supported by this API. +// Also note that only path, image, and text objects have APIs for creation. // // annot - handle to an annotation. -// path - handle to the path that is to be added to |annot|. +// obj - handle to the object that is to be added to |annot|. // // Return true if successful. -DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_AppendPathObject(FPDF_ANNOTATION annot, - FPDF_PAGEOBJECT path); +DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_AppendObject(FPDF_ANNOTATION annot, + FPDF_PAGEOBJECT obj); // Experimental API. -// Get the number of path objects in |annot|. +// Get the total number of objects in |annot|, including path objects, text +// objects, external objects, image objects, and shading objects. // // annot - handle to an annotation. // -// Returns the number of path objects in |annot|. -DLLEXPORT int STDCALL FPDFAnnot_GetPathObjectCount(FPDF_ANNOTATION annot); +// Returns the number of objects in |annot|. +DLLEXPORT int STDCALL FPDFAnnot_GetObjectCount(FPDF_ANNOTATION annot); // Experimental API. -// Get the path object in |annot| at |index|. +// Get the object in |annot| at |index|. // // annot - handle to an annotation. -// index - the index of the path object. +// index - the index of the object. // -// Return a handle to the path object, or NULL on failure. -DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFAnnot_GetPathObject(FPDF_ANNOTATION annot, - int index); +// Return a handle to the object, or NULL on failure. +DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFAnnot_GetObject(FPDF_ANNOTATION annot, + int index); +// Experimental API. // Set the color of an annotation. Fails when called on annotations with // appearance streams already defined; instead use // FPDFPath_Set{Stroke|Fill}Color(). @@ -188,6 +200,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetColor(FPDF_ANNOTATION annot, unsigned int B, unsigned int A); +// Experimental API. // Get the color of an annotation. If no color is specified, default to yellow // for highlight annotation, black for all else. Fails when called on // annotations with appearance streams already defined; instead use @@ -206,6 +219,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_GetColor(FPDF_ANNOTATION annot, unsigned int* B, unsigned int* A); +// Experimental API. // Check if the annotation is of a type that has attachment points // (i.e. quadpoints). Quadpoints are the vertices of the rectange that // encompasses the texts affected by the annotation. They provide the @@ -220,6 +234,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_GetColor(FPDF_ANNOTATION annot, DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_HasAttachmentPoints(FPDF_ANNOTATION annot); +// Experimental API. // Set the attachment points (i.e. quadpoints) of an annotation. If the // annotation's appearance stream is defined and this annotation is of a type // with quadpoints, then update the bounding box too. @@ -232,6 +247,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetAttachmentPoints(FPDF_ANNOTATION annot, const FS_QUADPOINTSF* quadPoints); +// Experimental API. // Get the attachment points (i.e. quadpoints) of an annotation. If the // annotation's appearance stream is defined and this annotation is of a type // with quadpoints, then return the bounding box it specifies instead. @@ -242,6 +258,7 @@ FPDFAnnot_SetAttachmentPoints(FPDF_ANNOTATION annot, DLLEXPORT FS_QUADPOINTSF STDCALL FPDFAnnot_GetAttachmentPoints(FPDF_ANNOTATION annot); +// Experimental API. // Set the annotation rectangle defining the location of the annotation. If the // annotation's appearance stream is defined and this annotation is of a type // without quadpoints, then update the bounding box too. @@ -253,6 +270,7 @@ FPDFAnnot_GetAttachmentPoints(FPDF_ANNOTATION annot); DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetRect(FPDF_ANNOTATION annot, const FS_RECTF* rect); +// Experimental API. // Get the annotation rectangle defining the location of the annotation. If the // annotation's appearance stream is defined and this annotation is of a type // without quadpoints, then return the bounding box it specifies instead. @@ -262,6 +280,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetRect(FPDF_ANNOTATION annot, // Returns a rectangle object, or an empty rectangle on failure. DLLEXPORT FS_RECTF STDCALL FPDFAnnot_GetRect(FPDF_ANNOTATION annot); +// Experimental API. // Set the contents of an annotation. // // annot - handle to an annotation. @@ -273,6 +292,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetText(FPDF_ANNOTATION annot, FPDFANNOT_TEXTTYPE type, FPDF_WIDESTRING text); +// Experimental API. // Get the contents of an annotation. |buffer| is only modified if |buflen| // is longer than the length of contents. // |