1 /*
2 NOTE!
3 The JNI specification states that New<PrimitiveType>Array() do not
4 throw java exceptions, but many JVMs (e.g. Android's) treat them the
5 same way as NewObjectArray which may throw e.g. OutOfMemoryError.
6 So after calling these functions it is as important to call
7 ExceptionCheck() to check for exceptions as for functions that
8 are marked as throwing exceptions according to the JNI specification.
9 */
10
11 #include <jni.h>
12 #ifdef _WIN32
13 #include <windows.h>
14 #else
15 #include <pthread.h>
16 #endif
17
18 #include "mupdf/fitz.h"
19 #include "mupdf/ucdn.h"
20 #include "mupdf/pdf.h"
21
22 #include "mupdf_native.h" /* javah generated prototypes */
23
24 #include <assert.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #ifdef HAVE_ANDROID
30 #include <android/log.h>
31 #include <android/bitmap.h>
32 #define LOG_TAG "libmupdf"
33 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
34 #define LOGT(...) __android_log_print(ANDROID_LOG_INFO,"alert",__VA_ARGS__)
35 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
36 #else
37 #undef LOGI
38 #undef LOGE
39 #define LOGI(...) do{printf(__VA_ARGS__);putchar('\n');}while(0)
40 #define LOGE(...) do{printf(__VA_ARGS__);putchar('\n');}while(0)
41 #endif
42
43 #define MY_JNI_VERSION JNI_VERSION_1_6
44
45 #define FUN(A) Java_com_artifex_mupdf_fitz_ ## A
46 #define PKG "com/artifex/mupdf/fitz/"
47
48 /* Do our best to avoid type casting warnings. */
49
50 #define CAST(type, var) (type)pointer_cast(var)
51
pointer_cast(jlong l)52 static inline void *pointer_cast(jlong l)
53 {
54 return (void *)(intptr_t)l;
55 }
56
jlong_cast(const void * p)57 static inline jlong jlong_cast(const void *p)
58 {
59 return (jlong)(intptr_t)p;
60 }
61
62 /* Our VM */
63 static JavaVM *jvm = NULL;
64
65 /* All the cached classes/mids/fids we need. */
66
67 static jclass cls_Buffer;
68 static jclass cls_ColorSpace;
69 static jclass cls_Context_Version;
70 static jclass cls_Cookie;
71 static jclass cls_Device;
72 static jclass cls_DisplayList;
73 static jclass cls_Document;
74 static jclass cls_DocumentWriter;
75 static jclass cls_FitzInputStream;
76 static jclass cls_FloatArray;
77 static jclass cls_Font;
78 static jclass cls_IOException;
79 static jclass cls_IllegalArgumentException;
80 static jclass cls_Image;
81 static jclass cls_IndexOutOfBoundsException;
82 static jclass cls_IntegerArray;
83 static jclass cls_Link;
84 static jclass cls_Location;
85 static jclass cls_Matrix;
86 static jclass cls_NativeDevice;
87 static jclass cls_NullPointerException;
88 static jclass cls_Object;
89 static jclass cls_OutOfMemoryError;
90 static jclass cls_Outline;
91 static jclass cls_PDFAnnotation;
92 static jclass cls_PDFDocument;
93 static jclass cls_PDFDocument_JsEventListener;
94 static jclass cls_PDFGraftMap;
95 static jclass cls_PDFObject;
96 static jclass cls_PDFPage;
97 static jclass cls_Page;
98 static jclass cls_Path;
99 static jclass cls_PathWalker;
100 static jclass cls_Pixmap;
101 static jclass cls_Point;
102 static jclass cls_Quad;
103 static jclass cls_Rect;
104 static jclass cls_RuntimeException;
105 static jclass cls_SeekableInputStream;
106 static jclass cls_SeekableOutputStream;
107 static jclass cls_SeekableStream;
108 static jclass cls_Shade;
109 static jclass cls_String;
110 static jclass cls_StrokeState;
111 static jclass cls_StructuredText;
112 static jclass cls_StructuredTextWalker;
113 static jclass cls_Text;
114 static jclass cls_TextBlock;
115 static jclass cls_TextChar;
116 static jclass cls_TextLine;
117 static jclass cls_TextWalker;
118 static jclass cls_TryLaterException;
119 static jclass cls_UnsupportedOperationException;
120 static jclass cls_PDFWidget;
121 static jclass cls_PKCS7Signer;
122 static jclass cls_PKCS7Verifier;
123 static jclass cls_PKCS7DesignatedName;
124 static jclass cls_UnsupportedOperationException;
125
126 static jfieldID fid_Buffer_pointer;
127 static jfieldID fid_ColorSpace_pointer;
128 static jfieldID fid_Context_Version_major;
129 static jfieldID fid_Context_Version_minor;
130 static jfieldID fid_Context_Version_patch;
131 static jfieldID fid_Context_Version_version;
132 static jfieldID fid_Cookie_pointer;
133 static jfieldID fid_Device_pointer;
134 static jfieldID fid_DisplayList_pointer;
135 static jfieldID fid_DocumentWriter_pointer;
136 static jfieldID fid_Document_pointer;
137 static jfieldID fid_FitzInputStream_pointer;
138 static jfieldID fid_FitzInputStream_markpos;
139 static jfieldID fid_FitzInputStream_closed;
140 static jfieldID fid_Font_pointer;
141 static jfieldID fid_Image_pointer;
142 static jfieldID fid_Matrix_a;
143 static jfieldID fid_Matrix_b;
144 static jfieldID fid_Matrix_c;
145 static jfieldID fid_Matrix_d;
146 static jfieldID fid_Matrix_e;
147 static jfieldID fid_Matrix_f;
148 static jfieldID fid_NativeDevice_nativeInfo;
149 static jfieldID fid_NativeDevice_nativeResource;
150 static jfieldID fid_PDFAnnotation_pointer;
151 static jfieldID fid_PDFDocument_pointer;
152 static jfieldID fid_PDFGraftMap_pointer;
153 static jfieldID fid_PDFObject_Null;
154 static jfieldID fid_PDFObject_pointer;
155 static jfieldID fid_PDFPage_pointer;
156 static jfieldID fid_Page_pointer;
157 static jfieldID fid_Path_pointer;
158 static jfieldID fid_Pixmap_pointer;
159 static jfieldID fid_Point_x;
160 static jfieldID fid_Point_y;
161 static jfieldID fid_Quad_ul_x;
162 static jfieldID fid_Quad_ul_y;
163 static jfieldID fid_Quad_ur_x;
164 static jfieldID fid_Quad_ur_y;
165 static jfieldID fid_Quad_ll_x;
166 static jfieldID fid_Quad_ll_y;
167 static jfieldID fid_Quad_lr_x;
168 static jfieldID fid_Quad_lr_y;
169 static jfieldID fid_Rect_x0;
170 static jfieldID fid_Rect_x1;
171 static jfieldID fid_Rect_y0;
172 static jfieldID fid_Rect_y1;
173 static jfieldID fid_Shade_pointer;
174 static jfieldID fid_StrokeState_pointer;
175 static jfieldID fid_StructuredText_pointer;
176 static jfieldID fid_TextBlock_bbox;
177 static jfieldID fid_TextBlock_lines;
178 static jfieldID fid_TextChar_quad;
179 static jfieldID fid_TextChar_c;
180 static jfieldID fid_TextLine_bbox;
181 static jfieldID fid_TextLine_chars;
182 static jfieldID fid_Text_pointer;
183 static jfieldID fid_PDFWidget_fieldFlags;
184 static jfieldID fid_PDFWidget_fieldType;
185 static jfieldID fid_PDFWidget_maxLen;
186 static jfieldID fid_PDFWidget_options;
187 static jfieldID fid_PDFWidget_pointer;
188 static jfieldID fid_PDFWidget_textFormat;
189 static jfieldID fid_PKCS7DesignatedName_cn;
190 static jfieldID fid_PKCS7DesignatedName_c;
191 static jfieldID fid_PKCS7DesignatedName_o;
192 static jfieldID fid_PKCS7DesignatedName_ou;
193 static jfieldID fid_PKCS7DesignatedName_email;
194 static jfieldID fid_PKCS7Signer_pointer;
195 static jfieldID fid_PKCS7Verifier_pointer;
196
197 static jmethodID mid_ColorSpace_fromPointer;
198 static jmethodID mid_ColorSpace_init;
199 static jmethodID mid_Context_Version_init;
200 static jmethodID mid_Device_beginGroup;
201 static jmethodID mid_Device_beginLayer;
202 static jmethodID mid_Device_beginMask;
203 static jmethodID mid_Device_beginTile;
204 static jmethodID mid_Device_clipImageMask;
205 static jmethodID mid_Device_clipPath;
206 static jmethodID mid_Device_clipStrokePath;
207 static jmethodID mid_Device_clipStrokeText;
208 static jmethodID mid_Device_clipText;
209 static jmethodID mid_Device_endGroup;
210 static jmethodID mid_Device_endLayer;
211 static jmethodID mid_Device_endMask;
212 static jmethodID mid_Device_endTile;
213 static jmethodID mid_Device_fillImage;
214 static jmethodID mid_Device_fillImageMask;
215 static jmethodID mid_Device_fillPath;
216 static jmethodID mid_Device_fillShade;
217 static jmethodID mid_Device_fillText;
218 static jmethodID mid_Device_ignoreText;
219 static jmethodID mid_Device_init;
220 static jmethodID mid_Device_popClip;
221 static jmethodID mid_Device_strokePath;
222 static jmethodID mid_Device_strokeText;
223 static jmethodID mid_DisplayList_init;
224 static jmethodID mid_FitzInputStream_init;
225 static jmethodID mid_Document_init;
226 static jmethodID mid_Font_init;
227 static jmethodID mid_Image_init;
228 static jmethodID mid_Link_init;
229 static jmethodID mid_Location_init;
230 static jmethodID mid_Matrix_init;
231 static jmethodID mid_Object_toString;
232 static jmethodID mid_Outline_init;
233 static jmethodID mid_PDFAnnotation_init;
234 static jmethodID mid_PDFDocument_init;
235 static jmethodID mid_PDFDocument_JsEventListener_onAlert;
236 static jmethodID mid_PDFGraftMap_init;
237 static jmethodID mid_PDFObject_init;
238 static jmethodID mid_PDFPage_init;
239 static jmethodID mid_Page_init;
240 static jmethodID mid_PathWalker_closePath;
241 static jmethodID mid_PathWalker_curveTo;
242 static jmethodID mid_PathWalker_lineTo;
243 static jmethodID mid_PathWalker_moveTo;
244 static jmethodID mid_Path_init;
245 static jmethodID mid_Pixmap_init;
246 static jmethodID mid_Point_init;
247 static jmethodID mid_Quad_init;
248 static jmethodID mid_Rect_init;
249 static jmethodID mid_SeekableInputStream_read;
250 static jmethodID mid_SeekableOutputStream_write;
251 static jmethodID mid_SeekableStream_position;
252 static jmethodID mid_SeekableStream_seek;
253 static jmethodID mid_Shade_init;
254 static jmethodID mid_StrokeState_init;
255 static jmethodID mid_StructuredText_init;
256 static jmethodID mid_StructuredTextWalker_onImageBlock;
257 static jmethodID mid_StructuredTextWalker_beginTextBlock;
258 static jmethodID mid_StructuredTextWalker_endTextBlock;
259 static jmethodID mid_StructuredTextWalker_beginLine;
260 static jmethodID mid_StructuredTextWalker_endLine;
261 static jmethodID mid_StructuredTextWalker_onChar;
262 static jmethodID mid_TextBlock_init;
263 static jmethodID mid_TextChar_init;
264 static jmethodID mid_TextLine_init;
265 static jmethodID mid_TextWalker_showGlyph;
266 static jmethodID mid_Text_init;
267 static jmethodID mid_PDFWidget_init;
268 static jmethodID mid_PKCS7Signer_maxDigest;
269 static jmethodID mid_PKCS7Signer_name;
270 static jmethodID mid_PKCS7Signer_sign;
271 static jmethodID mid_PKCS7Verifier_checkCertificate;
272 static jmethodID mid_PKCS7Verifier_checkDigest;
273 static jmethodID mid_PKCS7DesignatedName_init;
274
275 #ifdef _WIN32
276 static DWORD context_key;
277 #else
278 static pthread_key_t context_key;
279 #endif
280 static fz_context *base_context;
281
check_enums()282 static int check_enums()
283 {
284 int valid = 1;
285
286 valid &= com_artifex_mupdf_fitz_Device_BLEND_NORMAL == FZ_BLEND_NORMAL;
287 valid &= com_artifex_mupdf_fitz_Device_BLEND_MULTIPLY == FZ_BLEND_MULTIPLY;
288 valid &= com_artifex_mupdf_fitz_Device_BLEND_SCREEN == FZ_BLEND_SCREEN;
289 valid &= com_artifex_mupdf_fitz_Device_BLEND_OVERLAY == FZ_BLEND_OVERLAY;
290 valid &= com_artifex_mupdf_fitz_Device_BLEND_DARKEN == FZ_BLEND_DARKEN;
291 valid &= com_artifex_mupdf_fitz_Device_BLEND_LIGHTEN == FZ_BLEND_LIGHTEN;
292 valid &= com_artifex_mupdf_fitz_Device_BLEND_COLOR_DODGE == FZ_BLEND_COLOR_DODGE;
293 valid &= com_artifex_mupdf_fitz_Device_BLEND_COLOR_BURN == FZ_BLEND_COLOR_BURN;
294 valid &= com_artifex_mupdf_fitz_Device_BLEND_HARD_LIGHT == FZ_BLEND_HARD_LIGHT;
295 valid &= com_artifex_mupdf_fitz_Device_BLEND_SOFT_LIGHT == FZ_BLEND_SOFT_LIGHT;
296 valid &= com_artifex_mupdf_fitz_Device_BLEND_DIFFERENCE == FZ_BLEND_DIFFERENCE;
297 valid &= com_artifex_mupdf_fitz_Device_BLEND_EXCLUSION == FZ_BLEND_EXCLUSION;
298 valid &= com_artifex_mupdf_fitz_Device_BLEND_HUE == FZ_BLEND_HUE;
299 valid &= com_artifex_mupdf_fitz_Device_BLEND_SATURATION == FZ_BLEND_SATURATION;
300 valid &= com_artifex_mupdf_fitz_Device_BLEND_COLOR == FZ_BLEND_COLOR;
301 valid &= com_artifex_mupdf_fitz_Device_BLEND_LUMINOSITY == FZ_BLEND_LUMINOSITY;
302
303 valid &= com_artifex_mupdf_fitz_Font_LATIN == PDF_SIMPLE_ENCODING_LATIN;
304 valid &= com_artifex_mupdf_fitz_Font_GREEK == PDF_SIMPLE_ENCODING_GREEK;
305 valid &= com_artifex_mupdf_fitz_Font_CYRILLIC == PDF_SIMPLE_ENCODING_CYRILLIC;
306
307 valid &= com_artifex_mupdf_fitz_Font_ADOBE_CNS == FZ_ADOBE_CNS;
308 valid &= com_artifex_mupdf_fitz_Font_ADOBE_GB == FZ_ADOBE_GB;
309 valid &= com_artifex_mupdf_fitz_Font_ADOBE_JAPAN == FZ_ADOBE_JAPAN;
310 valid &= com_artifex_mupdf_fitz_Font_ADOBE_KOREA == FZ_ADOBE_KOREA;
311
312 valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_NONE == PDF_ANNOT_LE_NONE;
313 valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_SQUARE == PDF_ANNOT_LE_SQUARE;
314 valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_CIRCLE == PDF_ANNOT_LE_CIRCLE;
315 valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_DIAMOND == PDF_ANNOT_LE_DIAMOND;
316 valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_OPEN_ARROW == PDF_ANNOT_LE_OPEN_ARROW;
317 valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_CLOSED_ARROW == PDF_ANNOT_LE_CLOSED_ARROW;
318 valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_BUTT == PDF_ANNOT_LE_BUTT;
319 valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_R_OPEN_ARROW == PDF_ANNOT_LE_R_OPEN_ARROW;
320 valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_R_CLOSED_ARROW == PDF_ANNOT_LE_R_CLOSED_ARROW;
321 valid &= com_artifex_mupdf_fitz_PDFAnnotation_LINE_ENDING_SLASH == PDF_ANNOT_LE_SLASH;
322
323 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_TEXT == PDF_ANNOT_TEXT;
324 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_LINK == PDF_ANNOT_LINK;
325 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_FREE_TEXT == PDF_ANNOT_FREE_TEXT;
326 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_LINE == PDF_ANNOT_LINE;
327 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_SQUARE == PDF_ANNOT_SQUARE;
328 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_CIRCLE == PDF_ANNOT_CIRCLE;
329 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_POLYGON == PDF_ANNOT_POLYGON;
330 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_POLY_LINE == PDF_ANNOT_POLY_LINE;
331 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_HIGHLIGHT == PDF_ANNOT_HIGHLIGHT;
332 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_UNDERLINE == PDF_ANNOT_UNDERLINE;
333 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_SQUIGGLY == PDF_ANNOT_SQUIGGLY;
334 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_STRIKE_OUT == PDF_ANNOT_STRIKE_OUT;
335 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_REDACT == PDF_ANNOT_REDACT;
336 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_STAMP == PDF_ANNOT_STAMP;
337 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_CARET == PDF_ANNOT_CARET;
338 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_INK == PDF_ANNOT_INK;
339 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_POPUP == PDF_ANNOT_POPUP;
340 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_FILE_ATTACHMENT == PDF_ANNOT_FILE_ATTACHMENT;
341 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_SOUND == PDF_ANNOT_SOUND;
342 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_MOVIE == PDF_ANNOT_MOVIE;
343 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_RICH_MEDIA == PDF_ANNOT_RICH_MEDIA;
344 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_WIDGET == PDF_ANNOT_WIDGET;
345 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_SCREEN == PDF_ANNOT_SCREEN;
346 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_PRINTER_MARK == PDF_ANNOT_PRINTER_MARK;
347 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_TRAP_NET == PDF_ANNOT_TRAP_NET;
348 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_WATERMARK == PDF_ANNOT_WATERMARK;
349 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_3D == PDF_ANNOT_3D;
350 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_PROJECTION == PDF_ANNOT_PROJECTION;
351 valid &= com_artifex_mupdf_fitz_PDFAnnotation_TYPE_UNKNOWN == PDF_ANNOT_UNKNOWN;
352
353 valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_INVISIBLE == PDF_ANNOT_IS_INVISIBLE;
354 valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_HIDDEN == PDF_ANNOT_IS_HIDDEN;
355 valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_PRINT == PDF_ANNOT_IS_PRINT;
356 valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_NO_ZOOM == PDF_ANNOT_IS_NO_ZOOM;
357 valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_NO_ROTATE == PDF_ANNOT_IS_NO_ROTATE;
358 valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_NO_VIEW == PDF_ANNOT_IS_NO_VIEW;
359 valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_READ_ONLY == PDF_ANNOT_IS_READ_ONLY;
360 valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_LOCKED == PDF_ANNOT_IS_LOCKED;
361 valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_TOGGLE_NO_VIEW == PDF_ANNOT_IS_TOGGLE_NO_VIEW;
362 valid &= com_artifex_mupdf_fitz_PDFAnnotation_IS_LOCKED_CONTENTS == PDF_ANNOT_IS_LOCKED_CONTENTS;
363
364 valid &= com_artifex_mupdf_fitz_StrokeState_LINE_CAP_BUTT == FZ_LINECAP_BUTT;
365 valid &= com_artifex_mupdf_fitz_StrokeState_LINE_CAP_ROUND == FZ_LINECAP_ROUND;
366 valid &= com_artifex_mupdf_fitz_StrokeState_LINE_CAP_SQUARE == FZ_LINECAP_SQUARE;
367 valid &= com_artifex_mupdf_fitz_StrokeState_LINE_CAP_TRIANGLE == FZ_LINECAP_TRIANGLE;
368
369 valid &= com_artifex_mupdf_fitz_StrokeState_LINE_JOIN_MITER == FZ_LINEJOIN_MITER;
370 valid &= com_artifex_mupdf_fitz_StrokeState_LINE_JOIN_ROUND == FZ_LINEJOIN_ROUND;
371 valid &= com_artifex_mupdf_fitz_StrokeState_LINE_JOIN_BEVEL == FZ_LINEJOIN_BEVEL;
372 valid &= com_artifex_mupdf_fitz_StrokeState_LINE_JOIN_MITER_XPS == FZ_LINEJOIN_MITER_XPS;
373
374 valid &= com_artifex_mupdf_fitz_StructuredText_SELECT_CHARS == FZ_SELECT_CHARS;
375 valid &= com_artifex_mupdf_fitz_StructuredText_SELECT_WORDS == FZ_SELECT_WORDS;
376 valid &= com_artifex_mupdf_fitz_StructuredText_SELECT_LINES == FZ_SELECT_LINES;
377
378 valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_UNKNOWN == PDF_WIDGET_TYPE_UNKNOWN;
379 valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_BUTTON == PDF_WIDGET_TYPE_BUTTON;
380 valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_CHECKBOX == PDF_WIDGET_TYPE_CHECKBOX;
381 valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_COMBOBOX == PDF_WIDGET_TYPE_COMBOBOX;
382 valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_LISTBOX == PDF_WIDGET_TYPE_LISTBOX;
383 valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_RADIOBUTTON == PDF_WIDGET_TYPE_RADIOBUTTON;
384 valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_SIGNATURE == PDF_WIDGET_TYPE_SIGNATURE;
385 valid &= com_artifex_mupdf_fitz_PDFWidget_TYPE_TEXT == PDF_WIDGET_TYPE_TEXT;
386
387 valid &= com_artifex_mupdf_fitz_PDFWidget_TX_FORMAT_NONE == PDF_WIDGET_TX_FORMAT_NONE;
388 valid &= com_artifex_mupdf_fitz_PDFWidget_TX_FORMAT_NUMBER == PDF_WIDGET_TX_FORMAT_NUMBER;
389 valid &= com_artifex_mupdf_fitz_PDFWidget_TX_FORMAT_SPECIAL == PDF_WIDGET_TX_FORMAT_SPECIAL;
390 valid &= com_artifex_mupdf_fitz_PDFWidget_TX_FORMAT_DATE == PDF_WIDGET_TX_FORMAT_DATE;
391 valid &= com_artifex_mupdf_fitz_PDFWidget_TX_FORMAT_TIME == PDF_WIDGET_TX_FORMAT_TIME;
392
393 valid &= com_artifex_mupdf_fitz_PDFPage_REDACT_IMAGE_NONE == PDF_REDACT_IMAGE_NONE;
394 valid &= com_artifex_mupdf_fitz_PDFPage_REDACT_IMAGE_REMOVE == PDF_REDACT_IMAGE_REMOVE;
395 valid &= com_artifex_mupdf_fitz_PDFPage_REDACT_IMAGE_PIXELS == PDF_REDACT_IMAGE_PIXELS;
396
397 return valid ? 1 : 0;
398 }
399
400 /* Helper functions to set the java exception flag. */
401
jni_throw_imp(JNIEnv * env,jclass cls,const char * mess)402 static void jni_throw_imp(JNIEnv *env, jclass cls, const char *mess)
403 {
404 (*env)->ThrowNew(env, cls, mess);
405 }
406
407 #define jni_throw_void(env, info) do { jni_throw_imp(env, info); return; }
408 #define jni_throw(env, info) do { jni_throw_imp(env, info); return 0; }
409
jni_rethrow_imp(JNIEnv * env,fz_context * ctx)410 static void jni_rethrow_imp(JNIEnv *env, fz_context *ctx)
411 {
412 if (fz_caught(ctx) == FZ_ERROR_TRYLATER)
413 jni_throw_imp(env, cls_TryLaterException, fz_caught_message(ctx));
414 else
415 jni_throw_imp(env, cls_RuntimeException, fz_caught_message(ctx));
416 }
417
418 #define jni_rethrow_void(env, ctx) do { jni_rethrow_imp(env, ctx); return; } while (0);
419 #define jni_rethrow(env, ctx) do { jni_rethrow_imp(env, ctx); return 0; } while (0);
420
jni_throw_run_imp(JNIEnv * env,const char * info)421 static void jni_throw_run_imp(JNIEnv *env, const char *info)
422 {
423 jni_throw_imp(env, cls_RuntimeException, info);
424 }
425
426 #define jni_throw_run_void(env, info) do { jni_throw_run_imp(env, info); return; } while (0);
427 #define jni_throw_run(env, info) do { jni_throw_run_imp(env, info); return 0; } while (0);
428
jni_throw_oom_imp(JNIEnv * env,const char * info)429 static void jni_throw_oom_imp(JNIEnv *env, const char *info)
430 {
431 jni_throw_imp(env, cls_OutOfMemoryError, info);
432 }
433
434 #define jni_throw_oom_void(env, info) do { jni_throw_oom_imp(env, info); return; } while (0);
435 #define jni_throw_oom(env, info) do { jni_throw_oom_imp(env, info); return 0; } while (0);
436
jni_throw_oob_imp(JNIEnv * env,const char * info)437 static void jni_throw_oob_imp(JNIEnv *env, const char *info)
438 {
439 jni_throw_imp(env, cls_IndexOutOfBoundsException, info);
440 }
441
442 #define jni_throw_oob_void(env, info) do { jni_throw_oob_imp(env, info); return; } while (0);
443 #define jni_throw_oob(env, info) do { jni_throw_oob_imp(env, info); return 0; } while (0);
444
jni_throw_arg_imp(JNIEnv * env,const char * info)445 static void jni_throw_arg_imp(JNIEnv *env, const char *info)
446 {
447 jni_throw_imp(env, cls_IllegalArgumentException, info);
448 }
449
450 #define jni_throw_arg_void(env, info) do { jni_throw_arg_imp(env, info); return; } while (0);
451 #define jni_throw_arg(env, info) do { jni_throw_arg_imp(env, info); return 0; } while (0);
452
jni_throw_io_imp(JNIEnv * env,const char * info)453 static void jni_throw_io_imp(JNIEnv *env, const char *info)
454 {
455 jni_throw_imp(env, cls_IOException, info);
456 }
457
458 #define jni_throw_io_void(env, info) do { jni_throw_io_imp(env, info); return; } while (0);
459 #define jni_throw_io(env, info) do { jni_throw_io_imp(env, info); return 0; } while (0);
460
jni_throw_null_imp(JNIEnv * env,const char * info)461 static void jni_throw_null_imp(JNIEnv *env, const char *info)
462 {
463 jni_throw_imp(env, cls_NullPointerException, info);
464 }
465
466 #define jni_throw_null_void(env, info) do { jni_throw_null_imp(env, info); return; } while (0);
467 #define jni_throw_null(env, info) do { jni_throw_null_imp(env, info); return 0; } while (0);
468
jni_throw_uoe_imp(JNIEnv * env,const char * info)469 static void jni_throw_uoe_imp(JNIEnv *env, const char *info)
470 {
471 jni_throw_imp(env, cls_UnsupportedOperationException, info);
472 }
473
474 #define jni_throw_uoe_void(env, info) do { jni_throw_uoe_imp(env, info); return; } while (0);
475 #define jni_throw_uoe(env, info) do { jni_throw_uoe_imp(env, info); return 0; } while (0);
476
477 /* Convert a java exception and throw into fitz. */
478
fz_throw_java_and_detach_thread(fz_context * ctx,JNIEnv * env,jboolean detach)479 static void fz_throw_java_and_detach_thread(fz_context *ctx, JNIEnv *env, jboolean detach)
480 {
481 jthrowable ex = (*env)->ExceptionOccurred(env);
482 if (ex)
483 {
484 jobject msg;
485 (*env)->ExceptionClear(env);
486 msg = (*env)->CallObjectMethod(env, ex, mid_Object_toString);
487 if ((*env)->ExceptionCheck(env))
488 (*env)->ExceptionClear(env);
489 else if (msg)
490 {
491 const char *p = (*env)->GetStringUTFChars(env, msg, NULL);
492 if (p)
493 {
494 char buf[256];
495 fz_strlcpy(buf, p, sizeof buf);
496 (*env)->ReleaseStringUTFChars(env, msg, p);
497 if (detach)
498 (*jvm)->DetachCurrentThread(jvm);
499 fz_throw(ctx, FZ_ERROR_GENERIC, "%s", buf);
500 }
501 }
502 }
503 if (detach)
504 (*jvm)->DetachCurrentThread(jvm);
505 fz_throw(ctx, FZ_ERROR_GENERIC, "unknown java error");
506 }
507
508 #define fz_throw_java(ctx, env) fz_throw_java_and_detach_thread((ctx), (env), JNI_FALSE)
509
510 #define fz_throw_and_detach_thread(ctx, detach, code, ...) \
511 do \
512 { \
513 if (detach) \
514 (*jvm)->DetachCurrentThread(jvm); \
515 fz_throw((ctx), (code), __VA_ARGS__); \
516 } while (0)
517
518 #define fz_rethrow_and_detach_thread(ctx, detach) \
519 do \
520 { \
521 if (detach) \
522 (*jvm)->DetachCurrentThread(jvm); \
523 fz_rethrow(ctx); \
524 } while (0)
525
526 typedef struct {
527 pdf_pkcs7_verifier base;
528 jobject jverifier;
529 } java_pkcs7_verifier;
530
531 /* Load classes, field and method IDs. */
532
533 static const char *current_class_name = NULL;
534 static jclass current_class = NULL;
535
get_class(int * failed,JNIEnv * env,const char * name)536 static jclass get_class(int *failed, JNIEnv *env, const char *name)
537 {
538 jclass local;
539
540 if (*failed) return NULL;
541
542 current_class_name = name;
543 local = (*env)->FindClass(env, name);
544 if (!local || (*env)->ExceptionCheck(env))
545 {
546 LOGI("Failed to find class %s", name);
547 *failed = 1;
548 return NULL;
549 }
550
551 current_class = (*env)->NewGlobalRef(env, local);
552 if (!current_class)
553 {
554 LOGI("Failed to make global ref for %s", name);
555 *failed = 1;
556 return NULL;
557 }
558
559 (*env)->DeleteLocalRef(env, local);
560
561 return current_class;
562 }
563
get_field(int * failed,JNIEnv * env,const char * field,const char * sig)564 static jfieldID get_field(int *failed, JNIEnv *env, const char *field, const char *sig)
565 {
566 jfieldID fid;
567
568 if (*failed || !current_class) return NULL;
569
570 fid = (*env)->GetFieldID(env, current_class, field, sig);
571 if (fid == 0 || (*env)->ExceptionCheck(env))
572 {
573 LOGI("Failed to get field for %s %s %s", current_class_name, field, sig);
574 *failed = 1;
575 }
576
577 return fid;
578 }
579
get_static_field(int * failed,JNIEnv * env,const char * field,const char * sig)580 static jfieldID get_static_field(int *failed, JNIEnv *env, const char *field, const char *sig)
581 {
582 jfieldID fid;
583
584 if (*failed || !current_class) return NULL;
585
586 fid = (*env)->GetStaticFieldID(env, current_class, field, sig);
587 if (fid == 0 || (*env)->ExceptionCheck(env))
588 {
589 LOGI("Failed to get static field for %s %s %s", current_class_name, field, sig);
590 *failed = 1;
591 }
592
593 return fid;
594 }
595
get_method(int * failed,JNIEnv * env,const char * method,const char * sig)596 static jmethodID get_method(int *failed, JNIEnv *env, const char *method, const char *sig)
597 {
598 jmethodID mid;
599
600 if (*failed || !current_class) return NULL;
601
602 mid = (*env)->GetMethodID(env, current_class, method, sig);
603 if (mid == 0 || (*env)->ExceptionCheck(env))
604 {
605 LOGI("Failed to get method for %s %s %s", current_class_name, method, sig);
606 *failed = 1;
607 }
608
609 return mid;
610 }
611
get_static_method(int * failed,JNIEnv * env,const char * method,const char * sig)612 static jmethodID get_static_method(int *failed, JNIEnv *env, const char *method, const char *sig)
613 {
614 jmethodID mid;
615
616 if (*failed || !current_class) return NULL;
617
618 mid = (*env)->GetStaticMethodID(env, current_class, method, sig);
619 if (mid == 0 || (*env)->ExceptionCheck(env))
620 {
621 LOGI("Failed to get static method for %s %s %s", current_class_name, method, sig);
622 *failed = 1;
623 }
624
625 return mid;
626 }
627
find_fids(JNIEnv * env)628 static int find_fids(JNIEnv *env)
629 {
630 int err = 0;
631 int getvmErr;
632
633 cls_Buffer = get_class(&err, env, PKG"Buffer");
634 fid_Buffer_pointer = get_field(&err, env, "pointer", "J");
635
636 cls_ColorSpace = get_class(&err, env, PKG"ColorSpace");
637 fid_ColorSpace_pointer = get_field(&err, env, "pointer", "J");
638 mid_ColorSpace_init = get_method(&err, env, "<init>", "(J)V");
639 mid_ColorSpace_fromPointer = get_static_method(&err, env, "fromPointer", "(J)L"PKG"ColorSpace;");
640
641 cls_Context_Version = get_class(&err, env, PKG"Context$Version");
642 mid_Context_Version_init = get_method(&err, env, "<init>", "(L"PKG"Context;)V");
643 fid_Context_Version_major = get_field(&err, env, "major", "I");
644 fid_Context_Version_minor = get_field(&err, env, "minor", "I");
645 fid_Context_Version_patch = get_field(&err, env, "patch", "I");
646 fid_Context_Version_version = get_field(&err, env, "version", "Ljava/lang/String;");
647
648 cls_Cookie = get_class(&err, env, PKG"Cookie");
649 fid_Cookie_pointer = get_field(&err, env, "pointer", "J");
650
651 cls_Device = get_class(&err, env, PKG"Device");
652 fid_Device_pointer = get_field(&err, env, "pointer", "J");
653 mid_Device_init = get_method(&err, env, "<init>", "(J)V");
654 mid_Device_fillPath = get_method(&err, env, "fillPath", "(L"PKG"Path;ZL"PKG"Matrix;L"PKG"ColorSpace;[FFI)V");
655 mid_Device_strokePath = get_method(&err, env, "strokePath", "(L"PKG"Path;L"PKG"StrokeState;L"PKG"Matrix;L"PKG"ColorSpace;[FFI)V");
656 mid_Device_clipPath = get_method(&err, env, "clipPath", "(L"PKG"Path;ZL"PKG"Matrix;)V");
657 mid_Device_clipStrokePath = get_method(&err, env, "clipStrokePath", "(L"PKG"Path;L"PKG"StrokeState;L"PKG"Matrix;)V");
658 mid_Device_fillText = get_method(&err, env, "fillText", "(L"PKG"Text;L"PKG"Matrix;L"PKG"ColorSpace;[FFI)V");
659 mid_Device_strokeText = get_method(&err, env, "strokeText", "(L"PKG"Text;L"PKG"StrokeState;L"PKG"Matrix;L"PKG"ColorSpace;[FFI)V");
660 mid_Device_clipText = get_method(&err, env, "clipText", "(L"PKG"Text;L"PKG"Matrix;)V");
661 mid_Device_clipStrokeText = get_method(&err, env, "clipStrokeText", "(L"PKG"Text;L"PKG"StrokeState;L"PKG"Matrix;)V");
662 mid_Device_ignoreText = get_method(&err, env, "ignoreText", "(L"PKG"Text;L"PKG"Matrix;)V");
663 mid_Device_fillShade = get_method(&err, env, "fillShade", "(L"PKG"Shade;L"PKG"Matrix;FI)V");
664 mid_Device_fillImage = get_method(&err, env, "fillImage", "(L"PKG"Image;L"PKG"Matrix;FI)V");
665 mid_Device_fillImageMask = get_method(&err, env, "fillImageMask", "(L"PKG"Image;L"PKG"Matrix;L"PKG"ColorSpace;[FFI)V");
666 mid_Device_clipImageMask = get_method(&err, env, "clipImageMask", "(L"PKG"Image;L"PKG"Matrix;)V");
667 mid_Device_popClip = get_method(&err, env, "popClip", "()V");
668 mid_Device_beginLayer = get_method(&err, env, "beginLayer", "(Ljava/lang/String;)V");
669 mid_Device_endLayer = get_method(&err, env, "endLayer", "()V");
670 mid_Device_beginMask = get_method(&err, env, "beginMask", "(L"PKG"Rect;ZL"PKG"ColorSpace;[FI)V");
671 mid_Device_endMask = get_method(&err, env, "endMask", "()V");
672 mid_Device_beginGroup = get_method(&err, env, "beginGroup", "(L"PKG"Rect;L"PKG"ColorSpace;ZZIF)V");
673 mid_Device_endGroup = get_method(&err, env, "endGroup", "()V");
674 mid_Device_beginTile = get_method(&err, env, "beginTile", "(L"PKG"Rect;L"PKG"Rect;FFL"PKG"Matrix;I)I");
675 mid_Device_endTile = get_method(&err, env, "endTile", "()V");
676
677 cls_DisplayList = get_class(&err, env, PKG"DisplayList");
678 fid_DisplayList_pointer = get_field(&err, env, "pointer", "J");
679 mid_DisplayList_init = get_method(&err, env, "<init>", "(J)V");
680
681 cls_Document = get_class(&err, env, PKG"Document");
682 fid_Document_pointer = get_field(&err, env, "pointer", "J");
683 mid_Document_init = get_method(&err, env, "<init>", "(J)V");
684
685 cls_DocumentWriter = get_class(&err, env, PKG"DocumentWriter");
686 fid_DocumentWriter_pointer = get_field(&err, env, "pointer", "J");
687
688 cls_FitzInputStream = get_class(&err, env, PKG"FitzInputStream");
689 fid_FitzInputStream_pointer = get_field(&err, env, "pointer", "J");
690 fid_FitzInputStream_markpos = get_field(&err, env, "markpos", "J");
691 fid_FitzInputStream_closed = get_field(&err, env, "closed", "Z");
692 mid_FitzInputStream_init = get_method(&err, env, "<init>", "(J)V");
693
694 cls_Font = get_class(&err, env, PKG"Font");
695 fid_Font_pointer = get_field(&err, env, "pointer", "J");
696 mid_Font_init = get_method(&err, env, "<init>", "(J)V");
697
698 cls_Image = get_class(&err, env, PKG"Image");
699 fid_Image_pointer = get_field(&err, env, "pointer", "J");
700 mid_Image_init = get_method(&err, env, "<init>", "(J)V");
701
702 cls_Link = get_class(&err, env, PKG"Link");
703 mid_Link_init = get_method(&err, env, "<init>", "(L"PKG"Rect;Ljava/lang/String;)V");
704
705 cls_Location = get_class(&err, env, PKG"Location");
706 mid_Location_init = get_method(&err, env, "<init>", "(IIFF)V");
707
708 cls_Matrix = get_class(&err, env, PKG"Matrix");
709 fid_Matrix_a = get_field(&err, env, "a", "F");
710 fid_Matrix_b = get_field(&err, env, "b", "F");
711 fid_Matrix_c = get_field(&err, env, "c", "F");
712 fid_Matrix_d = get_field(&err, env, "d", "F");
713 fid_Matrix_e = get_field(&err, env, "e", "F");
714 fid_Matrix_f = get_field(&err, env, "f", "F");
715 mid_Matrix_init = get_method(&err, env, "<init>", "(FFFFFF)V");
716
717 cls_NativeDevice = get_class(&err, env, PKG"NativeDevice");
718 fid_NativeDevice_nativeResource = get_field(&err, env, "nativeResource", "Ljava/lang/Object;");
719 fid_NativeDevice_nativeInfo = get_field(&err, env, "nativeInfo", "J");
720
721 cls_Outline = get_class(&err, env, PKG"Outline");
722 mid_Outline_init = get_method(&err, env, "<init>", "(Ljava/lang/String;Ljava/lang/String;[L"PKG"Outline;)V");
723
724 cls_Page = get_class(&err, env, PKG"Page");
725 fid_Page_pointer = get_field(&err, env, "pointer", "J");
726 mid_Page_init = get_method(&err, env, "<init>", "(J)V");
727
728 cls_Path = get_class(&err, env, PKG"Path");
729 fid_Path_pointer = get_field(&err, env, "pointer", "J");
730 mid_Path_init = get_method(&err, env, "<init>", "(J)V");
731
732 cls_PathWalker = get_class(&err, env, PKG"PathWalker");
733 mid_PathWalker_moveTo = get_method(&err, env, "moveTo", "(FF)V");
734 mid_PathWalker_lineTo = get_method(&err, env, "lineTo", "(FF)V");
735 mid_PathWalker_curveTo = get_method(&err, env, "curveTo", "(FFFFFF)V");
736 mid_PathWalker_closePath = get_method(&err, env, "closePath", "()V");
737
738 cls_PDFAnnotation = get_class(&err, env, PKG"PDFAnnotation");
739 fid_PDFAnnotation_pointer = get_field(&err, env, "pointer", "J");
740 mid_PDFAnnotation_init = get_method(&err, env, "<init>", "(J)V");
741
742 cls_PDFDocument = get_class(&err, env, PKG"PDFDocument");
743 fid_PDFDocument_pointer = get_field(&err, env, "pointer", "J");
744 mid_PDFDocument_init = get_method(&err, env, "<init>", "(J)V");
745
746 cls_PDFDocument_JsEventListener = get_class(&err, env, PKG"PDFDocument$JsEventListener");
747 mid_PDFDocument_JsEventListener_onAlert = get_method(&err, env, "onAlert", "(Ljava/lang/String;)V");
748
749 cls_PDFGraftMap = get_class(&err, env, PKG"PDFGraftMap");
750 fid_PDFGraftMap_pointer = get_field(&err, env, "pointer", "J");
751 mid_PDFGraftMap_init = get_method(&err, env, "<init>", "(J)V");
752
753 cls_PDFObject = get_class(&err, env, PKG"PDFObject");
754 fid_PDFObject_pointer = get_field(&err, env, "pointer", "J");
755 fid_PDFObject_Null = get_static_field(&err, env, "Null", "L"PKG"PDFObject;");
756 mid_PDFObject_init = get_method(&err, env, "<init>", "(J)V");
757
758 cls_PDFPage = get_class(&err, env, PKG"PDFPage");
759 fid_PDFPage_pointer = get_field(&err, env, "pointer", "J");
760 mid_PDFPage_init = get_method(&err, env, "<init>", "(J)V");
761
762 cls_Pixmap = get_class(&err, env, PKG"Pixmap");
763 fid_Pixmap_pointer = get_field(&err, env, "pointer", "J");
764 mid_Pixmap_init = get_method(&err, env, "<init>", "(J)V");
765
766 cls_Point = get_class(&err, env, PKG"Point");
767 mid_Point_init = get_method(&err, env, "<init>", "(FF)V");
768 fid_Point_x = get_field(&err, env, "x", "F");
769 fid_Point_y = get_field(&err, env, "y", "F");
770
771 cls_Quad = get_class(&err, env, PKG"Quad");
772 fid_Quad_ul_x = get_field(&err, env, "ul_x", "F");
773 fid_Quad_ul_y = get_field(&err, env, "ul_y", "F");
774 fid_Quad_ur_x = get_field(&err, env, "ur_x", "F");
775 fid_Quad_ur_y = get_field(&err, env, "ur_y", "F");
776 fid_Quad_ll_x = get_field(&err, env, "ll_x", "F");
777 fid_Quad_ll_y = get_field(&err, env, "ll_y", "F");
778 fid_Quad_lr_x = get_field(&err, env, "lr_x", "F");
779 fid_Quad_lr_y = get_field(&err, env, "lr_y", "F");
780 mid_Quad_init = get_method(&err, env, "<init>", "(FFFFFFFF)V");
781
782 cls_Rect = get_class(&err, env, PKG"Rect");
783 fid_Rect_x0 = get_field(&err, env, "x0", "F");
784 fid_Rect_x1 = get_field(&err, env, "x1", "F");
785 fid_Rect_y0 = get_field(&err, env, "y0", "F");
786 fid_Rect_y1 = get_field(&err, env, "y1", "F");
787 mid_Rect_init = get_method(&err, env, "<init>", "(FFFF)V");
788
789 cls_SeekableInputStream = get_class(&err, env, PKG"SeekableInputStream");
790 mid_SeekableInputStream_read = get_method(&err, env, "read", "([B)I");
791
792 cls_SeekableOutputStream = get_class(&err, env, PKG"SeekableOutputStream");
793 mid_SeekableOutputStream_write = get_method(&err, env, "write", "([BII)V");
794
795 cls_SeekableStream = get_class(&err, env, PKG"SeekableStream");
796 mid_SeekableStream_position = get_method(&err, env, "position", "()J");
797 mid_SeekableStream_seek = get_method(&err, env, "seek", "(JI)J");
798
799 cls_Shade = get_class(&err, env, PKG"Shade");
800 fid_Shade_pointer = get_field(&err, env, "pointer", "J");
801 mid_Shade_init = get_method(&err, env, "<init>", "(J)V");
802
803 cls_String = get_class(&err, env, "java/lang/String");
804
805 cls_StrokeState = get_class(&err, env, PKG"StrokeState");
806 fid_StrokeState_pointer = get_field(&err, env, "pointer", "J");
807 mid_StrokeState_init = get_method(&err, env, "<init>", "(J)V");
808
809 cls_StructuredText = get_class(&err, env, PKG"StructuredText");
810 fid_StructuredText_pointer = get_field(&err, env, "pointer", "J");
811 mid_StructuredText_init = get_method(&err, env, "<init>", "(J)V");
812
813 cls_StructuredTextWalker = get_class(&err, env, PKG"StructuredTextWalker");
814 mid_StructuredTextWalker_onImageBlock = get_method(&err, env, "onImageBlock", "(L"PKG"Rect;L"PKG"Matrix;L"PKG"Image;)V");
815 mid_StructuredTextWalker_beginTextBlock = get_method(&err, env, "beginTextBlock", "(L"PKG"Rect;)V");
816 mid_StructuredTextWalker_endTextBlock = get_method(&err, env, "endTextBlock", "()V");
817 mid_StructuredTextWalker_beginLine = get_method(&err, env, "beginLine", "(L"PKG"Rect;I)V");
818 mid_StructuredTextWalker_endLine = get_method(&err, env, "endLine", "()V");
819 mid_StructuredTextWalker_onChar = get_method(&err, env, "onChar", "(IL"PKG"Point;L"PKG"Font;FL"PKG"Quad;)V");
820
821 cls_Text = get_class(&err, env, PKG"Text");
822 fid_Text_pointer = get_field(&err, env, "pointer", "J");
823 mid_Text_init = get_method(&err, env, "<init>", "(J)V");
824
825 cls_TextBlock = get_class(&err, env, PKG"StructuredText$TextBlock");
826 mid_TextBlock_init = get_method(&err, env, "<init>", "(L"PKG"StructuredText;)V");
827 fid_TextBlock_bbox = get_field(&err, env, "bbox", "L"PKG"Rect;");
828 fid_TextBlock_lines = get_field(&err, env, "lines", "[L"PKG"StructuredText$TextLine;");
829
830 cls_TextChar = get_class(&err, env, PKG"StructuredText$TextChar");
831 mid_TextChar_init = get_method(&err, env, "<init>", "(L"PKG"StructuredText;)V");
832 fid_TextChar_quad = get_field(&err, env, "quad", "L"PKG"Quad;");
833 fid_TextChar_c = get_field(&err, env, "c", "I");
834
835 cls_TextLine = get_class(&err, env, PKG"StructuredText$TextLine");
836 mid_TextLine_init = get_method(&err, env, "<init>", "(L"PKG"StructuredText;)V");
837 fid_TextLine_bbox = get_field(&err, env, "bbox", "L"PKG"Rect;");
838 fid_TextLine_chars = get_field(&err, env, "chars", "[L"PKG"StructuredText$TextChar;");
839
840 cls_TextWalker = get_class(&err, env, PKG"TextWalker");
841 mid_TextWalker_showGlyph = get_method(&err, env, "showGlyph", "(L"PKG"Font;L"PKG"Matrix;IIZ)V");
842
843 cls_PDFWidget = get_class(&err, env, PKG"PDFWidget");
844 fid_PDFWidget_pointer = get_field(&err, env, "pointer", "J");
845 fid_PDFWidget_fieldType = get_field(&err, env, "fieldType", "I");
846 fid_PDFWidget_textFormat = get_field(&err, env, "textFormat", "I");
847 fid_PDFWidget_maxLen = get_field(&err, env, "maxLen", "I");
848 fid_PDFWidget_fieldFlags = get_field(&err, env, "fieldFlags", "I");
849 fid_PDFWidget_options = get_field(&err, env, "options", "[Ljava/lang/String;");
850 mid_PDFWidget_init = get_method(&err, env, "<init>", "(J)V");
851
852 cls_PKCS7Signer = get_class(&err, env, PKG"PKCS7Signer");
853 fid_PKCS7Signer_pointer = get_field(&err, env, "pointer", "J");
854 mid_PKCS7Signer_name = get_method(&err, env, "name", "()L"PKG"PKCS7DesignatedName;");
855 mid_PKCS7Signer_sign = get_method(&err, env, "sign", "(L"PKG"FitzInputStream;)[B");
856 mid_PKCS7Signer_maxDigest = get_method(&err, env, "maxDigest", "()I");
857
858 cls_PKCS7Verifier = get_class(&err, env, PKG"PKCS7Verifier");
859 fid_PKCS7Verifier_pointer = get_field(&err, env, "pointer", "J");
860 mid_PKCS7Verifier_checkCertificate = get_method(&err, env, "checkCertificate", "([B)I");
861 mid_PKCS7Verifier_checkDigest = get_method(&err, env, "checkDigest", "(L"PKG"FitzInputStream;[B)I");
862
863 cls_PKCS7DesignatedName = get_class(&err, env, PKG"PKCS7DesignatedName");
864 fid_PKCS7DesignatedName_cn = get_field(&err, env, "cn", "Ljava/lang/String;");
865 fid_PKCS7DesignatedName_c = get_field(&err, env, "c", "Ljava/lang/String;");
866 fid_PKCS7DesignatedName_o = get_field(&err, env, "o", "Ljava/lang/String;");
867 fid_PKCS7DesignatedName_ou = get_field(&err, env, "ou", "Ljava/lang/String;");
868 fid_PKCS7DesignatedName_email = get_field(&err, env, "email", "Ljava/lang/String;");
869 mid_PKCS7DesignatedName_init = get_method(&err, env, "<init>", "()V");
870
871 cls_TryLaterException = get_class(&err, env, PKG"TryLaterException");
872
873 /* Standard Java classes */
874
875 cls_FloatArray = get_class(&err, env, "[F");
876 cls_IntegerArray = get_class(&err, env, "[I");
877
878 cls_Object = get_class(&err, env, "java/lang/Object");
879 mid_Object_toString = get_method(&err, env, "toString", "()Ljava/lang/String;");
880
881 cls_IndexOutOfBoundsException = get_class(&err, env, "java/lang/IndexOutOfBoundsException");
882 cls_IllegalArgumentException = get_class(&err, env, "java/lang/IllegalArgumentException");
883 cls_IOException = get_class(&err, env, "java/io/IOException");
884 cls_NullPointerException = get_class(&err, env, "java/lang/NullPointerException");
885 cls_RuntimeException = get_class(&err, env, "java/lang/RuntimeException");
886 cls_UnsupportedOperationException = get_class(&err, env, "java/lang/UnsupportedOperationException");
887
888 cls_OutOfMemoryError = get_class(&err, env, "java/lang/OutOfMemoryError");
889
890 if (err)
891 {
892 LOGE("one or more class, member or field IDs could not be found");
893 return -1;
894 }
895
896 /* Get and store the main JVM pointer. We need this in order to get
897 * JNIEnv pointers on callback threads. This is specifically
898 * guaranteed to be safe to store in a static var. */
899
900 getvmErr = (*env)->GetJavaVM(env, &jvm);
901 if (getvmErr < 0)
902 {
903 LOGE("cannot get JVM interface (error %d)", getvmErr);
904 return -1;
905 }
906
907 return 0;
908 }
909
910 /* When making callbacks from C to java, we may be called on threads
911 * other than the foreground. As such, we have no JNIEnv. This function
912 * handles getting us the required environment */
jni_attach_thread(fz_context * ctx,jboolean * detach)913 static JNIEnv *jni_attach_thread(fz_context *ctx, jboolean *detach)
914 {
915 JNIEnv *env = NULL;
916 int state;
917
918 *detach = JNI_FALSE;
919 state = (*jvm)->GetEnv(jvm, (void *)&env, MY_JNI_VERSION);
920 if (state == JNI_EDETACHED)
921 {
922 *detach = JNI_TRUE;
923 state = (*jvm)->AttachCurrentThread(jvm, (void *)&env, NULL);
924 }
925
926 if (state != JNI_OK) return NULL;
927
928 return env;
929 }
930
jni_detach_thread(jboolean detach)931 static void jni_detach_thread(jboolean detach)
932 {
933 if (!detach) return;
934 (*jvm)->DetachCurrentThread(jvm);
935 }
936
lose_fids(JNIEnv * env)937 static void lose_fids(JNIEnv *env)
938 {
939 (*env)->DeleteGlobalRef(env, cls_Buffer);
940 (*env)->DeleteGlobalRef(env, cls_ColorSpace);
941 (*env)->DeleteGlobalRef(env, cls_Context_Version);
942 (*env)->DeleteGlobalRef(env, cls_Cookie);
943 (*env)->DeleteGlobalRef(env, cls_Device);
944 (*env)->DeleteGlobalRef(env, cls_DisplayList);
945 (*env)->DeleteGlobalRef(env, cls_Document);
946 (*env)->DeleteGlobalRef(env, cls_DocumentWriter);
947 (*env)->DeleteGlobalRef(env, cls_FitzInputStream);
948 (*env)->DeleteGlobalRef(env, cls_FloatArray);
949 (*env)->DeleteGlobalRef(env, cls_Font);
950 (*env)->DeleteGlobalRef(env, cls_IllegalArgumentException);
951 (*env)->DeleteGlobalRef(env, cls_Image);
952 (*env)->DeleteGlobalRef(env, cls_IndexOutOfBoundsException);
953 (*env)->DeleteGlobalRef(env, cls_IntegerArray);
954 (*env)->DeleteGlobalRef(env, cls_IOException);
955 (*env)->DeleteGlobalRef(env, cls_Link);
956 (*env)->DeleteGlobalRef(env, cls_Location);
957 (*env)->DeleteGlobalRef(env, cls_Matrix);
958 (*env)->DeleteGlobalRef(env, cls_NativeDevice);
959 (*env)->DeleteGlobalRef(env, cls_NullPointerException);
960 (*env)->DeleteGlobalRef(env, cls_Object);
961 (*env)->DeleteGlobalRef(env, cls_Outline);
962 (*env)->DeleteGlobalRef(env, cls_OutOfMemoryError);
963 (*env)->DeleteGlobalRef(env, cls_Page);
964 (*env)->DeleteGlobalRef(env, cls_Path);
965 (*env)->DeleteGlobalRef(env, cls_PathWalker);
966 (*env)->DeleteGlobalRef(env, cls_PDFAnnotation);
967 (*env)->DeleteGlobalRef(env, cls_PDFDocument);
968 (*env)->DeleteGlobalRef(env, cls_PDFDocument_JsEventListener);
969 (*env)->DeleteGlobalRef(env, cls_PDFPage);
970 (*env)->DeleteGlobalRef(env, cls_PDFGraftMap);
971 (*env)->DeleteGlobalRef(env, cls_PDFObject);
972 (*env)->DeleteGlobalRef(env, cls_Pixmap);
973 (*env)->DeleteGlobalRef(env, cls_Point);
974 (*env)->DeleteGlobalRef(env, cls_Quad);
975 (*env)->DeleteGlobalRef(env, cls_Rect);
976 (*env)->DeleteGlobalRef(env, cls_RuntimeException);
977 (*env)->DeleteGlobalRef(env, cls_SeekableStream);
978 (*env)->DeleteGlobalRef(env, cls_SeekableInputStream);
979 (*env)->DeleteGlobalRef(env, cls_SeekableOutputStream);
980 (*env)->DeleteGlobalRef(env, cls_Shade);
981 (*env)->DeleteGlobalRef(env, cls_String);
982 (*env)->DeleteGlobalRef(env, cls_StrokeState);
983 (*env)->DeleteGlobalRef(env, cls_StructuredText);
984 (*env)->DeleteGlobalRef(env, cls_StructuredTextWalker);
985 (*env)->DeleteGlobalRef(env, cls_Text);
986 (*env)->DeleteGlobalRef(env, cls_TextBlock);
987 (*env)->DeleteGlobalRef(env, cls_TextChar);
988 (*env)->DeleteGlobalRef(env, cls_TextLine);
989 (*env)->DeleteGlobalRef(env, cls_TextWalker);
990 (*env)->DeleteGlobalRef(env, cls_TryLaterException);
991 (*env)->DeleteGlobalRef(env, cls_UnsupportedOperationException);
992 (*env)->DeleteGlobalRef(env, cls_PDFWidget);
993 (*env)->DeleteGlobalRef(env, cls_PKCS7Signer);
994 (*env)->DeleteGlobalRef(env, cls_PKCS7Verifier);
995 (*env)->DeleteGlobalRef(env, cls_PKCS7DesignatedName);
996 }
997
998
999 JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM * vm,void * reserved)1000 JNI_OnLoad(JavaVM *vm, void *reserved)
1001 {
1002 JNIEnv *env;
1003 jint ret;
1004
1005 ret = (*vm)->GetEnv(vm, (void **)&env, MY_JNI_VERSION);
1006 if (ret != JNI_OK)
1007 {
1008 LOGE("cannot get JNI interface during load (error %d)", ret);
1009 return -1;
1010 }
1011
1012 return MY_JNI_VERSION;
1013 }
1014
JNI_OnUnload(JavaVM * vm,void * reserved)1015 JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
1016 {
1017 JNIEnv *env;
1018 jint ret;
1019
1020 ret = (*vm)->GetEnv(vm, (void **)&env, MY_JNI_VERSION);
1021 if (ret != JNI_OK)
1022 {
1023 /* If this fails, we're really in trouble! */
1024 LOGE("cannot get JNI interface during unload (error %d)", ret);
1025 return;
1026 }
1027
1028 fz_drop_context(base_context);
1029 base_context = NULL;
1030 lose_fids(env);
1031 }
1032
1033 #ifdef HAVE_ANDROID
1034 #include "jni/android/androidfonts.c"
1035 #endif
1036
1037 #include "jni/wrap.c"
1038
1039 #include "jni/context.c"
1040 #include "jni/device.c"
1041 #include "jni/nativedevice.c"
1042
1043 #include "jni/buffer.c"
1044 #include "jni/colorspace.c"
1045 #include "jni/cookie.c"
1046 #include "jni/displaylist.c"
1047 #include "jni/displaylistdevice.c"
1048 #include "jni/document.c"
1049 #include "jni/documentwriter.c"
1050 #include "jni/drawdevice.c"
1051 #include "jni/fitzinputstream.c"
1052 #include "jni/font.c"
1053 #include "jni/image.c"
1054 #include "jni/page.c"
1055 #include "jni/path.c"
1056 #include "jni/pdfannotation.c"
1057 #include "jni/pdfdocument.c"
1058 #include "jni/pdfgraftmap.c"
1059 #include "jni/pdfobject.c"
1060 #include "jni/pdfpage.c"
1061 #include "jni/pdfwidget.c"
1062 #include "jni/pixmap.c"
1063 #include "jni/pkcs7signer.c"
1064 #include "jni/pkcs7verifier.c"
1065 #include "jni/rect.c"
1066 #include "jni/shade.c"
1067 #include "jni/strokestate.c"
1068 #include "jni/structuredtext.c"
1069 #include "jni/text.c"
1070
1071 #ifdef HAVE_ANDROID
1072 #include "jni/android/androiddrawdevice.c"
1073 #include "jni/android/androidimage.c"
1074 #endif
1075