summaryrefslogtreecommitdiff
path: root/pdf
diff options
context:
space:
mode:
authorPaul Gardiner <paulg.artifex@glidos.net>2012-08-31 17:09:05 +0100
committerPaul Gardiner <paulg.artifex@glidos.net>2012-08-31 17:09:05 +0100
commit769f75087c414d982f33a46c5439ad63b9d4df11 (patch)
treeb660fd9c43db95bd16da2d77d7a807a8b1f936d3 /pdf
parent01ecb79f9bcdeb9280554aff2e26218c07d088dd (diff)
downloadmupdf-769f75087c414d982f33a46c5439ad63b9d4df11.tar.xz
Forms: rework form reset action to use new method introduced for JS
Diffstat (limited to 'pdf')
-rw-r--r--pdf/mupdf-internal.h1
-rw-r--r--pdf/pdf_form.c169
-rw-r--r--pdf/pdf_js.c48
3 files changed, 110 insertions, 108 deletions
diff --git a/pdf/mupdf-internal.h b/pdf/mupdf-internal.h
index eec45acd..b3555f9e 100644
--- a/pdf/mupdf-internal.h
+++ b/pdf/mupdf-internal.h
@@ -575,6 +575,7 @@ void pdf_field_setFillColor(pdf_document *doc, pdf_obj *field, pdf_obj *col);
void pdf_field_setTextColor(pdf_document *doc, pdf_obj *field, pdf_obj *col);
int pdf_field_getDisplay(pdf_document *doc, pdf_obj *field);
void pdf_field_setDisplay(pdf_document *doc, pdf_obj *field, int d);
+pdf_obj *pdf_get_field(pdf_obj *form, char *name);
void pdf_field_reset(pdf_document *doc, pdf_obj *field);
/*
diff --git a/pdf/pdf_form.c b/pdf/pdf_form.c
index 451ba0c0..729baba8 100644
--- a/pdf/pdf_form.c
+++ b/pdf/pdf_form.c
@@ -1462,6 +1462,50 @@ static void update_pushbutton_appearance(pdf_document *doc, pdf_obj *obj)
}
}
+static pdf_obj *find_field(pdf_obj *dict, char *name, int len)
+{
+ pdf_obj *field;
+
+ int i, n = pdf_array_len(dict);
+
+ for (i = 0; i < n; i++)
+ {
+ char *part;
+
+ field = pdf_array_get(dict, i);
+ part = pdf_to_str_buf(pdf_dict_gets(field, "T"));
+ if (strlen(part) == len && !memcmp(part, name, len))
+ return field;
+ }
+
+ return NULL;
+}
+
+pdf_obj *pdf_get_field(pdf_obj *form, char *name)
+{
+ char *dot;
+ char *namep;
+ pdf_obj *dict = NULL;
+ int len;
+
+ /* Process the fully qualified field name which has
+ * the partial names delimited by '.'. Pretend there
+ * was a preceding '.' to simplify the loop */
+ dot = name - 1;
+
+ while (dot && form)
+ {
+ namep = dot + 1;
+ dot = strchr(namep, '.');
+ len = dot ? dot - namep : strlen(namep);
+ dict = find_field(form, namep, len);
+ if (dot)
+ form = pdf_dict_gets(dict, "Kids");
+ }
+
+ return dict;
+}
+
void pdf_field_reset(pdf_document *doc, pdf_obj *field)
{
fz_context *ctx = doc->ctx;
@@ -1475,6 +1519,11 @@ void pdf_field_reset(pdf_document *doc, pdf_obj *field)
* dictionaries, and attempts to remove V will be harmless. */
pdf_obj *dv = pdf_dict_gets(field, "DV");
pdf_obj *kids = pdf_dict_gets(field, "Kids");
+ pdf_obj *noreset = pdf_dict_gets(field, "NoReset");
+
+ /* Don't process fields we have marked not to be reset */
+ if (noreset)
+ return;
if (dv)
pdf_dict_puts(field, "V", dv);
@@ -1533,49 +1582,75 @@ void pdf_field_reset(pdf_document *doc, pdf_obj *field)
doc->dirty = 1;
}
-static void reset_field(pdf_document *doc, pdf_obj *obj)
+
+static void reset_form(pdf_document *doc, pdf_obj *fields, int exclude)
{
fz_context *ctx = doc->ctx;
+ pdf_obj *form = pdf_dict_getp(doc->trailer, "Root/AcroForm/Fields");
+ int i, n;
- doc->dirty = 1;
-
- switch (pdf_field_getType(doc, obj))
+ if (exclude)
{
- case FZ_WIDGET_TYPE_RADIOBUTTON:
- case FZ_WIDGET_TYPE_CHECKBOX:
+ /* mark the fields we don't want to reset */
+ pdf_obj *nil = pdf_new_null(ctx);
+
+ fz_try(ctx)
{
- pdf_obj *name = NULL;
+ n = pdf_array_len(fields);
- fz_var(name);
- fz_try(ctx)
- {
- name = pdf_new_name(ctx, "Off");
- pdf_dict_puts(obj, "AS", name);
- }
- fz_always(ctx)
- {
- pdf_drop_obj(name);
- }
- fz_catch(ctx)
+ for (i = 0; i < n; i++)
{
- fz_rethrow(ctx);
+ pdf_obj *field = pdf_array_get(fields, i);
+
+ if (pdf_is_string(field))
+ field = pdf_get_field(form, pdf_to_str_buf(field));
+
+ if (field)
+ pdf_dict_puts(field, "NoReset", nil);
}
}
- break;
- default:
+ fz_always(ctx)
{
- pdf_obj *def_val = pdf_dict_gets(obj, "DV");
+ pdf_drop_obj(nil);
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
- if (def_val)
- {
- pdf_dict_puts(obj, "V", def_val);
- }
- else
- {
- pdf_dict_dels(obj, "V");
- }
+ /* reset all unmarked fields */
+ n = pdf_array_len(form);
- pdf_field_mark_dirty(ctx, obj);
+ for (i = 0; i < n; i++)
+ pdf_field_reset(doc, pdf_array_get(form, i));
+
+ /* Unmark the marked fields */
+ n = pdf_array_len(fields);
+
+ for (i = 0; i < n; i++)
+ {
+ pdf_obj *field = pdf_array_get(fields, i);
+
+ if (pdf_is_string(field))
+ field = pdf_get_field(form, pdf_to_str_buf(field));
+
+ if (field)
+ pdf_dict_dels(field, "NoReset");
+ }
+ }
+ else
+ {
+ n = pdf_array_len(fields);
+
+ for (i = 0; i < n; i++)
+ {
+ pdf_obj *field = pdf_array_get(fields, i);
+
+ if (pdf_is_string(field))
+ field = pdf_get_field(form, pdf_to_str_buf(field));
+
+ if (field)
+ pdf_field_reset(doc, field);
}
}
}
@@ -1609,37 +1684,7 @@ static void execute_action(pdf_document *doc, pdf_obj *obj, pdf_obj *a)
}
else if (!strcmp(type, "ResetForm"))
{
- int flags = pdf_to_int(pdf_dict_gets(a, "Flags"));
- pdf_obj *affected_fields = pdf_dict_gets(a, "Fields");
- pdf_obj *all_fields = pdf_dict_getp(doc->trailer, "Root/AcroForm/Fields");
- int i, n = pdf_array_len(all_fields);
-
- for (i = 0; i < n; i++)
- {
- pdf_obj *field = pdf_array_get(all_fields, i);
- char *name = pdf_to_str_buf(pdf_dict_gets(field, "T"));
- int j, m = pdf_array_len(affected_fields);
- int found = 0;
-
- for (j = 0; j < m && !found; j++)
- {
- pdf_obj *tfield = pdf_array_get(affected_fields, j);
- char *tname;
-
- /* Elements if the array are either indirect references
- * to fields or field names. */
- tname = pdf_to_str_buf(pdf_is_string(tfield) ? tfield : pdf_dict_gets(tfield, "T"));
-
- if (!strcmp(tname, name))
- found = 1;
- }
-
- if (flags & 1)
- found = !found;
-
- if (found)
- reset_field(doc, field);
- }
+ reset_form(doc, pdf_dict_gets(a, "Fields"), pdf_to_int(pdf_dict_gets(a, "Flags")) & 1);
}
}
}
diff --git a/pdf/pdf_js.c b/pdf/pdf_js.c
index fb2f34cb..28c49186 100644
--- a/pdf/pdf_js.c
+++ b/pdf/pdf_js.c
@@ -272,25 +272,6 @@ static void doc_setApp(void *jsctx, void *obj, pdf_jsimp_obj *val)
fz_warn(js->doc->ctx, "Unexpected call to doc_setApp");
}
-static pdf_obj *find_field(pdf_obj *dict, char *name, int len)
-{
- pdf_obj *field;
-
- int i, n = pdf_array_len(dict);
-
- for (i = 0; i < n; i++)
- {
- char *part;
-
- field = pdf_array_get(dict, i);
- part = pdf_to_str_buf(pdf_dict_gets(field, "T"));
- if (strlen(part) == len && !memcmp(part, name, len))
- break;
- }
-
- return i < n ? field : NULL;
-}
-
static char *utf8_to_pdf(fz_context *ctx, char *utf8)
{
char *pdf = fz_malloc(ctx, strlen(utf8)+1);
@@ -324,31 +305,6 @@ static char *utf8_to_pdf(fz_context *ctx, char *utf8)
return pdf;
}
-static pdf_obj *get_field(pdf_obj *form, char *name)
-{
- char *dot;
- char *namep;
- pdf_obj *dict = NULL;
- int len;
-
- /* Process the fully qualified field name which has
- * the partial names delimited by '.'. Pretend there
- * was a preceding '.' to simplify the loop */
- dot = name - 1;
-
- while (dot && form)
- {
- namep = dot + 1;
- dot = strchr(namep, '.');
- len = dot ? dot - namep : strlen(namep);
- dict = find_field(form, namep, len);
- if (dot)
- form = pdf_dict_gets(dict, "Kids");
- }
-
- return dict;
-}
-
static pdf_jsimp_obj *doc_getField(void *jsctx, void *obj, int argc, pdf_jsimp_obj *args[])
{
pdf_js *js = (pdf_js *)jsctx;
@@ -369,7 +325,7 @@ static pdf_jsimp_obj *doc_getField(void *jsctx, void *obj, int argc, pdf_jsimp_o
if (utf8)
{
name = utf8_to_pdf(ctx, utf8);
- dict = get_field(js->form, name);
+ dict = pdf_get_field(js->form, name);
}
}
fz_always(ctx)
@@ -399,7 +355,7 @@ static void reset_field(pdf_js *js, pdf_jsimp_obj *item)
fz_try(ctx)
{
name = utf8_to_pdf(ctx, utf8);
- field = get_field(js->form, name);
+ field = pdf_get_field(js->form, name);
if (field)
pdf_field_reset(js->doc, field);
}