]> rtime.felk.cvut.cz Git - hornmich/skoda-qr-demo.git/blob - QRScanner/mobile/jni/pdf/js/pdf-jsimp-mu.c
Add MuPDF native source codes
[hornmich/skoda-qr-demo.git] / QRScanner / mobile / jni / pdf / js / pdf-jsimp-mu.c
1 #include "mupdf/pdf.h"
2
3 #include <mujs.h>
4
5 #define MAXARGS 16
6
7 #define OBJ(i) ((pdf_jsimp_obj*)((intptr_t)(i)))
8 #define IDX(p) ((intptr_t)(p))
9 #define NEWOBJ(J,x) OBJ(js_gettop(J) + (x))
10
11 struct pdf_jsimp_s
12 {
13         fz_context *ctx;
14         void *jsctx;
15         js_State *J;
16 };
17
18 static void *alloc(void *ud, void *ptr, unsigned int n)
19 {
20         fz_context *ctx = ud;
21         if (n == 0) {
22                 fz_free(ctx, ptr);
23                 return NULL;
24         }
25         if (ptr)
26                 return fz_resize_array(ctx, ptr, n, 1);
27         return fz_malloc_array(ctx, n, 1);
28 }
29
30 pdf_jsimp *pdf_new_jsimp(fz_context *ctx, void *jsctx)
31 {
32         js_State *J;
33         pdf_jsimp *imp;
34
35         J = js_newstate(alloc, ctx, 0);
36         js_setcontext(J, jsctx);
37
38         imp = fz_malloc_struct(ctx, pdf_jsimp);
39         imp->ctx = ctx;
40         imp->jsctx = jsctx;
41         imp->J = J;
42         return imp;
43 }
44
45 void pdf_drop_jsimp(pdf_jsimp *imp)
46 {
47         if (imp)
48         {
49                 js_freestate(imp->J);
50                 fz_free(imp->ctx, imp);
51         }
52 }
53
54 pdf_jsimp_type *pdf_jsimp_new_type(pdf_jsimp *imp, pdf_jsimp_dtr *dtr, char *name)
55 {
56         js_State *J = imp->J;
57         js_newobject(J);
58         js_setregistry(J, name);
59         return (pdf_jsimp_type*)name;
60 }
61
62 void pdf_jsimp_drop_type(pdf_jsimp *imp, pdf_jsimp_type *type)
63 {
64         if (imp && type)
65         {
66                 js_State *J = imp->J;
67                 js_delregistry(J, (const char *)type);
68         }
69 }
70
71 static void wrapmethod(js_State *J)
72 {
73         pdf_jsimp_obj *args[MAXARGS];
74         pdf_jsimp_obj *ret;
75         pdf_jsimp_method *meth;
76         const char *type;
77         void *jsctx;
78         void *obj;
79         int i;
80
81         int argc = js_gettop(J) - 1;
82
83         jsctx = js_getcontext(J);
84
85         js_currentfunction(J);
86         {
87                 js_getproperty(J, -1, "__call");
88                 meth = js_touserdata(J, -1, "method");
89                 js_pop(J, 1);
90
91                 js_getproperty(J, -1, "__type");
92                 type = js_tostring(J, -1);
93                 js_pop(J, 1);
94         }
95         js_pop(J, 1);
96
97         if (js_isuserdata(J, 0, type))
98                 obj = js_touserdata(J, 0, type);
99         else
100                 obj = NULL;
101
102         if (argc > MAXARGS)
103                 js_rangeerror(J, "too many arguments");
104
105         for (i = 0; i < argc; ++i)
106                 args[i] = OBJ(i+1);
107         ret = meth(jsctx, obj, argc, args);
108         if (ret)
109                 js_copy(J, IDX(ret));
110         else
111                 js_pushundefined(J);
112 }
113
114 static void wrapgetter(js_State *J)
115 {
116         pdf_jsimp_obj *ret;
117         pdf_jsimp_getter *get;
118         const char *type;
119         void *jsctx;
120         void *obj;
121
122         jsctx = js_getcontext(J);
123
124         js_currentfunction(J);
125         {
126                 js_getproperty(J, -1, "__get");
127                 get = js_touserdata(J, -1, "getter");
128                 js_pop(J, 1);
129
130                 js_getproperty(J, -1, "__type");
131                 type = js_tostring(J, -1);
132                 js_pop(J, 1);
133         }
134         js_pop(J, 1);
135
136         if (js_isuserdata(J, 0, type))
137                 obj = js_touserdata(J, 0, type);
138         else
139                 obj = NULL;
140
141         ret = get(jsctx, obj);
142         if (ret)
143                 js_copy(J, IDX(ret));
144         else
145                 js_pushundefined(J);
146 }
147
148 static void wrapsetter(js_State *J)
149 {
150         pdf_jsimp_setter *set;
151         const char *type;
152         void *jsctx;
153         void *obj;
154
155         jsctx = js_getcontext(J);
156
157         js_currentfunction(J);
158         {
159                 js_getproperty(J, -1, "__set");
160                 set = js_touserdata(J, -1, "setter");
161                 js_pop(J, 1);
162
163                 js_getproperty(J, -1, "__type");
164                 type = js_tostring(J, -1);
165                 js_pop(J, 1);
166         }
167         js_pop(J, 1);
168
169         if (js_isuserdata(J, 0, type))
170                 obj = js_touserdata(J, 0, type);
171         else
172                 obj = NULL;
173
174         set(jsctx, obj, OBJ(1));
175
176         js_pushundefined(J);
177 }
178
179 void pdf_jsimp_addmethod(pdf_jsimp *imp, pdf_jsimp_type *type, char *name, pdf_jsimp_method *meth)
180 {
181         js_State *J = imp->J;
182         js_getregistry(J, (const char *)type);
183         {
184                 js_newcfunction(J, wrapmethod, name, 0);
185                 {
186                         js_pushnull(J);
187                         js_newuserdata(J, "method", meth, NULL);
188                         js_defproperty(J, -2, "__call", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
189                         js_pushstring(J, (const char *)type);
190                         js_defproperty(J, -2, "__type", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
191                 }
192                 js_defproperty(J, -2, name, JS_READONLY | JS_DONTCONF);
193         }
194         js_pop(J, 1);
195 }
196
197 void pdf_jsimp_addproperty(pdf_jsimp *imp, pdf_jsimp_type *type, char *name, pdf_jsimp_getter *get, pdf_jsimp_setter *set)
198 {
199         js_State *J = imp->J;
200         js_getregistry(J, (const char *)type);
201         {
202                 js_newcfunction(J, wrapgetter, name, 0);
203                 {
204                         js_pushnull(J);
205                         js_newuserdata(J, "getter", get, NULL);
206                         js_defproperty(J, -2, "__get", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
207                         js_pushstring(J, (const char *)type);
208                         js_defproperty(J, -2, "__type", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
209                 }
210                 js_newcfunction(J, wrapsetter, name, 0);
211                 {
212                         js_pushnull(J);
213                         js_newuserdata(J, "setter", set, NULL);
214                         js_defproperty(J, -2, "__set", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
215                         js_pushstring(J, (const char *)type);
216                         js_defproperty(J, -2, "__type", JS_READONLY | JS_DONTENUM | JS_DONTCONF);
217                 }
218                 js_defaccessor(J, -3, name, JS_READONLY | JS_DONTCONF);
219         }
220         js_pop(J, 1);
221 }
222
223 void pdf_jsimp_set_global_type(pdf_jsimp *imp, pdf_jsimp_type *type)
224 {
225         js_State *J = imp->J;
226         const char *name;
227
228         js_getregistry(J, (const char *)type);
229         js_pushiterator(J, -1, 1);
230         while ((name = js_nextiterator(J, -1)))
231         {
232                 js_getproperty(J, -2, name);
233                 js_setglobal(J, name);
234         }
235 }
236
237 pdf_jsimp_obj *pdf_jsimp_new_obj(pdf_jsimp *imp, pdf_jsimp_type *type, void *natobj)
238 {
239         js_State *J = imp->J;
240         js_getregistry(J, (const char *)type);
241         js_newuserdata(J, (const char *)type, natobj, NULL);
242         return NEWOBJ(J, -1);
243 }
244
245 void pdf_jsimp_drop_obj(pdf_jsimp *imp, pdf_jsimp_obj *obj)
246 {
247 }
248
249 int pdf_jsimp_to_type(pdf_jsimp *imp, pdf_jsimp_obj *obj)
250 {
251         js_State *J = imp->J;
252         if (js_isnull(J, IDX(obj))) return JS_TYPE_NULL;
253         if (js_isboolean(J, IDX(obj))) return JS_TYPE_BOOLEAN;
254         if (js_isnumber(J, IDX(obj))) return JS_TYPE_NUMBER;
255         if (js_isstring(J, IDX(obj))) return JS_TYPE_STRING;
256         if (js_isarray(J, IDX(obj))) return JS_TYPE_ARRAY;
257         return JS_TYPE_UNKNOWN;
258 }
259
260 pdf_jsimp_obj *pdf_jsimp_from_string(pdf_jsimp *imp, char *str)
261 {
262         js_State *J = imp->J;
263         js_pushstring(J, str);
264         return NEWOBJ(J, -1);
265 }
266
267 char *pdf_jsimp_to_string(pdf_jsimp *imp, pdf_jsimp_obj *obj)
268 {
269         /* cast away const :( */
270         return (char*)js_tostring(imp->J, IDX(obj));
271 }
272
273 pdf_jsimp_obj *pdf_jsimp_from_number(pdf_jsimp *imp, double num)
274 {
275         js_State *J = imp->J;
276         js_pushnumber(J, num);
277         return NEWOBJ(J, -1);
278 }
279
280 double pdf_jsimp_to_number(pdf_jsimp *imp, pdf_jsimp_obj *obj)
281 {
282         return js_tonumber(imp->J, IDX(obj));
283 }
284
285 int pdf_jsimp_array_len(pdf_jsimp *imp, pdf_jsimp_obj *obj)
286 {
287         js_State *J = imp->J;
288         return js_getlength(J, IDX(obj));
289 }
290
291 pdf_jsimp_obj *pdf_jsimp_array_item(pdf_jsimp *imp, pdf_jsimp_obj *obj, int i)
292 {
293         js_State *J = imp->J;
294         js_getindex(J, IDX(obj), i);
295         return NEWOBJ(J, -1);
296 }
297
298 pdf_jsimp_obj *pdf_jsimp_property(pdf_jsimp *imp, pdf_jsimp_obj *obj, char *prop)
299 {
300         js_State *J = imp->J;
301         js_getproperty(J, IDX(obj), prop);
302         return NEWOBJ(J, -1);
303 }
304
305 void pdf_jsimp_execute(pdf_jsimp *imp, char *code)
306 {
307         js_State *J = imp->J;
308         js_dostring(J, code, 0);
309 }
310
311 void pdf_jsimp_execute_count(pdf_jsimp *imp, char *code, int count)
312 {
313         char *terminated = fz_malloc(imp->ctx, count+1);
314         memcpy(terminated, code, count);
315         terminated[count] = 0;
316         pdf_jsimp_execute(imp, terminated);
317         fz_free(imp->ctx, terminated);
318 }