summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fpdfsdk/fpdfannot.cpp18
-rw-r--r--fpdfsdk/fpdfannot_embeddertest.cpp69
-rw-r--r--fpdfsdk/fpdfview_c_api_test.c1
-rw-r--r--public/fpdf_annot.h38
-rw-r--r--testing/resources/text_form_multiple.in69
-rw-r--r--testing/resources/text_form_multiple.pdf82
6 files changed, 277 insertions, 0 deletions
diff --git a/fpdfsdk/fpdfannot.cpp b/fpdfsdk/fpdfannot.cpp
index 1c4345ab52..f3a9ea1b72 100644
--- a/fpdfsdk/fpdfannot.cpp
+++ b/fpdfsdk/fpdfannot.cpp
@@ -18,6 +18,8 @@
#include "core/fpdfapi/parser/cpdf_number.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fpdfdoc/cpdf_annot.h"
+#include "core/fpdfdoc/cpdf_formfield.h"
+#include "core/fpdfdoc/cpdf_interform.h"
#include "core/fpdfdoc/cpvt_color.h"
#include "core/fpdfdoc/cpvt_generateap.h"
#include "fpdfsdk/fsdk_define.h"
@@ -786,3 +788,19 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetFlags(FPDF_ANNOTATION annot,
pAnnotDict->SetNewFor<CPDF_Number>("F", flags);
return true;
}
+
+DLLEXPORT int STDCALL FPDFAnnot_GetFormFieldFlags(FPDF_PAGE page,
+ FPDF_ANNOTATION annot) {
+ CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
+ if (!pPage || !annot)
+ return FPDF_FORMFLAG_NONE;
+
+ CPDF_Dictionary* pAnnotDict =
+ CPDFAnnotContextFromFPDFAnnotation(annot)->GetAnnotDict();
+ if (!pAnnotDict)
+ return FPDF_FORMFLAG_NONE;
+
+ CPDF_InterForm interform(pPage->m_pDocument.Get());
+ CPDF_FormField* pFormField = interform.GetFieldByDict(pAnnotDict);
+ return pFormField ? pFormField->GetFieldFlags() : FPDF_FORMFLAG_NONE;
+}
diff --git a/fpdfsdk/fpdfannot_embeddertest.cpp b/fpdfsdk/fpdfannot_embeddertest.cpp
index c042b764a2..b50f73f3ab 100644
--- a/fpdfsdk/fpdfannot_embeddertest.cpp
+++ b/fpdfsdk/fpdfannot_embeddertest.cpp
@@ -887,3 +887,72 @@ TEST_F(FPDFAnnotEmbeddertest, GetSetStringValue) {
FPDFPage_CloseAnnot(new_annot);
CloseSaved();
}
+
+TEST_F(FPDFAnnotEmbeddertest, GetFormFieldFlagsTextField) {
+ // Open file with form text fields.
+ ASSERT_TRUE(OpenDocument("text_form_multiple.pdf"));
+ FPDF_PAGE page = FPDF_LoadPage(document(), 0);
+ ASSERT_TRUE(page);
+
+ // Retrieve the first annotation: user-editable text field.
+ FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
+ ASSERT_TRUE(annot);
+
+ // Check that the flag values are as expected.
+ int flags = FPDFAnnot_GetFormFieldFlags(page, annot);
+ EXPECT_FALSE(flags & FPDF_FORMFLAG_READONLY);
+ FPDFPage_CloseAnnot(annot);
+
+ // Retrieve the second annotation: read-only text field.
+ annot = FPDFPage_GetAnnot(page, 1);
+ ASSERT_TRUE(annot);
+
+ // Check that the flag values are as expected.
+ flags = FPDFAnnot_GetFormFieldFlags(page, annot);
+ EXPECT_TRUE(flags & FPDF_FORMFLAG_READONLY);
+ FPDFPage_CloseAnnot(annot);
+
+ UnloadPage(page);
+}
+
+TEST_F(FPDFAnnotEmbeddertest, GetFormFieldFlagsComboBox) {
+ // Open file with form text fields.
+ ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
+ FPDF_PAGE page = FPDF_LoadPage(document(), 0);
+ ASSERT_TRUE(page);
+
+ // Retrieve the first annotation: user-editable combobox.
+ FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
+ ASSERT_TRUE(annot);
+
+ // Check that the 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 the second annotation: regular combobox.
+ annot = FPDFPage_GetAnnot(page, 1);
+ ASSERT_TRUE(annot);
+
+ // Check that the 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 the third annotation: read-only combobox.
+ annot = FPDFPage_GetAnnot(page, 2);
+ ASSERT_TRUE(annot);
+
+ // Check that the 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 6753e66c52..1405b40ce8 100644
--- a/fpdfsdk/fpdfview_c_api_test.c
+++ b/fpdfsdk/fpdfview_c_api_test.c
@@ -61,6 +61,7 @@ int CheckPDFiumCApi() {
CHK(FPDFAnnot_GetStringValue);
CHK(FPDFAnnot_GetFlags);
CHK(FPDFAnnot_SetFlags);
+ CHK(FPDFAnnot_GetFormFieldFlags);
// fpdf_attachment.h
CHK(FPDFDoc_GetAttachmentCount);
diff --git a/public/fpdf_annot.h b/public/fpdf_annot.h
index 1351f7193b..2a44e45bc8 100644
--- a/public/fpdf_annot.h
+++ b/public/fpdf_annot.h
@@ -55,6 +55,33 @@ extern "C" {
#define FPDF_ANNOT_FLAG_LOCKED (1 << 7)
#define FPDF_ANNOT_FLAG_TOGGLENOVIEW (1 << 8)
+#define FPDF_OBJECT_UNKNOWN 0
+#define FPDF_OBJECT_BOOLEAN 1
+#define FPDF_OBJECT_NUMBER 2
+#define FPDF_OBJECT_STRING 3
+#define FPDF_OBJECT_NAME 4
+#define FPDF_OBJECT_ARRAY 5
+#define FPDF_OBJECT_DICTIONARY 6
+#define FPDF_OBJECT_STREAM 7
+#define FPDF_OBJECT_NULLOBJ 8
+#define FPDF_OBJECT_REFERENCE 9
+
+// Refer to PDF Reference version 1.7 table 8.70 for field flags common to all
+// interactive form field types.
+#define FPDF_FORMFLAG_NONE 0
+#define FPDF_FORMFLAG_READONLY (1 << 0)
+#define FPDF_FORMFLAG_REQUIRED (1 << 1)
+#define FPDF_FORMFLAG_NOEXPORT (1 << 2)
+
+// Refer to PDF Reference version 1.7 table 8.77 for field flags specific to
+// interactive form text fields.
+#define FPDF_FORMFLAG_TEXT_MULTILINE (1 << 12)
+
+// Refer to PDF Reference version 1.7 table 8.79 for field flags specific to
+// interactive form choice fields.
+#define FPDF_FORMFLAG_CHOICE_COMBO (1 << 17)
+#define FPDF_FORMFLAG_CHOICE_EDIT (1 << 18)
+
typedef enum FPDFANNOT_COLORTYPE {
FPDFANNOT_COLORTYPE_Color = 0,
FPDFANNOT_COLORTYPE_InteriorColor
@@ -366,6 +393,17 @@ DLLEXPORT int STDCALL FPDFAnnot_GetFlags(FPDF_ANNOTATION annot);
DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_SetFlags(FPDF_ANNOTATION annot,
int flags);
+// Experimental API.
+// Get the annotation flags of |annot|, which is an interactive form
+// annotation in |page|.
+//
+// page - handle to a page.
+// annot - handle to an interactive form annotation.
+//
+// Returns the annotation flags specific to interactive forms.
+DLLEXPORT int STDCALL FPDFAnnot_GetFormFieldFlags(FPDF_PAGE page,
+ FPDF_ANNOTATION annot);
+
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
diff --git a/testing/resources/text_form_multiple.in b/testing/resources/text_form_multiple.in
new file mode 100644
index 0000000000..43919eb200
--- /dev/null
+++ b/testing/resources/text_form_multiple.in
@@ -0,0 +1,69 @@
+{{header}}
+{{object 1 0}}
+<<
+ /Type /Catalog
+ /Pages 2 0 R
+ /AcroForm << /Fields [ 4 0 R 9 0 R ] /DR 5 0 R >>
+>>
+endobj
+{{object 2 0}}
+<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
+endobj
+{{object 3 0}}
+<<
+ /Type /Page
+ /Parent 2 0 R
+ /Resources 5 0 R
+ /MediaBox [ 0 0 300 300 ]
+ /Contents 8 0 R
+ /Annots [ 4 0 R 9 0 R ]
+>>
+endobj
+{{object 4 0}}
+<<
+ /Type /Annot
+ /FT /Tx
+ /T (Text Box)
+ /DA (0 0 0 rg /F1 12 Tf)
+ /Rect [ 100 100 200 130 ]
+ /Subtype /Widget
+>>
+endobj
+{{object 5 0}}
+<< /Font 6 0 R >>
+endobj
+{{object 6 0}}
+<< /F1 7 0 R >>
+endobj
+{{object 7 0}} <<
+ /Type /Font
+ /Subtype /Type1
+ /BaseFont /Helvetica
+>>
+endobj
+{{object 8 0}}
+<< /Length 51 >>
+stream
+BT
+0 0 0 rg
+/F1 12 Tf
+100 150 Td
+(Test Form) Tj
+ET
+endstream
+endobj
+{{object 9 0}}
+<<
+ /Type /Annot
+ /FT /Tx
+ /Ff 1
+ /T (ReadOnly)
+ /DA (0 0 0 rg /F1 12 Tf)
+ /Rect [ 100 200 200 230 ]
+ /Subtype /Widget
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/text_form_multiple.pdf b/testing/resources/text_form_multiple.pdf
new file mode 100644
index 0000000000..6b14cefa82
--- /dev/null
+++ b/testing/resources/text_form_multiple.pdf
@@ -0,0 +1,82 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj
+<<
+ /Type /Catalog
+ /Pages 2 0 R
+ /AcroForm << /Fields [ 4 0 R 9 0 R ] /DR 5 0 R >>
+>>
+endobj
+2 0 obj
+<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
+endobj
+3 0 obj
+<<
+ /Type /Page
+ /Parent 2 0 R
+ /Resources 5 0 R
+ /MediaBox [ 0 0 300 300 ]
+ /Contents 8 0 R
+ /Annots [ 4 0 R 9 0 R ]
+>>
+endobj
+4 0 obj
+<<
+ /Type /Annot
+ /FT /Tx
+ /T (Text Box)
+ /DA (0 0 0 rg /F1 12 Tf)
+ /Rect [ 100 100 200 130 ]
+ /Subtype /Widget
+>>
+endobj
+5 0 obj
+<< /Font 6 0 R >>
+endobj
+6 0 obj
+<< /F1 7 0 R >>
+endobj
+7 0 obj <<
+ /Type /Font
+ /Subtype /Type1
+ /BaseFont /Helvetica
+>>
+endobj
+8 0 obj
+<< /Length 51 >>
+stream
+BT
+0 0 0 rg
+/F1 12 Tf
+100 150 Td
+(Test Form) Tj
+ET
+endstream
+endobj
+9 0 obj
+<<
+ /Type /Annot
+ /FT /Tx
+ /Ff 1
+ /T (ReadOnly)
+ /DA (0 0 0 rg /F1 12 Tf)
+ /Rect [ 100 200 200 230 ]
+ /Subtype /Widget
+>>
+endobj
+xref
+0 10
+0000000000 65535 f
+0000000015 00000 n
+0000000120 00000 n
+0000000179 00000 n
+0000000321 00000 n
+0000000457 00000 n
+0000000490 00000 n
+0000000521 00000 n
+0000000597 00000 n
+0000000697 00000 n
+trailer<< /Root 1 0 R /Size 10 >>
+startxref
+841
+%%EOF