diff options
author | Paul Gardiner <paul@glidos.net> | 2012-06-28 14:19:10 +0100 |
---|---|---|
committer | Paul Gardiner <paul@glidos.net> | 2012-06-28 14:20:20 +0100 |
commit | d03b9b3ce5726f9479c35ed2b9c2bee670850a26 (patch) | |
tree | 701af10c0ee3ffc8c3e4a2a26c552920789aea08 /pdf | |
parent | c88b0849511b970abe9864993c011af89e0daccc (diff) | |
download | mupdf-d03b9b3ce5726f9479c35ed2b9c2bee670850a26.tar.xz |
Forms: implement javascript form-field formatting
Consists in adding JS function AFNumber_Format and updating the DOM to
include event.value
Diffstat (limited to 'pdf')
-rw-r--r-- | pdf/mupdf-internal.h | 1 | ||||
-rw-r--r-- | pdf/pdf_form.c | 84 | ||||
-rw-r--r-- | pdf/pdf_js.c | 113 | ||||
-rw-r--r-- | pdf/pdf_js_none.c | 5 |
4 files changed, 173 insertions, 30 deletions
diff --git a/pdf/mupdf-internal.h b/pdf/mupdf-internal.h index 69702ef3..018565d6 100644 --- a/pdf/mupdf-internal.h +++ b/pdf/mupdf-internal.h @@ -601,6 +601,7 @@ fz_widget *pdf_get_focussed_widget(pdf_document *doc); pdf_js *pdf_new_js(pdf_document *doc); void pdf_drop_js(pdf_js *js); void pdf_js_setup_event(pdf_js *js, pdf_obj *target); +char *pdf_js_getEventValue(pdf_js *js); void pdf_js_execute(pdf_js *js, char *code); void pdf_js_execute_count(pdf_js *js, char *code, int count); diff --git a/pdf/pdf_form.c b/pdf/pdf_form.c index 56e2e5d8..65f9392f 100644 --- a/pdf/pdf_form.c +++ b/pdf/pdf_form.c @@ -1156,7 +1156,7 @@ static pdf_xobject *load_or_create_form(pdf_document *doc, pdf_obj *obj, fz_rect return form; } -static void update_text_appearance(pdf_document *doc, pdf_obj *obj) +static void update_text_appearance(pdf_document *doc, pdf_obj *obj, char *eventValue) { fz_context *ctx = doc->ctx; text_widget_info info; @@ -1175,7 +1175,11 @@ static void update_text_appearance(pdf_document *doc, pdf_obj *obj) fz_var(text); fz_try(ctx) { - text = pdf_field_getValue(doc, obj); + if (eventValue) + text = fz_strdup(ctx, eventValue); + else + text = pdf_field_getValue(doc, obj); + get_text_widget_info(doc, obj, &info); form = load_or_create_form(doc, obj, &rect); @@ -1348,27 +1352,6 @@ static void update_pushbutton_appearance(pdf_document *doc, pdf_obj *obj) } } -void pdf_update_appearance(pdf_document *doc, pdf_obj *obj) -{ - if (!pdf_dict_gets(obj, "AP") || pdf_dict_gets(obj, "Dirty")) - { - if (!strcmp(pdf_to_name(pdf_dict_gets(obj, "Subtype")), "Widget")) - { - switch(get_field_type(doc, obj)) - { - case FZ_WIDGET_TYPE_TEXT: - update_text_appearance(doc, obj); - break; - case FZ_WIDGET_TYPE_PUSHBUTTON: - update_pushbutton_appearance(doc, obj); - break; - } - } - - pdf_dict_dels(obj, "Dirty"); - } -} - static void reset_field(pdf_document *doc, pdf_obj *obj) { fz_context *ctx = doc->ctx; @@ -1414,13 +1397,10 @@ static void reset_field(pdf_document *doc, pdf_obj *obj) } } -static void execute_action(pdf_document *doc, pdf_obj *obj) +static void execute_action(pdf_document *doc, pdf_obj *obj, pdf_obj *a) { fz_context *ctx = doc->ctx; - pdf_obj *a; - - a = pdf_dict_gets(obj, "A"); - while (a) + if (a) { char *type = pdf_to_name(pdf_dict_gets(a, "S")); @@ -1479,7 +1459,53 @@ static void execute_action(pdf_document *doc, pdf_obj *obj) reset_field(doc, field); } } + } +} +void pdf_update_appearance(pdf_document *doc, pdf_obj *obj) +{ + if (!pdf_dict_gets(obj, "AP") || pdf_dict_gets(obj, "Dirty")) + { + if (!strcmp(pdf_to_name(pdf_dict_gets(obj, "Subtype")), "Widget")) + { + switch(get_field_type(doc, obj)) + { + case FZ_WIDGET_TYPE_TEXT: + { + pdf_obj *formatting = pdf_dict_getp(obj, "AA/F"); + if (formatting) + { + /* Apply formatting */ + execute_action(doc, obj, formatting); + /* Update appearance from JS event.value */ + update_text_appearance(doc, obj, pdf_js_getEventValue(doc->js)); + } + else + { + /* Update appearance from field value */ + update_text_appearance(doc, obj, NULL); + } + } + break; + case FZ_WIDGET_TYPE_PUSHBUTTON: + update_pushbutton_appearance(doc, obj); + break; + } + } + + pdf_dict_dels(obj, "Dirty"); + } +} + +static void execute_action_chain(pdf_document *doc, pdf_obj *obj) +{ + fz_context *ctx = doc->ctx; + pdf_obj *a; + + a = pdf_dict_gets(obj, "A"); + while (a) + { + execute_action(doc, obj, a); a = pdf_dict_gets(a, "Next"); } } @@ -1670,7 +1696,7 @@ int pdf_pass_event(pdf_document *doc, pdf_page *page, fz_ui_event *ui_event) break; } - execute_action(doc, annot->obj); + execute_action_chain(doc, annot->obj); } break; } diff --git a/pdf/pdf_js.c b/pdf/pdf_js.c index 72111775..d3022bc1 100644 --- a/pdf/pdf_js.c +++ b/pdf/pdf_js.c @@ -4,6 +4,7 @@ typedef struct pdf_js_event_s { pdf_obj *target; + char *value; } pdf_js_event; struct pdf_js_s @@ -170,6 +171,23 @@ static void event_setTarget(void *jsctx, void *obj, pdf_jsimp_obj *val) fz_warn(js->doc->ctx, "Unexpected call to event_setTarget"); } +static pdf_jsimp_obj *event_getValue(void *jsctx, void *obj) +{ + pdf_js *js = (pdf_js *)jsctx; + pdf_js_event *e = (pdf_js_event *)obj; + + return pdf_jsimp_fromString(js->imp, js->event.value); +} + +static void event_setValue(void *jsctx, void *obj, pdf_jsimp_obj *val) +{ + pdf_js *js = (pdf_js *)jsctx; + fz_context *ctx = js->doc->ctx; + fz_free(ctx, js->event.value); + js->event.value = NULL; + js->event.value = fz_strdup(ctx, pdf_jsimp_toString(js->imp, val)); +} + static pdf_jsimp_obj *doc_getEvent(void *jsctx, void *obj) { pdf_js *js = (pdf_js *)jsctx; @@ -222,6 +240,7 @@ static void declare_dom(pdf_js *js) /* Create the event type */ js->eventtype = pdf_jsimp_new_type(imp, NULL); pdf_jsimp_addproperty(imp, js->eventtype, "target", event_getTarget, event_setTarget); + pdf_jsimp_addproperty(imp, js->eventtype, "value", event_getValue, event_setValue); /* Create the field type */ js->fieldtype = pdf_jsimp_new_type(imp, NULL); @@ -256,7 +275,84 @@ static void preload_helpers(pdf_js *js) "color.yellow = [ \"CMYK\", 0,0,1,0 ];\n" "color.dkGray = [ \"G\", 0.25];\n" "color.gray = [ \"G\", 0.5];\n" - "color.ltGray = [ \"G\", 0.75];\n"); + "color.ltGray = [ \"G\", 0.75];\n" + "\n" + "function AFNumber_Format(nDec,sepStyle,negStyle,currStyle,strCurrency,bCurrencyPrepend)\n" + "{\n" + " var val = event.value;\n" + " var fracpart;\n" + " var intpart;\n" + " var point = sepStyle&2 ? ',' : '.';\n" + " var separator = sepStyle&2 ? '.' : ',';\n" + "\n" + " if (/^\\D*\\./.test(val))\n" + " val = '0'+val;\n" + "\n" + " var groups = val.match(/\\d+/g);\n" + "\n" + " switch (groups.length)\n" + " {\n" + " case 0:\n" + " return;\n" + " case 1:\n" + " fracpart = '';\n" + " intpart = groups[0];\n" + " break;\n" + " default:\n" + " fracpart = groups.pop();\n" + " intpart = groups.join('');\n" + " break;\n" + " }\n" + "\n" + " // Remove leading zeros\n" + " intpart = intpart.replace(/^0*/,'');\n" + " if (!intpart)\n" + " intpart = '0';\n" + "\n" + " if ((sepStyle & 1) == 0)\n" + " {\n" + " // Add the thousands sepearators: pad to length multiple of 3 with zeros,\n" + " // split into 3s, join with separator, and remove the leading zeros\n" + " intpart = new Array(2-(intpart.length+2)%3+1).join('0') + intpart;\n" + " intpart = intpart.match(/.../g).join(separator).replace(/^0*/,'');\n" + " }\n" + "\n" + " if (!intpart)\n" + " intpart = '0';\n" + "\n" + " // Adjust fractional part to correct number of decimal places\n" + " fracpart += new Array(nDec+1).join('0');\n" + " fracpart = fracpart.substr(0,nDec);\n" + "\n" + " if (fracpart)\n" + " intpart += point+fracpart;\n" + "\n" + " if (bCurrencyPrepend)\n" + " intpart = strCurrency+intpart;\n" + " else\n" + " intpart += strCurrency;\n" + "\n" + " if (/-/.test(val))\n" + " {\n" + " switch (negStyle)\n" + " {\n" + " case 0:\n" + " intpart = '-'+intpart;\n" + " break;\n" + " case 1:\n" + " break;\n" + " case 2:\n" + " case 3:\n" + " intpart = '('+intpart+')';\n" + " break;\n" + " }\n" + " }\n" + "\n" + " if (negStyle&1)\n" + " event.target.textColor = /-/.text(val) ? color.red : color.black;\n" + "\n" + " event.value = intpart;\n" + "}\n"); } pdf_js *pdf_new_js(pdf_document *doc) @@ -338,6 +434,7 @@ void pdf_drop_js(pdf_js *js) if (js) { fz_context *ctx = js->doc->ctx; + fz_free(ctx, js->event.value); pdf_jsimp_drop_type(js->imp, js->fieldtype); pdf_jsimp_drop_type(js->imp, js->doctype); pdf_drop_jsimp(js->imp); @@ -348,7 +445,21 @@ void pdf_drop_js(pdf_js *js) void pdf_js_setup_event(pdf_js *js, pdf_obj *target) { if (js) + { + fz_context *ctx = js->doc->ctx; + char *val = pdf_field_getValue(js->doc, target); + js->event.target = target; + + fz_free(ctx, js->event.value); + js->event.value = NULL; + js->event.value = fz_strdup(ctx, val?val:""); + } +} + +char *pdf_js_getEventValue(pdf_js *js) +{ + return js ? js->event.value : NULL; } void pdf_js_execute(pdf_js *js, char *code) diff --git a/pdf/pdf_js_none.c b/pdf/pdf_js_none.c index bc8d2ee7..34c7c491 100644 --- a/pdf/pdf_js_none.c +++ b/pdf/pdf_js_none.c @@ -17,6 +17,11 @@ void pdf_js_setup_event(pdf_js *js, pdf_obj *target) { } +char *pdf_js_getEventValue(pdf_js *js) +{ + return ""; +} + void pdf_js_execute(pdf_js *js, char *code) { } |