diff options
-rw-r--r-- | pdf/mupdf-internal.h | 36 | ||||
-rw-r--r-- | pdf/pdf_form.c | 46 | ||||
-rw-r--r-- | pdf/pdf_js.c | 114 | ||||
-rw-r--r-- | pdf/pdf_jsimp.c | 59 | ||||
-rw-r--r-- | pdf/pdf_xref.c | 3 | ||||
-rw-r--r-- | win32/libmupdf.vcproj | 8 |
6 files changed, 255 insertions, 11 deletions
diff --git a/pdf/mupdf-internal.h b/pdf/mupdf-internal.h index 1a1fad73..d0617769 100644 --- a/pdf/mupdf-internal.h +++ b/pdf/mupdf-internal.h @@ -185,6 +185,8 @@ struct pdf_hotspot_s int state; }; +typedef struct pdf_js_s pdf_js; + struct pdf_document_s { fz_document super; @@ -211,6 +213,8 @@ struct pdf_document_s pdf_lexbuf_large lexbuf; fz_widget *focus; + + pdf_js *js; }; void pdf_cache_object(pdf_document *doc, int num, int gen); @@ -530,6 +534,9 @@ fz_link *pdf_load_link_annots(pdf_document *, pdf_obj *annots, fz_matrix page_ct pdf_annot *pdf_load_annots(pdf_document *, pdf_obj *annots, fz_matrix page_ctm); void pdf_free_annot(fz_context *ctx, pdf_annot *link); +char *pdf_field_getValue(pdf_document *doc, pdf_obj *field); +void pdf_field_setValue(pdf_document *doc, pdf_obj *field, char *text); + /* * Page tree, pages and related objects */ @@ -560,4 +567,33 @@ void pdf_store_item(fz_context *ctx, pdf_obj *key, void *val, unsigned int items void *pdf_find_item(fz_context *ctx, fz_store_free_fn *free, pdf_obj *key); void pdf_remove_item(fz_context *ctx, fz_store_free_fn *free, pdf_obj *key); +/* + * Javascript engine interface + */ +pdf_js *pdf_new_js(pdf_document *doc); +void pdf_drop_js(pdf_js *js); + +typedef struct pdf_jsimp_s pdf_jsimp; +typedef struct pdf_jsimp_type_s pdf_jsimp_type; +typedef struct pdf_jsimp_obj_s pdf_jsimp_obj; + +typedef void (pdf_jsimp_dtr)(void *jsctx, void *obj); +typedef pdf_jsimp_obj *(pdf_jsimp_method)(void *jsctx, void *obj, int argc, pdf_jsimp_obj *args[]); +typedef pdf_jsimp_obj *(pdf_jsimp_getter)(void *jsctx, void *obj); +typedef void (pdf_jsimp_setter)(void *jsctx, void *obj, pdf_jsimp_obj *val); + +pdf_jsimp *pdf_new_jsimp(fz_context *ctx, void *jsctx); +void pdf_drop_jsimp(pdf_jsimp *imp); + +pdf_jsimp_type *pdf_jsimp_new_type(pdf_jsimp *imp, pdf_jsimp_dtr *dtr); +void pdf_jsimp_addmethod(pdf_jsimp *imp, pdf_jsimp_type *type, char *name, pdf_jsimp_method *meth); +void pdf_jsimp_addproperty(pdf_jsimp *imp, pdf_jsimp_type *type, char *name, pdf_jsimp_getter *get, pdf_jsimp_setter *set); + +pdf_jsimp_obj *pdf_jsimp_new_obj(pdf_jsimp *imp, pdf_jsimp_type *type, void *obj); + +void pdf_jsimp_set_this(pdf_jsimp *imp, pdf_jsimp_obj *obj); + +pdf_jsimp_obj *pdf_jsimp_fromString(pdf_jsimp *imp, char *str); +char *pdf_jsimp_toString(pdf_jsimp *imp, pdf_jsimp_obj *obj); + #endif diff --git a/pdf/pdf_form.c b/pdf/pdf_form.c index bee28ece..d1bc7576 100644 --- a/pdf/pdf_form.c +++ b/pdf/pdf_form.c @@ -714,19 +714,17 @@ int fz_widget_get_type(fz_widget *widget) return widget->type; } -char *fz_widget_text_get_text(fz_widget_text *tw) +char *pdf_field_getValue(pdf_document *doc, pdf_obj *field) { - pdf_document *doc = tw->super.doc; fz_context *ctx = doc->ctx; - pdf_obj *vobj = get_inheritable(tw->super.obj, "V"); + pdf_obj *vobj = get_inheritable(field, "V"); int len = 0; char *buf = NULL; fz_buffer *strmbuf = NULL; - - fz_free(ctx, tw->text); - tw->text = NULL; + char *text = NULL; fz_var(strmbuf); + fz_var(text); fz_try(ctx) { if (pdf_is_string(vobj)) @@ -742,9 +740,9 @@ char *fz_widget_text_get_text(fz_widget_text *tw) if (buf) { - tw->text = fz_malloc(ctx, len+1); - memcpy(tw->text, buf, len); - tw->text[len] = 0; + text = fz_malloc(ctx, len+1); + memcpy(text, buf, len); + text[len] = 0; } } fz_always(ctx) @@ -753,6 +751,33 @@ char *fz_widget_text_get_text(fz_widget_text *tw) } fz_catch(ctx) { + fz_free(ctx, text); + fz_rethrow(ctx); + } + + return text; +} + +void pdf_field_setValue(pdf_document *doc, pdf_obj *field, char *text) +{ + update_text_appearance(doc, field, text); + update_text_field_value(doc->ctx, field, text); +} + +char *fz_widget_text_get_text(fz_widget_text *tw) +{ + pdf_document *doc = tw->super.doc; + fz_context *ctx = doc->ctx; + + fz_free(ctx, tw->text); + tw->text = NULL; + + fz_try(ctx) + { + tw->text = pdf_field_getValue(doc, tw->super.obj); + } + fz_catch(ctx) + { fz_warn(ctx, "failed allocation in fz_widget_text_get_text"); } @@ -765,8 +790,7 @@ void fz_widget_text_set_text(fz_widget_text *tw, char *text) fz_try(ctx) { - update_text_appearance(tw->super.doc, tw->super.obj, text); - update_text_field_value(tw->super.doc->ctx, tw->super.obj, text); + pdf_field_setValue(tw->super.doc, tw->super.obj, text); fz_free(ctx, tw->text); tw->text = fz_strdup(ctx, text); } diff --git a/pdf/pdf_js.c b/pdf/pdf_js.c new file mode 100644 index 00000000..4c2e30ab --- /dev/null +++ b/pdf/pdf_js.c @@ -0,0 +1,114 @@ +#include "fitz-internal.h" +#include "mupdf-internal.h" + +struct pdf_js_s +{ + pdf_document *doc; + pdf_obj *form; + pdf_jsimp *imp; + pdf_jsimp_type *doctype; + pdf_jsimp_type *fieldtype; + pdf_jsimp_obj *jsdoc; +}; + +static pdf_jsimp_obj *field_getValue(void *jsctx, void *obj) +{ + pdf_js *js = (pdf_js *)jsctx; + pdf_obj *field = (pdf_obj *)obj; + + return pdf_jsimp_fromString(js->imp, pdf_field_getValue(js->doc, field)); +} + +static void field_setValue(void *jsctx, void *obj, pdf_jsimp_obj *val) +{ + pdf_js *js = (pdf_js *)jsctx; + pdf_obj *field = (pdf_obj *)obj; + + pdf_field_setValue(js->doc, field, pdf_jsimp_toString(js->imp, val)); +} + +static pdf_jsimp_obj *doc_getField(void *jsctx, void *obj, int argc, pdf_jsimp_obj *args[]) +{ + pdf_js *js = (pdf_js *)jsctx; + pdf_obj *field; + int n, i; + char *name; + + if (argc != 1) + return NULL; + + name = pdf_jsimp_toString(js->imp, args[0]); + + n = pdf_array_len(js->form); + + for (i = 0; i < n; i++) + { + pdf_obj *t; + field = pdf_array_get(js->form, i); + t = pdf_dict_gets(field, "T"); + if (!strcmp(name, pdf_to_name(t))) + break; + } + + return (i < n) ? pdf_jsimp_new_obj(js->imp, js->fieldtype, field) + : NULL; +} + +static void declare_dom(pdf_js *js) +{ + pdf_jsimp *imp = js->imp; + + /* Create the document type */ + js->doctype = pdf_jsimp_new_type(imp, NULL); + pdf_jsimp_addmethod(imp, js->doctype, "getField", doc_getField); + + /* Create the field type */ + js->fieldtype = pdf_jsimp_new_type(imp, NULL); + pdf_jsimp_addproperty(imp, js->fieldtype, "value", field_getValue, field_setValue); + + /* Create the document object and tell the engine to use + * it as "this" */ + js->jsdoc = pdf_jsimp_new_obj(imp, js->doctype, NULL); + pdf_jsimp_set_this(js->imp, js->jsdoc); +} + +pdf_js *pdf_new_js(pdf_document *doc) +{ + fz_context *ctx = doc->ctx; + pdf_js *js = NULL; + + fz_var(js); + fz_try(ctx) + { + pdf_obj *root, *acroform; + js = fz_malloc_struct(ctx, pdf_js); + js->doc = doc; + + /* Find the form array */ + root = pdf_dict_gets(doc->trailer, "Root"); + acroform = pdf_dict_gets(root, "AcroForm"); + js->form = pdf_dict_gets(acroform, "Fields"); + + /* Initialise the javascript engine, passing the main context + * for use in memory allocation and exception handling. Also + * pass our js context, for it to pass back to us. */ + js->imp = pdf_new_jsimp(ctx, js); + declare_dom(js); + } + fz_catch(ctx) + { + pdf_drop_js(js); + } + + return js; +} + +void pdf_drop_js(pdf_js *js) +{ + if (js) + { + fz_context *ctx = js->doc->ctx; + pdf_drop_jsimp(js->imp); + fz_free(ctx, js); + } +}
\ No newline at end of file diff --git a/pdf/pdf_jsimp.c b/pdf/pdf_jsimp.c new file mode 100644 index 00000000..080b1df4 --- /dev/null +++ b/pdf/pdf_jsimp.c @@ -0,0 +1,59 @@ +#include "fitz-internal.h" +#include "mupdf-internal.h" + +struct pdf_jsimp_s +{ + int x; +}; + +struct pdf_jsimp_type_s +{ + int x; +}; + +struct pdf_jsimp_obj_s +{ + int x; +}; + + +pdf_jsimp *pdf_new_jsimp(fz_context *ctx, void *jsctx) +{ + return NULL; +} + +void pdf_drop_jsimp(pdf_jsimp *imp) +{ +} + +pdf_jsimp_type *pdf_jsimp_new_type(pdf_jsimp *imp, pdf_jsimp_dtr *dtr) +{ + return NULL; +} + +void pdf_jsimp_addmethod(pdf_jsimp *imp, pdf_jsimp_type *type, char *name, pdf_jsimp_method *meth) +{ +} + +void pdf_jsimp_addproperty(pdf_jsimp *imp, pdf_jsimp_type *type, char *name, pdf_jsimp_getter *get, pdf_jsimp_setter *set) +{ +} + +pdf_jsimp_obj *pdf_jsimp_new_obj(pdf_jsimp *imp, pdf_jsimp_type *type, void *obj) +{ + return NULL; +} + +void pdf_jsimp_set_this(pdf_jsimp *imp, pdf_jsimp_obj *obj) +{ +} + +pdf_jsimp_obj *pdf_jsimp_fromString(pdf_jsimp *imp, char *str) +{ + return NULL; +} + +char *pdf_jsimp_toString(pdf_jsimp *imp, pdf_jsimp_obj *obj) +{ + return NULL; +}
\ No newline at end of file diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c index f260dcbc..e73ce72a 100644 --- a/pdf/pdf_xref.c +++ b/pdf/pdf_xref.c @@ -690,6 +690,7 @@ pdf_open_document_with_stream(fz_stream *file) fz_try(ctx) { + xref->js = pdf_new_js(xref); pdf_load_xref(xref, &xref->lexbuf.base); } fz_catch(ctx) @@ -812,6 +813,8 @@ pdf_close_document(pdf_document *xref) return; ctx = xref->ctx; + pdf_drop_js(xref->js); + if (xref->table) { for (i = 0; i < xref->len; i++) diff --git a/win32/libmupdf.vcproj b/win32/libmupdf.vcproj index ddbb9ef2..c88c5be1 100644 --- a/win32/libmupdf.vcproj +++ b/win32/libmupdf.vcproj @@ -286,6 +286,14 @@ > </File> <File + RelativePath="..\pdf\pdf_js.c" + > + </File> + <File + RelativePath="..\pdf\pdf_jsimp.c" + > + </File> + <File RelativePath="..\pdf\pdf_lex.c" > </File> |