diff options
-rw-r--r-- | fpdfsdk/fpdfannot.cpp | 18 | ||||
-rw-r--r-- | fpdfsdk/fpdfannot_embeddertest.cpp | 69 | ||||
-rw-r--r-- | fpdfsdk/fpdfview_c_api_test.c | 1 | ||||
-rw-r--r-- | public/fpdf_annot.h | 38 | ||||
-rw-r--r-- | testing/resources/text_form_multiple.in | 69 | ||||
-rw-r--r-- | testing/resources/text_form_multiple.pdf | 82 |
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 |