summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fpdfsdk/fpdfannot.cpp19
-rw-r--r--fpdfsdk/fpdfannot_embeddertest.cpp85
-rw-r--r--fpdfsdk/fpdfview_c_api_test.c1
-rw-r--r--public/fpdf_annot.h21
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