summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/pdf/pdf-annot.c3
-rw-r--r--source/pdf/pdf-field.c49
-rw-r--r--source/pdf/pdf-form.c67
-rw-r--r--source/pdf/pdf-pkcs7.c40
4 files changed, 129 insertions, 30 deletions
diff --git a/source/pdf/pdf-annot.c b/source/pdf/pdf-annot.c
index 8e4fd9b1..0aada455 100644
--- a/source/pdf/pdf-annot.c
+++ b/source/pdf/pdf-annot.c
@@ -732,6 +732,9 @@ pdf_create_annot(pdf_document *doc, pdf_page *page, fz_annot_type type)
pdf_dict_puts_drop(annot_obj, "Subtype", pdf_new_name(doc, type_str));
pdf_dict_puts_drop(annot_obj, "Rect", pdf_new_rect(doc, &rect));
+ /* Make printable as default */
+ pdf_dict_puts_drop(annot_obj, "F", pdf_new_int(doc, F_Print));
+
annot = fz_malloc_struct(ctx, pdf_annot);
annot->page = page;
annot->rect = rect;
diff --git a/source/pdf/pdf-field.c b/source/pdf/pdf-field.c
index 2a2f07cc..127d92a5 100644
--- a/source/pdf/pdf-field.c
+++ b/source/pdf/pdf-field.c
@@ -53,3 +53,52 @@ int pdf_field_type(pdf_document *doc, pdf_obj *obj)
else
return PDF_WIDGET_TYPE_NOT_WIDGET;
}
+
+void pdf_set_field_type(pdf_document *doc, pdf_obj *obj, int type)
+{
+ int setbits = 0;
+ int clearbits = 0;
+ char *typename = NULL;
+
+ switch(type)
+ {
+ case PDF_WIDGET_TYPE_PUSHBUTTON:
+ typename = "Btn";
+ setbits = Ff_Pushbutton;
+ break;
+ case PDF_WIDGET_TYPE_CHECKBOX:
+ typename = "Btn";
+ clearbits = Ff_Pushbutton;
+ setbits = Ff_Radio;
+ break;
+ case PDF_WIDGET_TYPE_RADIOBUTTON:
+ typename = "Btn";
+ clearbits = (Ff_Pushbutton|Ff_Radio);
+ break;
+ case PDF_WIDGET_TYPE_TEXT:
+ typename = "Tx";
+ break;
+ case PDF_WIDGET_TYPE_LISTBOX:
+ typename = "Ch";
+ clearbits = Ff_Combo;
+ break;
+ case PDF_WIDGET_TYPE_COMBOBOX:
+ typename = "Ch";
+ setbits = Ff_Combo;
+ break;
+ case PDF_WIDGET_TYPE_SIGNATURE:
+ typename = "Sig";
+ break;
+ }
+
+ if (typename)
+ pdf_dict_puts_drop(obj, "FT", pdf_new_name(doc, typename));
+
+ if (setbits != 0 || clearbits != 0)
+ {
+ int bits = pdf_to_int(pdf_dict_gets(obj, "Ff"));
+ bits &= ~clearbits;
+ bits |= setbits;
+ pdf_dict_puts_drop(obj, "Ff", pdf_new_int(doc, bits));
+ }
+}
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;
diff --git a/source/pdf/pdf-pkcs7.c b/source/pdf/pdf-pkcs7.c
index 178d20ea..a36d1592 100644
--- a/source/pdf/pdf-pkcs7.c
+++ b/source/pdf/pdf-pkcs7.c
@@ -741,29 +741,37 @@ void pdf_sign_signature(pdf_document *doc, pdf_widget *widget, const char *sigfi
fz_try(ctx)
{
char *dn_str;
+ pdf_obj *wobj = ((pdf_annot *)widget)->obj;
+ fz_rect rect = fz_empty_rect;
- pdf_signature_set_value(doc, ((pdf_annot *)widget)->obj, signer);
- dn = pdf_signer_designated_name(signer);
- fzbuf = fz_new_buffer(ctx, 256);
- if (!dn->cn)
- fz_throw(ctx, FZ_ERROR_GENERIC, "Certificate has no common name");
+ pdf_signature_set_value(doc, wobj, signer);
- fz_buffer_printf(ctx, fzbuf, "cn=%s", dn->cn);
+ pdf_to_rect(ctx, pdf_dict_gets(wobj, "Rect"), &rect);
+ /* Create an appearance stream only if the signature is intended to be visible */
+ if (!fz_is_empty_rect(&rect))
+ {
+ dn = pdf_signer_designated_name(signer);
+ fzbuf = fz_new_buffer(ctx, 256);
+ if (!dn->cn)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Certificate has no common name");
+
+ fz_buffer_printf(ctx, fzbuf, "cn=%s", dn->cn);
- if (dn->o)
- fz_buffer_printf(ctx, fzbuf, ", o=%s", dn->o);
+ if (dn->o)
+ fz_buffer_printf(ctx, fzbuf, ", o=%s", dn->o);
- if (dn->ou)
- fz_buffer_printf(ctx, fzbuf, ", ou=%s", dn->ou);
+ if (dn->ou)
+ fz_buffer_printf(ctx, fzbuf, ", ou=%s", dn->ou);
- if (dn->email)
- fz_buffer_printf(ctx, fzbuf, ", email=%s", dn->email);
+ if (dn->email)
+ fz_buffer_printf(ctx, fzbuf, ", email=%s", dn->email);
- if (dn->c)
- fz_buffer_printf(ctx, fzbuf, ", c=%s", dn->c);
+ if (dn->c)
+ fz_buffer_printf(ctx, fzbuf, ", c=%s", dn->c);
- (void)fz_buffer_storage(ctx, fzbuf, (unsigned char **) &dn_str);
- pdf_set_signature_appearance(doc, (pdf_annot *)widget, dn->cn, dn_str, NULL);
+ (void)fz_buffer_storage(ctx, fzbuf, (unsigned char **) &dn_str);
+ pdf_set_signature_appearance(doc, (pdf_annot *)widget, dn->cn, dn_str, NULL);
+ }
}
fz_always(ctx)
{