summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gardiner <paulg.artifex@glidos.net>2012-09-06 15:15:22 +0100
committerPaul Gardiner <paulg.artifex@glidos.net>2012-09-18 14:59:49 +0100
commitc06c3f6183eb6e7955749c060abe99e0b91ea1f7 (patch)
tree841d7fb48faa77628fb1d4dfe79e3830136d3bff
parent33bfa9165dacaabd008144aa96a61612fea97c6b (diff)
downloadmupdf-c06c3f6183eb6e7955749c060abe99e0b91ea1f7.tar.xz
Forms: improve cpp/c interface regarding exceptions
Three alterations: We were previously being careful to avoid throwing exceptions in the DOM-implementation callbacks because these were being called directly from C++. This commit adds three veneers that turn exceptions into warnings, hence allowing the callbacks to be written in usual mupdf style. Protect the "field" callbacks from executing with a NULL field. Ensure that the event object is set up before executing A actions
-rw-r--r--pdf/pdf_form.c8
-rw-r--r--pdf/pdf_js.c51
-rw-r--r--pdf/pdf_jsimp_cpp.c49
-rw-r--r--pdf/pdf_jsimp_cpp.h6
-rw-r--r--pdf/pdf_jsimp_v8.cpp22
5 files changed, 95 insertions, 41 deletions
diff --git a/pdf/pdf_form.c b/pdf/pdf_form.c
index 2fb8114c..76e28058 100644
--- a/pdf/pdf_form.c
+++ b/pdf/pdf_form.c
@@ -1737,9 +1737,13 @@ void pdf_update_appearance(pdf_document *doc, pdf_obj *obj)
static void execute_action_chain(pdf_document *doc, pdf_obj *obj)
{
- pdf_obj *a;
+ pdf_obj *a = pdf_dict_gets(obj, "A");
+ pdf_js_event e;
+
+ e.target = obj;
+ e.value = "";
+ pdf_js_setup_event(doc->js, &e);
- a = pdf_dict_gets(obj, "A");
while (a)
{
execute_action(doc, obj, a);
diff --git a/pdf/pdf_js.c b/pdf/pdf_js.c
index 2443e667..fa33c44c 100644
--- a/pdf/pdf_js.c
+++ b/pdf/pdf_js.c
@@ -70,21 +70,9 @@ static pdf_jsimp_obj *field_buttonSetCaption(void *jsctx, void *obj, int argc, p
static pdf_jsimp_obj *field_getDisplay(void *jsctx, void *obj)
{
pdf_js *js = (pdf_js *)jsctx;
- fz_context *ctx = js->doc->ctx;
pdf_obj *field = (pdf_obj *)obj;
- pdf_jsimp_obj *res = NULL;
- fz_try(ctx)
- {
- int d = pdf_field_display(js->doc, field);
- res = pdf_jsimp_from_number(js->imp, (double)d);
- }
- fz_catch(ctx)
- {
- fz_warn(ctx, "%s", ctx->error->message);
- }
-
- return res;
+ return field ? pdf_jsimp_from_number(js->imp, (double)pdf_field_display(js->doc, field)) : NULL;
}
static void field_setDisplay(void *jsctx, void *obj, pdf_jsimp_obj *val)
@@ -93,15 +81,8 @@ static void field_setDisplay(void *jsctx, void *obj, pdf_jsimp_obj *val)
fz_context *ctx = js->doc->ctx;
pdf_obj *field = (pdf_obj *)obj;
- fz_try(ctx)
- {
- int ival = (int)pdf_jsimp_to_number(js->imp, val);
- pdf_field_set_display(js->doc, field, ival);
- }
- fz_catch(ctx)
- {
- fz_warn(ctx, "%s", ctx->error->message);
- }
+ if (field)
+ pdf_field_set_display(js->doc, field, (int)pdf_jsimp_to_number(js->imp, val));
}
static pdf_jsimp_obj *field_getFillColor(void *jsctx, void *obj)
@@ -114,8 +95,12 @@ static void field_setFillColor(void *jsctx, void *obj, pdf_jsimp_obj *val)
pdf_js *js = (pdf_js *)jsctx;
fz_context *ctx = js->doc->ctx;
pdf_obj *field = (pdf_obj *)obj;
- pdf_obj *col = load_color(js->doc->ctx, js->imp, val);
+ pdf_obj *col;
+ if (!field)
+ return;
+
+ col = load_color(js->doc->ctx, js->imp, val);
fz_try(ctx)
{
pdf_field_set_fill_color(js->doc, field, col);
@@ -140,8 +125,12 @@ static void field_setTextColor(void *jsctx, void *obj, pdf_jsimp_obj *val)
pdf_js *js = (pdf_js *)jsctx;
fz_context *ctx = js->doc->ctx;
pdf_obj *field = (pdf_obj *)obj;
- pdf_obj *col = load_color(js->doc->ctx, js->imp, val);
+ pdf_obj *col;
+
+ if (!field)
+ return;
+ col = load_color(js->doc->ctx, js->imp, val);
fz_try(ctx)
{
pdf_field_set_text_color(js->doc, field, col);
@@ -161,7 +150,7 @@ static pdf_jsimp_obj *field_getBorderStyle(void *jsctx, void *obj)
pdf_js *js = (pdf_js *)jsctx;
pdf_obj *field = (pdf_obj *)obj;
- return pdf_jsimp_from_string(js->imp, pdf_field_border_style(js->doc, field));
+ return field ? pdf_jsimp_from_string(js->imp, pdf_field_border_style(js->doc, field)) : NULL;
}
static void field_setBorderStyle(void *jsctx, void *obj, pdf_jsimp_obj *val)
@@ -169,15 +158,20 @@ static void field_setBorderStyle(void *jsctx, void *obj, pdf_jsimp_obj *val)
pdf_js *js = (pdf_js *)jsctx;
pdf_obj *field = (pdf_obj *)obj;
- pdf_field_set_border_style(js->doc, field, pdf_jsimp_to_string(js->imp, val));
+ if (field)
+ pdf_field_set_border_style(js->doc, field, pdf_jsimp_to_string(js->imp, val));
}
static pdf_jsimp_obj *field_getValue(void *jsctx, void *obj)
{
pdf_js *js = (pdf_js *)jsctx;
pdf_obj *field = (pdf_obj *)obj;
- char *fval = pdf_field_value(js->doc, field);
+ char *fval;
+
+ if (!field)
+ return NULL;
+ fval = pdf_field_value(js->doc, field);
return pdf_jsimp_from_string(js->imp, fval?fval:"");
}
@@ -186,7 +180,8 @@ static void field_setValue(void *jsctx, void *obj, pdf_jsimp_obj *val)
pdf_js *js = (pdf_js *)jsctx;
pdf_obj *field = (pdf_obj *)obj;
- (void)pdf_field_set_value(js->doc, field, pdf_jsimp_to_string(js->imp, val));
+ if (field)
+ (void)pdf_field_set_value(js->doc, field, pdf_jsimp_to_string(js->imp, val));
}
static pdf_jsimp_obj *event_getTarget(void *jsctx, void *obj)
diff --git a/pdf/pdf_jsimp_cpp.c b/pdf/pdf_jsimp_cpp.c
index 5ac449ee..90f2a6e8 100644
--- a/pdf/pdf_jsimp_cpp.c
+++ b/pdf/pdf_jsimp_cpp.c
@@ -166,3 +166,52 @@ void pdf_jsimp_execute_count(pdf_jsimp *imp, char *code, int count)
if (err != NULL)
fz_throw(pdf_jsimp_ctx_cpp(imp), "%s", err);
}
+pdf_jsimp_obj *pdf_jsimp_call_method(pdf_jsimp *imp, pdf_jsimp_method *meth, void *jsctx, void *obj, int argc, pdf_jsimp_obj *args[])
+{
+ fz_context *ctx = pdf_jsimp_ctx_cpp(imp);
+ pdf_jsimp_obj *res;
+
+ fz_try(ctx)
+ {
+ res = meth(jsctx, obj, argc, args);
+ }
+ fz_catch(ctx)
+ {
+ res = NULL;
+ fz_warn(ctx, "%s", ctx->error->message);
+ }
+
+ return res;
+}
+
+pdf_jsimp_obj *pdf_jsimp_call_getter(pdf_jsimp *imp, pdf_jsimp_getter *get, void *jsctx, void *obj)
+{
+ fz_context *ctx = pdf_jsimp_ctx_cpp(imp);
+ pdf_jsimp_obj *res;
+
+ fz_try(ctx)
+ {
+ res = get(jsctx, obj);
+ }
+ fz_catch(ctx)
+ {
+ res = NULL;
+ fz_warn(ctx, "%s", ctx->error->message);
+ }
+
+ return res;
+}
+
+void pdf_jsimp_call_setter(pdf_jsimp *imp, pdf_jsimp_setter *set, void *jsctx, void *obj, pdf_jsimp_obj *val)
+{
+ fz_context *ctx = pdf_jsimp_ctx_cpp(imp);
+
+ fz_try(ctx)
+ {
+ set(jsctx, obj, val);
+ }
+ fz_catch(ctx)
+ {
+ fz_warn(ctx, "%s", ctx->error->message);
+ }
+}
diff --git a/pdf/pdf_jsimp_cpp.h b/pdf/pdf_jsimp_cpp.h
index b794d02d..01b87edd 100644
--- a/pdf/pdf_jsimp_cpp.h
+++ b/pdf/pdf_jsimp_cpp.h
@@ -21,3 +21,9 @@ const char *pdf_jsimp_array_len_cpp(pdf_jsimp *imp, pdf_jsimp_obj *obj, int *len
const char *pdf_jsimp_array_item_cpp(pdf_jsimp *imp, pdf_jsimp_obj *obj, int i, pdf_jsimp_obj **item);
const char *pdf_jsimp_execute_cpp(pdf_jsimp *imp, char *code);
const char *pdf_jsimp_execute_count_cpp(pdf_jsimp *imp, char *code, int count);
+
+/* Also when calling back into mupdf, all exceptions must be caught. The functions bellow
+ * wrap these calls */
+pdf_jsimp_obj *pdf_jsimp_call_method(pdf_jsimp *imp, pdf_jsimp_method *meth, void *jsctx, void *obj, int argc, pdf_jsimp_obj *args[]);
+pdf_jsimp_obj *pdf_jsimp_call_getter(pdf_jsimp *imp, pdf_jsimp_getter *get, void *jsctx, void *obj);
+void pdf_jsimp_call_setter(pdf_jsimp *imp, pdf_jsimp_setter *set, void *jsctx, void *obj, pdf_jsimp_obj *val);
diff --git a/pdf/pdf_jsimp_v8.cpp b/pdf/pdf_jsimp_v8.cpp
index 4e38a9b3..78a14eac 100644
--- a/pdf/pdf_jsimp_v8.cpp
+++ b/pdf/pdf_jsimp_v8.cpp
@@ -17,29 +17,29 @@ extern "C" {
using namespace v8;
using namespace std;
+struct PDFJSImp;
+
/* Object we pass to FunctionTemplate::New, which v8 passes back to us in
* callMethod, allowing us to call our client's, passed-in method. */
struct PDFJSImpMethod
{
- void *jsctx;
+ PDFJSImp *imp;
pdf_jsimp_method *meth;
- PDFJSImpMethod(void *jsctx, pdf_jsimp_method *meth) : jsctx(jsctx), meth(meth) {}
+ PDFJSImpMethod(PDFJSImp *imp, pdf_jsimp_method *meth) : imp(imp), meth(meth) {}
};
/* Object we pass to ObjectTemplate::SetAccessor, which v8 passes back to us in
* setProp and getProp, allowing us to call our client's, passed-in set/get methods. */
struct PDFJSImpProperty
{
- void *jsctx;
+ PDFJSImp *imp;
pdf_jsimp_getter *get;
pdf_jsimp_setter *set;
- PDFJSImpProperty(void *jsctx, pdf_jsimp_getter *get, pdf_jsimp_setter *set) : jsctx(jsctx), get(get), set(set) {}
+ PDFJSImpProperty(PDFJSImp *imp, pdf_jsimp_getter *get, pdf_jsimp_setter *set) : imp(imp), get(get), set(set) {}
};
-struct PDFJSImp;
-
/* Internal representation of the pdf_jsimp_type object */
struct PDFJSImpType
{
@@ -239,7 +239,7 @@ static Handle<Value> callMethod(const Arguments &args)
for (int i = 0; i < c; i++)
native_args[i] = new PDFJSImpObject(args[i]);
- PDFJSImpObject *obj = reinterpret_cast<PDFJSImpObject *>(m->meth(m->jsctx, nself, c, reinterpret_cast<pdf_jsimp_obj **>(native_args)));
+ PDFJSImpObject *obj = reinterpret_cast<PDFJSImpObject *>(pdf_jsimp_call_method(reinterpret_cast<pdf_jsimp *>(m->imp), m->meth, m->imp->jsctx, nself, c, reinterpret_cast<pdf_jsimp_obj **>(native_args)));
Handle<Value> val;
if (obj)
val = obj->toValue();
@@ -258,7 +258,7 @@ extern "C" const char *pdf_jsimp_addmethod_cpp(pdf_jsimp *imp, pdf_jsimp_type *t
PDFJSImpType *vType = reinterpret_cast<PDFJSImpType *>(type);
HandleScope scope;
- PDFJSImpMethod *pmeth = new PDFJSImpMethod(vType->imp->jsctx, meth);
+ PDFJSImpMethod *pmeth = new PDFJSImpMethod(vType->imp, meth);
vType->templ->Set(String::New(name), FunctionTemplate::New(callMethod, External::New(pmeth)));
vType->methods.push_back(pmeth);
return NULL;
@@ -283,7 +283,7 @@ static Handle<Value> getProp(Local<String> property, const AccessorInfo &info)
}
}
- PDFJSImpObject *obj = reinterpret_cast<PDFJSImpObject *>(p->get(p->jsctx, nself));
+ PDFJSImpObject *obj = reinterpret_cast<PDFJSImpObject *>(pdf_jsimp_call_getter(reinterpret_cast<pdf_jsimp *>(p->imp), p->get, p->imp->jsctx, nself));
Handle<Value> val;
if (obj)
val = obj->toValue();
@@ -308,7 +308,7 @@ static void setProp(Local<String> property, Local<Value> value, const AccessorIn
PDFJSImpObject *obj = new PDFJSImpObject(value);
- p->set(p->jsctx, nself, reinterpret_cast<pdf_jsimp_obj *>(obj));
+ pdf_jsimp_call_setter(reinterpret_cast<pdf_jsimp *>(p->imp), p->set, p->imp->jsctx, nself, reinterpret_cast<pdf_jsimp_obj *>(obj));
delete obj;
}
@@ -317,7 +317,7 @@ extern "C" const char *pdf_jsimp_addproperty_cpp(pdf_jsimp *imp, pdf_jsimp_type
PDFJSImpType *vType = reinterpret_cast<PDFJSImpType *>(type);
HandleScope scope;
- PDFJSImpProperty *prop = new PDFJSImpProperty(vType->imp->jsctx, get, set);
+ PDFJSImpProperty *prop = new PDFJSImpProperty(vType->imp, get, set);
vType->templ->SetAccessor(String::New(name), getProp, setProp, External::New(prop));
vType->properties.push_back(prop);
return NULL;