summaryrefslogtreecommitdiff
path: root/source/pdf/pdf-form.c
diff options
context:
space:
mode:
authorPaul Gardiner <paul.gardiner@artifex.com>2014-02-14 14:09:41 +0000
committerPaul Gardiner <paul.gardiner@artifex.com>2014-02-14 14:29:56 +0000
commit3f0004acad7da3fcac4687844cb36e2b1ee855b0 (patch)
tree084f97ec66920088e966d2a027ea9b7f1eca4318 /source/pdf/pdf-form.c
parent520dbcb30f9f303fa13f4f2dbd5e7589dd5d7ca6 (diff)
downloadmupdf-3f0004acad7da3fcac4687844cb36e2b1ee855b0.tar.xz
Add function for creating form fields (widgets)
This feature is being implemented mostly for the purpose of permitting the addition to a page of invisible signatures. Also change pdf_create_annot to make freshly created annotations printable by default.
Diffstat (limited to 'source/pdf/pdf-form.c')
-rw-r--r--source/pdf/pdf-form.c67
1 files changed, 53 insertions, 14 deletions
diff --git a/source/pdf/pdf-form.c b/source/pdf/pdf-form.c
index a6ea16c3..c08ecd4e 100644
--- a/source/pdf/pdf-form.c
+++ b/source/pdf/pdf-form.c
@@ -1,19 +1,5 @@
#include "mupdf/pdf.h"
-enum
-{
- F_Invisible = 1 << (1-1),
- F_Hidden = 1 << (2-1),
- F_Print = 1 << (3-1),
- F_NoZoom = 1 << (4-1),
- F_NoRotate = 1 << (5-1),
- F_NoView = 1 << (6-1),
- F_ReadOnly = 1 << (7-1),
- F_Locked = 1 << (8-1),
- F_ToggleNoView = 1 << (9-1),
- F_LockedContents = 1 << (10-1)
-};
-
/* Must be kept in sync with definitions in pdf_util.js */
enum
{
@@ -23,6 +9,12 @@ enum
Display_NoView
};
+enum
+{
+ SigFlag_SignaturesExist = 1,
+ SigFlag_AppendOnly = 2
+};
+
static char *get_string_or_stream(pdf_document *doc, pdf_obj *obj)
{
fz_context *ctx = doc->ctx;
@@ -924,6 +916,53 @@ pdf_widget *pdf_next_widget(pdf_widget *previous)
return (pdf_widget *)annot;
}
+pdf_widget *pdf_create_widget(pdf_document *doc, pdf_page *page, int type, char *fieldname)
+{
+ fz_context *ctx = doc->ctx;
+ pdf_obj *form = NULL;
+ int old_sigflags = pdf_to_int(pdf_dict_getp(pdf_trailer(doc), "Root/AcroForm/SigFlags"));
+ pdf_annot *annot = pdf_create_annot(doc, page, FZ_ANNOT_WIDGET);
+
+ fz_try(ctx)
+ {
+ pdf_set_field_type(doc, annot->obj, type);
+ pdf_dict_puts_drop(annot->obj, "T", pdf_new_string(doc, fieldname, strlen(fieldname)));
+ annot->widget_type = type;
+
+ if (type == PDF_WIDGET_TYPE_SIGNATURE)
+ {
+ int sigflags = (old_sigflags | (SigFlag_SignaturesExist|SigFlag_AppendOnly));
+ pdf_dict_putp_drop(pdf_trailer(doc), "Root/AcroForm/SigFlags", pdf_new_int(doc, sigflags));
+ }
+
+ /*
+ pdf_create_annot will have linked the new widget into the page's
+ annot array. We also need it linked into the document's form
+ */
+ form = pdf_dict_getp(pdf_trailer(doc), "Root/AcroForm/Fields");
+ if (!form)
+ {
+ form = pdf_new_array(doc, 1);
+ pdf_dict_putp_drop(pdf_trailer(doc), "Root/AcroForm/Fields", form);
+ }
+
+ pdf_array_push(form, annot->obj); /* Cleanup relies on this statement being last */
+ }
+ fz_catch(ctx)
+ {
+ pdf_delete_annot(doc, page, annot);
+
+ /* An empty Fields array may have been created, but that is harmless */
+
+ if (type == PDF_WIDGET_TYPE_SIGNATURE)
+ pdf_dict_putp_drop(pdf_trailer(doc), "Root/AcroForm/SigFlags", pdf_new_int(doc, old_sigflags));
+
+ fz_rethrow(ctx);
+ }
+
+ return (pdf_widget *)annot;
+}
+
int pdf_widget_get_type(pdf_widget *widget)
{
pdf_annot *annot = (pdf_annot *)widget;