Add FPDFAnnot_SetFormFieldFlags API to modify form field flags
This CL adds a new public API function FPDFAnnot_SetFormFieldFlags() to
allow modifying form field flags for interactive form annotations. This
enables use cases like setting fields as readonly, enabling multiline
text, password fields, and rich text formatting.
Bug: 42271156
Change-Id: I855bd6fcf5907d735954c2fcb12cacb2983874f1
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/131231
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Helmut Januschka <helmut@januschka.com>
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp
index 40c74d7..3ee31a6 100644
--- a/fpdfsdk/fpdf_annot.cpp
+++ b/fpdfsdk/fpdf_annot.cpp
@@ -1296,6 +1296,19 @@
return pFormField ? pFormField->GetFieldFlags() : FPDF_FORMFLAG_NONE;
}
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
+FPDFAnnot_SetFormFieldFlags(FPDF_FORMHANDLE handle,
+ FPDF_ANNOTATION annot,
+ int flags) {
+ CPDF_FormField* form_field = GetFormField(handle, annot);
+ if (!form_field) {
+ return false;
+ }
+
+ form_field->SetFieldFlags(flags);
+ return true;
+}
+
FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV
FPDFAnnot_GetFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
FPDF_PAGE page,
diff --git a/fpdfsdk/fpdf_annot_embeddertest.cpp b/fpdfsdk/fpdf_annot_embeddertest.cpp
index ac39ed1..9a9ca15 100644
--- a/fpdfsdk/fpdf_annot_embeddertest.cpp
+++ b/fpdfsdk/fpdf_annot_embeddertest.cpp
@@ -3871,3 +3871,66 @@
FPDFAnnot_AddFileAttachment(annot.get(), not_empty_name.get()));
}
}
+
+TEST_F(FPDFAnnotEmbedderTest, SetFormFieldFlags) {
+ ASSERT_TRUE(OpenDocument("text_form_multiple.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+
+ {
+ ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
+ ASSERT_TRUE(annot);
+
+ int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_REQUIRED);
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_NOEXPORT);
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_TEXT_MULTILINE);
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_TEXT_PASSWORD);
+
+ int new_flags = FPDF_FORMFLAG_READONLY | FPDF_FORMFLAG_REQUIRED;
+ EXPECT_TRUE(
+ FPDFAnnot_SetFormFieldFlags(form_handle(), annot.get(), new_flags));
+
+ flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
+ EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY);
+ EXPECT_TRUE(flags & FPDF_FORMFLAG_REQUIRED);
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_NOEXPORT);
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_TEXT_MULTILINE);
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_TEXT_PASSWORD);
+ }
+
+ {
+ ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 3));
+ ASSERT_TRUE(annot);
+
+ int flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_REQUIRED);
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_NOEXPORT);
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_TEXT_MULTILINE);
+ EXPECT_TRUE(flags & FPDF_FORMFLAG_TEXT_PASSWORD);
+
+ int new_flags = FPDF_FORMFLAG_TEXT_MULTILINE | FPDF_FORMFLAG_NOEXPORT;
+ EXPECT_TRUE(
+ FPDFAnnot_SetFormFieldFlags(form_handle(), annot.get(), new_flags));
+
+ flags = FPDFAnnot_GetFormFieldFlags(form_handle(), annot.get());
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_REQUIRED);
+ EXPECT_TRUE(flags & FPDF_FORMFLAG_NOEXPORT);
+ EXPECT_TRUE(flags & FPDF_FORMFLAG_TEXT_MULTILINE);
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_TEXT_PASSWORD);
+ }
+
+ {
+ ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
+ ASSERT_TRUE(annot);
+ EXPECT_FALSE(FPDFAnnot_SetFormFieldFlags(nullptr, annot.get(), 0));
+
+ EXPECT_FALSE(FPDFAnnot_SetFormFieldFlags(form_handle(), nullptr, 0));
+ EXPECT_FALSE(FPDFAnnot_SetFormFieldFlags(nullptr, nullptr, 0));
+ }
+
+ UnloadPage(page);
+}
diff --git a/fpdfsdk/fpdf_view_c_api_test.c b/fpdfsdk/fpdf_view_c_api_test.c
index 9b11e32..a2f3633 100644
--- a/fpdfsdk/fpdf_view_c_api_test.c
+++ b/fpdfsdk/fpdf_view_c_api_test.c
@@ -94,6 +94,7 @@
CHK(FPDFAnnot_SetColor);
CHK(FPDFAnnot_SetFlags);
CHK(FPDFAnnot_SetFocusableSubtypes);
+ CHK(FPDFAnnot_SetFormFieldFlags);
CHK(FPDFAnnot_SetRect);
CHK(FPDFAnnot_SetStringValue);
CHK(FPDFAnnot_SetURI);
diff --git a/public/fpdf_annot.h b/public/fpdf_annot.h
index af0850c..525a9f9 100644
--- a/public/fpdf_annot.h
+++ b/public/fpdf_annot.h
@@ -686,6 +686,20 @@
FPDF_ANNOTATION annot);
// Experimental API.
+// Sets the form field flags for an interactive form annotation.
+//
+// handle - the handle to the form fill module, returned by
+// FPDFDOC_InitFormFillEnvironment().
+// annot - handle to an interactive form annotation.
+// flags - the form field flags to be set.
+//
+// Returns true if successful.
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
+FPDFAnnot_SetFormFieldFlags(FPDF_FORMHANDLE handle,
+ FPDF_ANNOTATION annot,
+ int flags);
+
+// 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.