comparison mupdf-source/platform/java/jni/nativedevice.c @ 3:2c135c81b16c

MERGE: upstream PyMuPDF 1.26.4 with MuPDF 1.26.7
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:44:09 +0200
parents b50eed0cc0ef
children
comparison
equal deleted inserted replaced
0:6015a75abc2d 3:2c135c81b16c
1 // Copyright (C) 2004-2024 Artifex Software, Inc.
2 //
3 // This file is part of MuPDF.
4 //
5 // MuPDF is free software: you can redistribute it and/or modify it under the
6 // terms of the GNU Affero General Public License as published by the Free
7 // Software Foundation, either version 3 of the License, or (at your option)
8 // any later version.
9 //
10 // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU Affero General Public License
16 // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
17 //
18 // Alternative licensing terms are available from the licensor.
19 // For commercial licensing, see <https://www.artifex.com/> or contact
20 // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
21 // CA 94129, USA, for further information.
22
23 /* Device interface */
24
25 typedef struct NativeDeviceInfo NativeDeviceInfo;
26
27 typedef int (NativeDeviceLockFn)(JNIEnv *env, NativeDeviceInfo *info);
28 typedef void (NativeDeviceUnlockFn)(JNIEnv *env, NativeDeviceInfo *info);
29
30 struct NativeDeviceInfo
31 {
32 /* Some devices (like the AndroidDrawDevice, or DrawDevice) need
33 * to lock/unlock the java object around device calls. We have functions
34 * here to do that. Other devices (like the DisplayList device) need
35 * no such locking, so these are NULL. */
36 NativeDeviceLockFn *lock; /* Function to lock */
37 NativeDeviceUnlockFn *unlock; /* Function to unlock */
38 jobject object; /* The java object that needs to be locked. */
39
40 /* Conceptually, we support drawing onto a 'plane' of pixels.
41 * The plane is width/height in size. The page is positioned on this
42 * at xOffset,yOffset. We want to redraw the given patch of this.
43 *
44 * The samples pointer in pixmap is updated on every lock/unlock, to
45 * cope with the object moving in memory.
46 */
47 fz_pixmap *pixmap;
48 int xOffset;
49 int yOffset;
50 int width;
51 int height;
52 };
53
54 static NativeDeviceInfo *lockNativeDevice(JNIEnv *env, jobject self, int *err)
55 {
56 NativeDeviceInfo *info = NULL;
57
58 *err = 0;
59 if (!(*env)->IsInstanceOf(env, self, cls_NativeDevice))
60 return NULL;
61
62 info = CAST(NativeDeviceInfo *, (*env)->GetLongField(env, self, fid_NativeDevice_nativeInfo));
63 if (!info)
64 {
65 /* Some devices (like the Displaylist device) need no locking, so have no info. */
66 return NULL;
67 }
68 info->object = (*env)->GetObjectField(env, self, fid_NativeDevice_nativeResource);
69
70 if (info->lock(env, info))
71 {
72 *err = 1;
73 return NULL;
74 }
75
76 return info;
77 }
78
79 static void unlockNativeDevice(JNIEnv *env, NativeDeviceInfo *info)
80 {
81 if (info)
82 info->unlock(env, info);
83 }
84
85 JNIEXPORT void JNICALL
86 FUN(NativeDevice_finalize)(JNIEnv *env, jobject self)
87 {
88 fz_context *ctx = get_context(env);
89 NativeDeviceInfo *ninfo;
90
91 if (!ctx) return;
92
93 FUN(Device_finalize)(env, self); /* Call super.finalize() */
94
95 ninfo = CAST(NativeDeviceInfo *, (*env)->GetLongField(env, self, fid_NativeDevice_nativeInfo));
96 if (ninfo)
97 {
98 fz_drop_pixmap(ctx, ninfo->pixmap);
99 fz_free(ctx, ninfo);
100 }
101
102 (*env)->SetLongField(env, self, fid_NativeDevice_nativeInfo, 0);
103 (*env)->SetObjectField(env, self, fid_NativeDevice_nativeResource, NULL);
104 }
105
106 JNIEXPORT void JNICALL
107 FUN(NativeDevice_close)(JNIEnv *env, jobject self)
108 {
109 fz_context *ctx = get_context(env);
110 fz_device *dev = from_Device(env, self);
111 NativeDeviceInfo *info;
112 int err;
113
114 if (!ctx || !dev) return;
115
116 info = lockNativeDevice(env, self, &err);
117 if (err)
118 return;
119 fz_try(ctx)
120 fz_close_device(ctx, dev);
121 fz_always(ctx)
122 unlockNativeDevice(env, info);
123 fz_catch(ctx)
124 jni_rethrow_void(env, ctx);
125 }
126 JNIEXPORT void JNICALL
127 FUN(NativeDevice_fillPath)(JNIEnv *env, jobject self, jobject jpath, jboolean even_odd, jobject jctm, jobject jcs, jfloatArray jcolor, jfloat alpha, jint jcp)
128 {
129 fz_context *ctx = get_context(env);
130 fz_device *dev = from_Device(env, self);
131 fz_path *path = from_Path(env, jpath);
132 fz_matrix ctm = from_Matrix(env, jctm);
133 fz_colorspace *cs = from_ColorSpace(env, jcs);
134 float color[FZ_MAX_COLORS];
135 NativeDeviceInfo *info;
136 fz_color_params cp = from_ColorParams_safe(env, jcp);
137 int err;
138
139 if (!ctx || !dev) return;
140 if (!path) jni_throw_arg_void(env, "path must not be null");
141 if (!from_jfloatArray(env, color, cs ? fz_colorspace_n(ctx, cs) : FZ_MAX_COLORS, jcolor)) return;
142
143 info = lockNativeDevice(env, self, &err);
144 if (err)
145 return;
146 fz_try(ctx)
147 fz_fill_path(ctx, dev, path, even_odd, ctm, cs, color, alpha, cp);
148 fz_always(ctx)
149 unlockNativeDevice(env, info);
150 fz_catch(ctx)
151 jni_rethrow_void(env, ctx);
152 }
153
154 JNIEXPORT void JNICALL
155 FUN(NativeDevice_strokePath)(JNIEnv *env, jobject self, jobject jpath, jobject jstroke, jobject jctm, jobject jcs, jfloatArray jcolor, jfloat alpha, jint jcp)
156 {
157 fz_context *ctx = get_context(env);
158 fz_device *dev = from_Device(env, self);
159 fz_path *path = from_Path(env, jpath);
160 fz_stroke_state *stroke = from_StrokeState(env, jstroke);
161 fz_matrix ctm = from_Matrix(env, jctm);
162 fz_colorspace *cs = from_ColorSpace(env, jcs);
163 fz_color_params cp = from_ColorParams_safe(env, jcp);
164 float color[FZ_MAX_COLORS];
165 NativeDeviceInfo *info;
166 int err;
167
168 if (!ctx || !dev) return;
169 if (!path) jni_throw_arg_void(env, "path must not be null");
170 if (!stroke) jni_throw_arg_void(env, "stroke must not be null");
171 if (!from_jfloatArray(env, color, cs ? fz_colorspace_n(ctx, cs) : FZ_MAX_COLORS, jcolor)) return;
172
173 info = lockNativeDevice(env, self, &err);
174 if (err)
175 return;
176 fz_try(ctx)
177 fz_stroke_path(ctx, dev, path, stroke, ctm, cs, color, alpha, cp);
178 fz_always(ctx)
179 unlockNativeDevice(env, info);
180 fz_catch(ctx)
181 jni_rethrow_void(env, ctx);
182 }
183
184 JNIEXPORT void JNICALL
185 FUN(NativeDevice_clipPath)(JNIEnv *env, jobject self, jobject jpath, jboolean even_odd, jobject jctm)
186 {
187 fz_context *ctx = get_context(env);
188 fz_device *dev = from_Device(env, self);
189 fz_path *path = from_Path(env, jpath);
190 fz_matrix ctm = from_Matrix(env, jctm);
191 NativeDeviceInfo *info;
192 int err;
193
194 if (!ctx || !dev) return;
195 if (!path) jni_throw_arg_void(env, "path must not be null");
196
197 info = lockNativeDevice(env, self, &err);
198 if (err)
199 return;
200 fz_try(ctx)
201 fz_clip_path(ctx, dev, path, even_odd, ctm, fz_infinite_rect);
202 fz_always(ctx)
203 unlockNativeDevice(env, info);
204 fz_catch(ctx)
205 jni_rethrow_void(env, ctx);
206 }
207
208 JNIEXPORT void JNICALL
209 FUN(NativeDevice_clipStrokePath)(JNIEnv *env, jobject self, jobject jpath, jobject jstroke, jobject jctm)
210 {
211 fz_context *ctx = get_context(env);
212 fz_device *dev = from_Device(env, self);
213 fz_path *path = from_Path(env, jpath);
214 fz_stroke_state *stroke = from_StrokeState(env, jstroke);
215 fz_matrix ctm = from_Matrix(env, jctm);
216 NativeDeviceInfo *info;
217 int err;
218
219 if (!ctx || !dev) return;
220 if (!path) jni_throw_arg_void(env, "path must not be null");
221 if (!stroke) jni_throw_arg_void(env, "stroke must not be null");
222
223 info = lockNativeDevice(env, self, &err);
224 if (err)
225 return;
226 fz_try(ctx)
227 fz_clip_stroke_path(ctx, dev, path, stroke, ctm, fz_infinite_rect);
228 fz_always(ctx)
229 unlockNativeDevice(env, info);
230 fz_catch(ctx)
231 jni_rethrow_void(env, ctx);
232 }
233
234 JNIEXPORT void JNICALL
235 FUN(NativeDevice_fillText)(JNIEnv *env, jobject self, jobject jtext, jobject jctm, jobject jcs, jfloatArray jcolor, jfloat alpha, jint jcp)
236 {
237 fz_context *ctx = get_context(env);
238 fz_device *dev = from_Device(env, self);
239 fz_text *text = from_Text(env, jtext);
240 fz_matrix ctm = from_Matrix(env, jctm);
241 fz_colorspace *cs = from_ColorSpace(env, jcs);
242 fz_color_params cp = from_ColorParams_safe(env, jcp);
243 float color[FZ_MAX_COLORS];
244 NativeDeviceInfo *info;
245 int err;
246
247 if (!ctx || !dev) return;
248 if (!text) jni_throw_arg_void(env, "text must not be null");
249 if (!from_jfloatArray(env, color, cs ? fz_colorspace_n(ctx, cs) : FZ_MAX_COLORS, jcolor)) return;
250
251 info = lockNativeDevice(env, self, &err);
252 if (err)
253 return;
254 fz_try(ctx)
255 fz_fill_text(ctx, dev, text, ctm, cs, color, alpha, cp);
256 fz_always(ctx)
257 unlockNativeDevice(env, info);
258 fz_catch(ctx)
259 jni_rethrow_void(env, ctx);
260 }
261
262 JNIEXPORT void JNICALL
263 FUN(NativeDevice_strokeText)(JNIEnv *env, jobject self, jobject jtext, jobject jstroke, jobject jctm, jobject jcs, jfloatArray jcolor, jfloat alpha, jint jcp)
264 {
265 fz_context *ctx = get_context(env);
266 fz_device *dev = from_Device(env, self);
267 fz_text *text = from_Text(env, jtext);
268 fz_stroke_state *stroke = from_StrokeState(env, jstroke);
269 fz_matrix ctm = from_Matrix(env, jctm);
270 fz_colorspace *cs = from_ColorSpace(env, jcs);
271 fz_color_params cp = from_ColorParams_safe(env, jcp);
272 float color[FZ_MAX_COLORS];
273 NativeDeviceInfo *info;
274 int err;
275
276 if (!ctx || !dev) return;
277 if (!text) jni_throw_arg_void(env, "text must not be null");
278 if (!stroke) jni_throw_arg_void(env, "stroke must not be null");
279 if (!from_jfloatArray(env, color, cs ? fz_colorspace_n(ctx, cs) : FZ_MAX_COLORS, jcolor)) return;
280
281 info = lockNativeDevice(env, self, &err);
282 if (err)
283 return;
284 fz_try(ctx)
285 fz_stroke_text(ctx, dev, text, stroke, ctm, cs, color, alpha, cp);
286 fz_always(ctx)
287 unlockNativeDevice(env, info);
288 fz_catch(ctx)
289 jni_rethrow_void(env, ctx);
290 }
291
292 JNIEXPORT void JNICALL
293 FUN(NativeDevice_clipText)(JNIEnv *env, jobject self, jobject jtext, jobject jctm)
294 {
295 fz_context *ctx = get_context(env);
296 fz_device *dev = from_Device(env, self);
297 fz_text *text = from_Text(env, jtext);
298 fz_matrix ctm = from_Matrix(env, jctm);
299 NativeDeviceInfo *info;
300 int err;
301
302 if (!ctx || !dev) return;
303 if (!text) jni_throw_arg_void(env, "text must not be null");
304
305 info = lockNativeDevice(env, self, &err);
306 if (err)
307 return;
308 fz_try(ctx)
309 fz_clip_text(ctx, dev, text, ctm, fz_infinite_rect);
310 fz_always(ctx)
311 unlockNativeDevice(env, info);
312 fz_catch(ctx)
313 jni_rethrow_void(env, ctx);
314 }
315
316 JNIEXPORT void JNICALL
317 FUN(NativeDevice_clipStrokeText)(JNIEnv *env, jobject self, jobject jtext, jobject jstroke, jobject jctm)
318 {
319 fz_context *ctx = get_context(env);
320 fz_device *dev = from_Device(env, self);
321 fz_text *text = from_Text(env, jtext);
322 fz_stroke_state *stroke = from_StrokeState(env, jstroke);
323 fz_matrix ctm = from_Matrix(env, jctm);
324 NativeDeviceInfo *info;
325 int err;
326
327 if (!ctx || !dev) return;
328 if (!text) jni_throw_arg_void(env, "text must not be null");
329 if (!stroke) jni_throw_arg_void(env, "stroke must not be null");
330
331 info = lockNativeDevice(env, self, &err);
332 if (err)
333 return;
334 fz_try(ctx)
335 fz_clip_stroke_text(ctx, dev, text, stroke, ctm, fz_infinite_rect);
336 fz_always(ctx)
337 unlockNativeDevice(env, info);
338 fz_catch(ctx)
339 jni_rethrow_void(env, ctx);
340 }
341
342 JNIEXPORT void JNICALL
343 FUN(NativeDevice_ignoreText)(JNIEnv *env, jobject self, jobject jtext, jobject jctm)
344 {
345 fz_context *ctx = get_context(env);
346 fz_device *dev = from_Device(env, self);
347 fz_text *text = from_Text(env, jtext);
348 fz_matrix ctm = from_Matrix(env, jctm);
349 NativeDeviceInfo *info;
350 int err;
351
352 if (!ctx || !dev) return;
353 if (!text) jni_throw_arg_void(env, "text must not be null");
354
355 info = lockNativeDevice(env, self, &err);
356 if (err)
357 return;
358 fz_try(ctx)
359 fz_ignore_text(ctx, dev, text, ctm);
360 fz_always(ctx)
361 unlockNativeDevice(env, info);
362 fz_catch(ctx)
363 jni_rethrow_void(env, ctx);
364 }
365
366 JNIEXPORT void JNICALL
367 FUN(NativeDevice_fillShade)(JNIEnv *env, jobject self, jobject jshd, jobject jctm, jfloat alpha, jint jcp)
368 {
369 fz_context *ctx = get_context(env);
370 fz_device *dev = from_Device(env, self);
371 fz_shade *shd = from_Shade(env, jshd);
372 fz_matrix ctm = from_Matrix(env, jctm);
373 fz_color_params cp = from_ColorParams_safe(env, jcp);
374 NativeDeviceInfo *info;
375 int err;
376
377 if (!ctx || !dev) return;
378 if (!shd) jni_throw_arg_void(env, "shade must not be null");
379
380 info = lockNativeDevice(env, self, &err);
381 if (err)
382 return;
383 fz_try(ctx)
384 fz_fill_shade(ctx, dev, shd, ctm, alpha, cp);
385 fz_always(ctx)
386 unlockNativeDevice(env, info);
387 fz_catch(ctx)
388 jni_rethrow_void(env, ctx);
389 }
390
391 JNIEXPORT void JNICALL
392 FUN(NativeDevice_fillImage)(JNIEnv *env, jobject self, jobject jimg, jobject jctm, jfloat alpha, jint jcp)
393 {
394 fz_context *ctx = get_context(env);
395 fz_device *dev = from_Device(env, self);
396 fz_image *img = from_Image(env, jimg);
397 fz_matrix ctm = from_Matrix(env, jctm);
398 fz_color_params cp = from_ColorParams_safe(env, jcp);
399 NativeDeviceInfo *info;
400 int err;
401
402 if (!ctx || !dev) return;
403 if (!img) jni_throw_arg_void(env, "image must not be null");
404
405 info = lockNativeDevice(env, self, &err);
406 if (err)
407 return;
408 fz_try(ctx)
409 fz_fill_image(ctx, dev, img, ctm, alpha, cp);
410 fz_always(ctx)
411 unlockNativeDevice(env, info);
412 fz_catch(ctx)
413 jni_rethrow_void(env, ctx);
414 }
415
416 JNIEXPORT void JNICALL
417 FUN(NativeDevice_fillImageMask)(JNIEnv *env, jobject self, jobject jimg, jobject jctm, jobject jcs, jfloatArray jcolor, jfloat alpha, jint jcp)
418 {
419 fz_context *ctx = get_context(env);
420 fz_device *dev = from_Device(env, self);
421 fz_image *img = from_Image(env, jimg);
422 fz_matrix ctm = from_Matrix(env, jctm);
423 fz_colorspace *cs = from_ColorSpace(env, jcs);
424 fz_color_params cp = from_ColorParams_safe(env, jcp);
425 float color[FZ_MAX_COLORS];
426 NativeDeviceInfo *info;
427 int err;
428
429 if (!ctx || !dev) return;
430 if (!img) jni_throw_arg_void(env, "image must not be null");
431 if (!from_jfloatArray(env, color, cs ? fz_colorspace_n(ctx, cs) : FZ_MAX_COLORS, jcolor)) return;
432
433 info = lockNativeDevice(env, self, &err);
434 if (err)
435 return;
436 fz_try(ctx)
437 fz_fill_image_mask(ctx, dev, img, ctm, cs, color, alpha, cp);
438 fz_always(ctx)
439 unlockNativeDevice(env, info);
440 fz_catch(ctx)
441 jni_rethrow_void(env, ctx);
442 }
443
444 JNIEXPORT void JNICALL
445 FUN(NativeDevice_clipImageMask)(JNIEnv *env, jobject self, jobject jimg, jobject jctm)
446 {
447 fz_context *ctx = get_context(env);
448 fz_device *dev = from_Device(env, self);
449 fz_image *img = from_Image(env, jimg);
450 fz_matrix ctm = from_Matrix(env, jctm);
451 NativeDeviceInfo *info;
452 int err;
453
454 if (!ctx || !dev) return;
455 if (!img) jni_throw_arg_void(env, "image must not be null");
456
457 info = lockNativeDevice(env, self, &err);
458 if (err)
459 return;
460 fz_try(ctx)
461 fz_clip_image_mask(ctx, dev, img, ctm, fz_infinite_rect);
462 fz_always(ctx)
463 unlockNativeDevice(env, info);
464 fz_catch(ctx)
465 jni_rethrow_void(env, ctx);
466 }
467
468 JNIEXPORT void JNICALL
469 FUN(NativeDevice_popClip)(JNIEnv *env, jobject self)
470 {
471 fz_context *ctx = get_context(env);
472 fz_device *dev = from_Device(env, self);
473 NativeDeviceInfo *info;
474 int err;
475
476 if (!ctx || !dev) return;
477
478 info = lockNativeDevice(env, self, &err);
479 if (err)
480 return;
481 fz_try(ctx)
482 fz_pop_clip(ctx, dev);
483 fz_always(ctx)
484 unlockNativeDevice(env, info);
485 fz_catch(ctx)
486 jni_rethrow_void(env, ctx);
487 }
488
489 JNIEXPORT void JNICALL
490 FUN(NativeDevice_beginLayer)(JNIEnv *env, jobject self, jstring jname)
491 {
492 fz_context *ctx = get_context(env);
493 fz_device *dev = from_Device(env, self);
494 NativeDeviceInfo *info;
495 const char *name;
496 int err;
497
498 if (!ctx || !dev) return;
499
500 if (jname)
501 {
502 name = (*env)->GetStringUTFChars(env, jname, NULL);
503 if (!name) return;
504 }
505
506 info = lockNativeDevice(env, self, &err);
507 if (err)
508 return;
509 fz_try(ctx)
510 fz_begin_layer(ctx, dev, name);
511 fz_always(ctx)
512 {
513 (*env)->ReleaseStringUTFChars(env, jname, name);
514 unlockNativeDevice(env, info);
515 }
516 fz_catch(ctx)
517 jni_rethrow_void(env, ctx);
518 }
519
520 JNIEXPORT void JNICALL
521 FUN(NativeDevice_endLayer)(JNIEnv *env, jobject self)
522 {
523 fz_context *ctx = get_context(env);
524 fz_device *dev = from_Device(env, self);
525 NativeDeviceInfo *info;
526 int err;
527
528 if (!ctx || !dev) return;
529
530 info = lockNativeDevice(env, self, &err);
531 if (err)
532 return;
533 fz_try(ctx)
534 fz_end_layer(ctx, dev);
535 fz_always(ctx)
536 unlockNativeDevice(env, info);
537 fz_catch(ctx)
538 jni_rethrow_void(env, ctx);
539 }
540
541 JNIEXPORT void JNICALL
542 FUN(NativeDevice_beginMask)(JNIEnv *env, jobject self, jobject jrect, jboolean luminosity, jobject jcs, jfloatArray jcolor, jint jcp)
543 {
544 fz_context *ctx = get_context(env);
545 fz_device *dev = from_Device(env, self);
546 fz_rect rect = from_Rect(env, jrect);
547 fz_colorspace *cs = from_ColorSpace(env, jcs);
548 fz_color_params cp = from_ColorParams_safe(env, jcp);
549 float color[FZ_MAX_COLORS];
550 NativeDeviceInfo *info;
551 int err;
552
553 if (!ctx || !dev) return;
554 if (!from_jfloatArray(env, color, cs ? fz_colorspace_n(ctx, cs) : FZ_MAX_COLORS, jcolor)) return;
555
556 info = lockNativeDevice(env, self, &err);
557 if (err)
558 return;
559 fz_try(ctx)
560 fz_begin_mask(ctx, dev, rect, luminosity, cs, color, cp);
561 fz_always(ctx)
562 unlockNativeDevice(env, info);
563 fz_catch(ctx)
564 jni_rethrow_void(env, ctx);
565 }
566
567 JNIEXPORT void JNICALL
568 FUN(NativeDevice_endMask)(JNIEnv *env, jobject self)
569 {
570 fz_context *ctx = get_context(env);
571 fz_device *dev = from_Device(env, self);
572 NativeDeviceInfo *info;
573 int err;
574
575 if (!ctx || !dev) return;
576
577 info = lockNativeDevice(env, self, &err);
578 if (err)
579 return;
580 fz_try(ctx)
581 fz_end_mask(ctx, dev);
582 fz_always(ctx)
583 unlockNativeDevice(env, info);
584 fz_catch(ctx)
585 jni_rethrow_void(env, ctx);
586 }
587
588 JNIEXPORT void JNICALL
589 FUN(NativeDevice_beginGroup)(JNIEnv *env, jobject self, jobject jrect, jobject jcs, jboolean isolated, jboolean knockout, jint blendmode, jfloat alpha)
590 {
591 fz_context *ctx = get_context(env);
592 fz_device *dev = from_Device(env, self);
593 fz_rect rect = from_Rect(env, jrect);
594 fz_colorspace *cs = from_ColorSpace(env, jcs);
595 NativeDeviceInfo *info;
596 int err;
597
598 if (!ctx || !dev) return;
599
600 info = lockNativeDevice(env, self, &err);
601 if (err)
602 return;
603 fz_try(ctx)
604 fz_begin_group(ctx, dev, rect, cs, isolated, knockout, blendmode, alpha);
605 fz_always(ctx)
606 unlockNativeDevice(env, info);
607 fz_catch(ctx)
608 jni_rethrow_void(env, ctx);
609 }
610
611 JNIEXPORT void JNICALL
612 FUN(NativeDevice_endGroup)(JNIEnv *env, jobject self)
613 {
614 fz_context *ctx = get_context(env);
615 fz_device *dev = from_Device(env, self);
616 NativeDeviceInfo *info;
617 int err;
618
619 if (!ctx || !dev) return;
620
621 info = lockNativeDevice(env, self, &err);
622 if (err)
623 return;
624 fz_try(ctx)
625 fz_end_group(ctx, dev);
626 fz_always(ctx)
627 unlockNativeDevice(env, info);
628 fz_catch(ctx)
629 jni_rethrow_void(env, ctx);
630 }
631
632 JNIEXPORT jint JNICALL
633 FUN(NativeDevice_beginTile)(JNIEnv *env, jobject self, jobject jarea, jobject jview, jfloat xstep, jfloat ystep, jobject jctm, jint id, jint doc_id)
634 {
635 fz_context *ctx = get_context(env);
636 fz_device *dev = from_Device(env, self);
637 fz_rect area = from_Rect(env, jarea);
638 fz_rect view = from_Rect(env, jview);
639 fz_matrix ctm = from_Matrix(env, jctm);
640 NativeDeviceInfo *info;
641 int i = 0;
642 int err;
643
644 if (!ctx || !dev) return 0;
645
646 info = lockNativeDevice(env, self, &err);
647 if (err)
648 return 0;
649 fz_try(ctx)
650 i = fz_begin_tile_tid(ctx, dev, area, view, xstep, ystep, ctm, id, doc_id);
651 fz_always(ctx)
652 unlockNativeDevice(env, info);
653 fz_catch(ctx)
654 jni_rethrow(env, ctx);
655
656 return i;
657 }
658
659 JNIEXPORT void JNICALL
660 FUN(NativeDevice_endTile)(JNIEnv *env, jobject self)
661 {
662 fz_context *ctx = get_context(env);
663 fz_device *dev = from_Device(env, self);
664 NativeDeviceInfo *info;
665 int err;
666
667 if (!ctx || !dev) return;
668
669 info = lockNativeDevice(env, self, &err);
670 if (err)
671 return;
672 fz_try(ctx)
673 fz_end_tile(ctx, dev);
674 fz_always(ctx)
675 unlockNativeDevice(env, info);
676 fz_catch(ctx)
677 jni_rethrow_void(env, ctx);
678 }
679
680 JNIEXPORT void JNICALL
681 FUN(NativeDevice_beginStructure)(JNIEnv *env, jobject self, jint standard, jstring jraw, jint idx)
682 {
683 fz_context *ctx = get_context(env);
684 fz_device *dev = from_Device(env, self);
685 NativeDeviceInfo *info;
686 const char *raw;
687 int err;
688
689 if (!ctx || !dev) return;
690
691 if (jraw)
692 {
693 raw = (*env)->GetStringUTFChars(env, jraw, NULL);
694 if (!raw) return;
695 }
696
697 info = lockNativeDevice(env, self, &err);
698 if (err)
699 return;
700 fz_try(ctx)
701 fz_begin_structure(ctx, dev, standard, raw, idx);
702 fz_always(ctx)
703 {
704 (*env)->ReleaseStringUTFChars(env, jraw, raw);
705 unlockNativeDevice(env, info);
706 }
707 fz_catch(ctx)
708 jni_rethrow_void(env, ctx);
709 }
710
711 JNIEXPORT void JNICALL
712 FUN(NativeDevice_endStructure)(JNIEnv *env, jobject self)
713 {
714 fz_context *ctx = get_context(env);
715 fz_device *dev = from_Device(env, self);
716 NativeDeviceInfo *info;
717 int err;
718
719 if (!ctx || !dev) return;
720
721 info = lockNativeDevice(env, self, &err);
722 if (err)
723 return;
724 fz_try(ctx)
725 fz_end_structure(ctx, dev);
726 fz_always(ctx)
727 unlockNativeDevice(env, info);
728 fz_catch(ctx)
729 jni_rethrow_void(env, ctx);
730 }
731
732 JNIEXPORT void JNICALL
733 FUN(NativeDevice_beginMetatext)(JNIEnv *env, jobject self, jint meta, jstring jtext)
734 {
735 fz_context *ctx = get_context(env);
736 fz_device *dev = from_Device(env, self);
737 NativeDeviceInfo *info;
738 const char *text;
739 int err;
740
741 if (!ctx || !dev) return;
742
743 if (jtext)
744 {
745 text = (*env)->GetStringUTFChars(env, jtext, NULL);
746 if (!text) return;
747 }
748
749 info = lockNativeDevice(env, self, &err);
750 if (err)
751 return;
752 fz_try(ctx)
753 fz_begin_metatext(ctx, dev, meta, text);
754 fz_always(ctx)
755 {
756 (*env)->ReleaseStringUTFChars(env, jtext, text);
757 unlockNativeDevice(env, info);
758 }
759 fz_catch(ctx)
760 jni_rethrow_void(env, ctx);
761 }
762
763 JNIEXPORT void JNICALL
764 FUN(NativeDevice_endMetatext)(JNIEnv *env, jobject self)
765 {
766 fz_context *ctx = get_context(env);
767 fz_device *dev = from_Device(env, self);
768 NativeDeviceInfo *info;
769 int err;
770
771 if (!ctx || !dev) return;
772
773 info = lockNativeDevice(env, self, &err);
774 if (err)
775 return;
776 fz_try(ctx)
777 fz_end_metatext(ctx, dev);
778 fz_always(ctx)
779 unlockNativeDevice(env, info);
780 fz_catch(ctx)
781 jni_rethrow_void(env, ctx);
782 }
783
784 JNIEXPORT void JNICALL
785 FUN(NativeDevice_renderFlags)(JNIEnv *env, jobject self, jint set, jint clear)
786 {
787 fz_context *ctx = get_context(env);
788 fz_device *dev = from_Device(env, self);
789 NativeDeviceInfo *info;
790 int err;
791
792 if (!ctx || !dev) return;
793
794 info = lockNativeDevice(env, self, &err);
795 if (err)
796 return;
797 fz_try(ctx)
798 fz_render_flags(ctx, dev, set, clear);
799 fz_always(ctx)
800 unlockNativeDevice(env, info);
801 fz_catch(ctx)
802 jni_rethrow_void(env, ctx);
803 }
804
805 JNIEXPORT void JNICALL
806 FUN(NativeDevice_setDefaultColorSpaces)(JNIEnv *env, jobject self, jobject jdcs)
807 {
808 fz_context *ctx = get_context(env);
809 fz_device *dev = from_Device(env, self);
810 fz_default_colorspaces *dcs = from_DefaultColorSpaces(env, jdcs);
811 NativeDeviceInfo *info;
812 int err;
813
814 if (!ctx || !dev) return;
815
816 info = lockNativeDevice(env, self, &err);
817 if (err)
818 return;
819 fz_try(ctx)
820 fz_set_default_colorspaces(ctx, dev, dcs);
821 fz_always(ctx)
822 unlockNativeDevice(env, info);
823 fz_catch(ctx)
824 jni_rethrow_void(env, ctx);
825 }