summaryrefslogtreecommitdiff
path: root/pdf
diff options
context:
space:
mode:
authorPaul Gardiner <paul@glidos.net>2012-05-08 15:12:13 +0100
committerPaul Gardiner <paul@glidos.net>2012-05-08 15:12:13 +0100
commit9ebe09595ad8088f518b6397e791aa44c27a374f (patch)
tree7ad61da049f0905f64bebfc75f34547467d053d9 /pdf
parent1ee037cf638874f8f726bcde8c79ef135cedc755 (diff)
downloadmupdf-9ebe09595ad8088f518b6397e791aa44c27a374f.tar.xz
First go at Javascript-engine abstract API
Diffstat (limited to 'pdf')
-rw-r--r--pdf/mupdf-internal.h36
-rw-r--r--pdf/pdf_form.c46
-rw-r--r--pdf/pdf_js.c114
-rw-r--r--pdf/pdf_jsimp.c59
-rw-r--r--pdf/pdf_xref.c3
5 files changed, 247 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++)