diff options
-rw-r--r-- | fpdfsdk/fpdfannot.cpp | 19 | ||||
-rw-r--r-- | fpdfsdk/fpdfannot_embeddertest.cpp | 85 | ||||
-rw-r--r-- | fpdfsdk/fpdfview_c_api_test.c | 1 | ||||
-rw-r--r-- | public/fpdf_annot.h | 21 |
4 files changed, 126 insertions, 0 deletions
diff --git a/fpdfsdk/fpdfannot.cpp b/fpdfsdk/fpdfannot.cpp index f3a9ea1b72..fcbed5c2ce 100644 --- a/fpdfsdk/fpdfannot.cpp +++ b/fpdfsdk/fpdfannot.cpp @@ -804,3 +804,22 @@ DLLEXPORT int STDCALL FPDFAnnot_GetFormFieldFlags(FPDF_PAGE page, CPDF_FormField* pFormField = interform.GetFieldByDict(pAnnotDict); return pFormField ? pFormField->GetFieldFlags() : FPDF_FORMFLAG_NONE; } + +DLLEXPORT FPDF_ANNOTATION STDCALL +FPDFAnnot_GetFormFieldAtPoint(FPDF_FORMHANDLE hHandle, + FPDF_PAGE page, + double page_x, + double page_y) { + CPDF_Page* pPage = CPDFPageFromFPDFPage(page); + if (!hHandle || !pPage) + return nullptr; + + CPDF_InterForm interform(pPage->m_pDocument.Get()); + int annot_index = -1; + CPDF_FormControl* pFormCtrl = interform.GetControlAtPoint( + pPage, CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)), + &annot_index); + if (!pFormCtrl || annot_index == -1) + return nullptr; + return FPDFPage_GetAnnot(page, annot_index); +} diff --git a/fpdfsdk/fpdfannot_embeddertest.cpp b/fpdfsdk/fpdfannot_embeddertest.cpp index b50f73f3ab..58a00067a7 100644 --- a/fpdfsdk/fpdfannot_embeddertest.cpp +++ b/fpdfsdk/fpdfannot_embeddertest.cpp @@ -956,3 +956,88 @@ TEST_F(FPDFAnnotEmbeddertest, GetFormFieldFlagsComboBox) { UnloadPage(page); } + +TEST_F(FPDFAnnotEmbeddertest, GetFormAnnotNull) { + // Open file with form text fields. + EXPECT_TRUE(OpenDocument("text_form.pdf")); + FPDF_PAGE page = LoadPage(0); + ASSERT_TRUE(page); + + // Attempt to get an annotation where no annotation exists on page. + FPDF_ANNOTATION annot = + FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 0, 0); + EXPECT_FALSE(annot); + + UnloadPage(page); +} + +TEST_F(FPDFAnnotEmbeddertest, GetFormAnnotAndCheckFlagsTextField) { + // Open file with form text fields. + EXPECT_TRUE(OpenDocument("text_form_multiple.pdf")); + FPDF_PAGE page = LoadPage(0); + ASSERT_TRUE(page); + + // Retrieve user-editable text field annotation. + FPDF_ANNOTATION annot = + FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 105, 118); + ASSERT_TRUE(annot); + + // Check that interactive form annotation flag values are as expected. + int flags = FPDFAnnot_GetFormFieldFlags(page, annot); + EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY); + FPDFPage_CloseAnnot(annot); + + // Retrieve read-only text field annotation. + annot = FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 105, 202); + ASSERT_TRUE(annot); + + // Check that interactive form annotation flag values are as expected. + flags = FPDFAnnot_GetFormFieldFlags(page, annot); + EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY); + FPDFPage_CloseAnnot(annot); + + UnloadPage(page); +} + +TEST_F(FPDFAnnotEmbeddertest, GetFormAnnotAndCheckFlagsComboBox) { + // Open file with form comboboxes. + EXPECT_TRUE(OpenDocument("combobox_form.pdf")); + FPDF_PAGE page = LoadPage(0); + ASSERT_TRUE(page); + + // Retrieve user-editable combobox annotation. + FPDF_ANNOTATION annot = + FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 102, 63); + ASSERT_TRUE(annot); + + // Check that interactive form annotation flag values are as expected. + int flags = FPDFAnnot_GetFormFieldFlags(page, annot); + EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY); + EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO); + EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_EDIT); + FPDFPage_CloseAnnot(annot); + + // Retrieve regular combobox annotation. + annot = FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 102, 113); + ASSERT_TRUE(annot); + + // Check that interactive form annotation flag values are as expected. + flags = FPDFAnnot_GetFormFieldFlags(page, annot); + EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY); + EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO); + EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT); + FPDFPage_CloseAnnot(annot); + + // Retrieve read-only combobox annotation. + annot = FPDFAnnot_GetFormFieldAtPoint(form_handle(), page, 102, 213); + ASSERT_TRUE(annot); + + // Check that interactive form annotation flag values are as expected. + flags = FPDFAnnot_GetFormFieldFlags(page, annot); + EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY); + EXPECT_TRUE(flags & FPDF_FORMFLAG_CHOICE_COMBO); + EXPECT_FALSE(flags & FPDF_FORMFLAG_CHOICE_EDIT); + FPDFPage_CloseAnnot(annot); + + UnloadPage(page); +} diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c index 1405b40ce8..546ae47512 100644 --- a/fpdfsdk/fpdfview_c_api_test.c +++ b/fpdfsdk/fpdfview_c_api_test.c @@ -62,6 +62,7 @@ int CheckPDFiumCApi() { CHK(FPDFAnnot_GetFlags); CHK(FPDFAnnot_SetFlags); CHK(FPDFAnnot_GetFormFieldFlags); + CHK(FPDFAnnot_GetFormFieldAtPoint); // fpdf_attachment.h CHK(FPDFDoc_GetAttachmentCount); diff --git a/public/fpdf_annot.h b/public/fpdf_annot.h index 2a44e45bc8..c0f9a6e4c6 100644 --- a/public/fpdf_annot.h +++ b/public/fpdf_annot.h @@ -9,6 +9,7 @@ #include "fpdfview.h" #include "fpdf_doc.h" +#include "fpdf_formfill.h" #ifdef __cplusplus extern "C" { @@ -404,6 +405,26 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetFlags(FPDF_ANNOTATION annot, DLLEXPORT int STDCALL FPDFAnnot_GetFormFieldFlags(FPDF_PAGE page, FPDF_ANNOTATION annot); +// Experimental API. +// Retrieves an interactive form annotation whose rectangle contains a given +// point on a page. Must call FPDFPage_CloseAnnot() when the annotation returned +// is no longer needed. +// +// +// hHandle - handle to the form fill module, returned by +// FPDFDOC_InitFormFillEnvironment. +// page - handle to the page, returned by FPDF_LoadPage function. +// page_x - X position in PDF "user space". +// page_y - Y position in PDF "user space". +// +// Returns the interactive form annotation whose rectangle contains the given +// coordinates on the page. If there is no such annotation, return NULL. +DLLEXPORT FPDF_ANNOTATION STDCALL +FPDFAnnot_GetFormFieldAtPoint(FPDF_FORMHANDLE hHandle, + FPDF_PAGE page, + double page_x, + double page_y); + #ifdef __cplusplus } // extern "C" #endif // __cplusplus |