nativedevice.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  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. /* Device interface */
  23. typedef struct NativeDeviceInfo NativeDeviceInfo;
  24. typedef int (NativeDeviceLockFn)(JNIEnv *env, NativeDeviceInfo *info);
  25. typedef void (NativeDeviceUnlockFn)(JNIEnv *env, NativeDeviceInfo *info);
  26. struct NativeDeviceInfo
  27. {
  28. /* Some devices (like the AndroidDrawDevice, or DrawDevice) need
  29. * to lock/unlock the java object around device calls. We have functions
  30. * here to do that. Other devices (like the DisplayList device) need
  31. * no such locking, so these are NULL. */
  32. NativeDeviceLockFn *lock; /* Function to lock */
  33. NativeDeviceUnlockFn *unlock; /* Function to unlock */
  34. jobject object; /* The java object that needs to be locked. */
  35. /* Conceptually, we support drawing onto a 'plane' of pixels.
  36. * The plane is width/height in size. The page is positioned on this
  37. * at xOffset,yOffset. We want to redraw the given patch of this.
  38. *
  39. * The samples pointer in pixmap is updated on every lock/unlock, to
  40. * cope with the object moving in memory.
  41. */
  42. fz_pixmap *pixmap;
  43. int xOffset;
  44. int yOffset;
  45. int width;
  46. int height;
  47. };
  48. static NativeDeviceInfo *lockNativeDevice(JNIEnv *env, jobject self, int *err)
  49. {
  50. NativeDeviceInfo *info = NULL;
  51. *err = 0;
  52. if (!(*env)->IsInstanceOf(env, self, cls_NativeDevice))
  53. return NULL;
  54. info = CAST(NativeDeviceInfo *, (*env)->GetLongField(env, self, fid_NativeDevice_nativeInfo));
  55. if (!info)
  56. {
  57. /* Some devices (like the Displaylist device) need no locking, so have no info. */
  58. return NULL;
  59. }
  60. info->object = (*env)->GetObjectField(env, self, fid_NativeDevice_nativeResource);
  61. if (info->lock(env, info))
  62. {
  63. *err = 1;
  64. return NULL;
  65. }
  66. return info;
  67. }
  68. static void unlockNativeDevice(JNIEnv *env, NativeDeviceInfo *info)
  69. {
  70. if (info)
  71. info->unlock(env, info);
  72. }
  73. JNIEXPORT void JNICALL
  74. FUN(NativeDevice_finalize)(JNIEnv *env, jobject self)
  75. {
  76. fz_context *ctx = get_context(env);
  77. NativeDeviceInfo *ninfo;
  78. if (!ctx) return;
  79. FUN(Device_finalize)(env, self); /* Call super.finalize() */
  80. ninfo = CAST(NativeDeviceInfo *, (*env)->GetLongField(env, self, fid_NativeDevice_nativeInfo));
  81. if (ninfo)
  82. {
  83. fz_drop_pixmap(ctx, ninfo->pixmap);
  84. fz_free(ctx, ninfo);
  85. }
  86. (*env)->SetLongField(env, self, fid_NativeDevice_nativeInfo, 0);
  87. (*env)->SetObjectField(env, self, fid_NativeDevice_nativeResource, NULL);
  88. }
  89. JNIEXPORT void JNICALL
  90. FUN(NativeDevice_close)(JNIEnv *env, jobject self)
  91. {
  92. fz_context *ctx = get_context(env);
  93. fz_device *dev = from_Device(env, self);
  94. NativeDeviceInfo *info;
  95. int err;
  96. if (!ctx || !dev) return;
  97. info = lockNativeDevice(env, self, &err);
  98. if (err)
  99. return;
  100. fz_try(ctx)
  101. fz_close_device(ctx, dev);
  102. fz_always(ctx)
  103. unlockNativeDevice(env, info);
  104. fz_catch(ctx)
  105. jni_rethrow_void(env, ctx);
  106. }
  107. JNIEXPORT void JNICALL
  108. FUN(NativeDevice_fillPath)(JNIEnv *env, jobject self, jobject jpath, jboolean even_odd, jobject jctm, jobject jcs, jfloatArray jcolor, jfloat alpha, jint jcp)
  109. {
  110. fz_context *ctx = get_context(env);
  111. fz_device *dev = from_Device(env, self);
  112. fz_path *path = from_Path(env, jpath);
  113. fz_matrix ctm = from_Matrix(env, jctm);
  114. fz_colorspace *cs = from_ColorSpace(env, jcs);
  115. float color[FZ_MAX_COLORS];
  116. NativeDeviceInfo *info;
  117. fz_color_params cp = from_ColorParams_safe(env, jcp);
  118. int err;
  119. if (!ctx || !dev) return;
  120. if (!path) jni_throw_arg_void(env, "path must not be null");
  121. if (!from_jfloatArray(env, color, cs ? fz_colorspace_n(ctx, cs) : FZ_MAX_COLORS, jcolor)) return;
  122. info = lockNativeDevice(env, self, &err);
  123. if (err)
  124. return;
  125. fz_try(ctx)
  126. fz_fill_path(ctx, dev, path, even_odd, ctm, cs, color, alpha, cp);
  127. fz_always(ctx)
  128. unlockNativeDevice(env, info);
  129. fz_catch(ctx)
  130. jni_rethrow_void(env, ctx);
  131. }
  132. JNIEXPORT void JNICALL
  133. FUN(NativeDevice_strokePath)(JNIEnv *env, jobject self, jobject jpath, jobject jstroke, jobject jctm, jobject jcs, jfloatArray jcolor, jfloat alpha, jint jcp)
  134. {
  135. fz_context *ctx = get_context(env);
  136. fz_device *dev = from_Device(env, self);
  137. fz_path *path = from_Path(env, jpath);
  138. fz_stroke_state *stroke = from_StrokeState(env, jstroke);
  139. fz_matrix ctm = from_Matrix(env, jctm);
  140. fz_colorspace *cs = from_ColorSpace(env, jcs);
  141. fz_color_params cp = from_ColorParams_safe(env, jcp);
  142. float color[FZ_MAX_COLORS];
  143. NativeDeviceInfo *info;
  144. int err;
  145. if (!ctx || !dev) return;
  146. if (!path) jni_throw_arg_void(env, "path must not be null");
  147. if (!stroke) jni_throw_arg_void(env, "stroke must not be null");
  148. if (!from_jfloatArray(env, color, cs ? fz_colorspace_n(ctx, cs) : FZ_MAX_COLORS, jcolor)) return;
  149. info = lockNativeDevice(env, self, &err);
  150. if (err)
  151. return;
  152. fz_try(ctx)
  153. fz_stroke_path(ctx, dev, path, stroke, ctm, cs, color, alpha, cp);
  154. fz_always(ctx)
  155. unlockNativeDevice(env, info);
  156. fz_catch(ctx)
  157. jni_rethrow_void(env, ctx);
  158. }
  159. JNIEXPORT void JNICALL
  160. FUN(NativeDevice_clipPath)(JNIEnv *env, jobject self, jobject jpath, jboolean even_odd, jobject jctm)
  161. {
  162. fz_context *ctx = get_context(env);
  163. fz_device *dev = from_Device(env, self);
  164. fz_path *path = from_Path(env, jpath);
  165. fz_matrix ctm = from_Matrix(env, jctm);
  166. NativeDeviceInfo *info;
  167. int err;
  168. if (!ctx || !dev) return;
  169. if (!path) jni_throw_arg_void(env, "path must not be null");
  170. info = lockNativeDevice(env, self, &err);
  171. if (err)
  172. return;
  173. fz_try(ctx)
  174. fz_clip_path(ctx, dev, path, even_odd, ctm, fz_infinite_rect);
  175. fz_always(ctx)
  176. unlockNativeDevice(env, info);
  177. fz_catch(ctx)
  178. jni_rethrow_void(env, ctx);
  179. }
  180. JNIEXPORT void JNICALL
  181. FUN(NativeDevice_clipStrokePath)(JNIEnv *env, jobject self, jobject jpath, jobject jstroke, jobject jctm)
  182. {
  183. fz_context *ctx = get_context(env);
  184. fz_device *dev = from_Device(env, self);
  185. fz_path *path = from_Path(env, jpath);
  186. fz_stroke_state *stroke = from_StrokeState(env, jstroke);
  187. fz_matrix ctm = from_Matrix(env, jctm);
  188. NativeDeviceInfo *info;
  189. int err;
  190. if (!ctx || !dev) return;
  191. if (!path) jni_throw_arg_void(env, "path must not be null");
  192. if (!stroke) jni_throw_arg_void(env, "stroke must not be null");
  193. info = lockNativeDevice(env, self, &err);
  194. if (err)
  195. return;
  196. fz_try(ctx)
  197. fz_clip_stroke_path(ctx, dev, path, stroke, ctm, fz_infinite_rect);
  198. fz_always(ctx)
  199. unlockNativeDevice(env, info);
  200. fz_catch(ctx)
  201. jni_rethrow_void(env, ctx);
  202. }
  203. JNIEXPORT void JNICALL
  204. FUN(NativeDevice_fillText)(JNIEnv *env, jobject self, jobject jtext, jobject jctm, jobject jcs, jfloatArray jcolor, jfloat alpha, jint jcp)
  205. {
  206. fz_context *ctx = get_context(env);
  207. fz_device *dev = from_Device(env, self);
  208. fz_text *text = from_Text(env, jtext);
  209. fz_matrix ctm = from_Matrix(env, jctm);
  210. fz_colorspace *cs = from_ColorSpace(env, jcs);
  211. fz_color_params cp = from_ColorParams_safe(env, jcp);
  212. float color[FZ_MAX_COLORS];
  213. NativeDeviceInfo *info;
  214. int err;
  215. if (!ctx || !dev) return;
  216. if (!text) jni_throw_arg_void(env, "text must not be null");
  217. if (!from_jfloatArray(env, color, cs ? fz_colorspace_n(ctx, cs) : FZ_MAX_COLORS, jcolor)) return;
  218. info = lockNativeDevice(env, self, &err);
  219. if (err)
  220. return;
  221. fz_try(ctx)
  222. fz_fill_text(ctx, dev, text, ctm, cs, color, alpha, cp);
  223. fz_always(ctx)
  224. unlockNativeDevice(env, info);
  225. fz_catch(ctx)
  226. jni_rethrow_void(env, ctx);
  227. }
  228. JNIEXPORT void JNICALL
  229. FUN(NativeDevice_strokeText)(JNIEnv *env, jobject self, jobject jtext, jobject jstroke, jobject jctm, jobject jcs, jfloatArray jcolor, jfloat alpha, jint jcp)
  230. {
  231. fz_context *ctx = get_context(env);
  232. fz_device *dev = from_Device(env, self);
  233. fz_text *text = from_Text(env, jtext);
  234. fz_stroke_state *stroke = from_StrokeState(env, jstroke);
  235. fz_matrix ctm = from_Matrix(env, jctm);
  236. fz_colorspace *cs = from_ColorSpace(env, jcs);
  237. fz_color_params cp = from_ColorParams_safe(env, jcp);
  238. float color[FZ_MAX_COLORS];
  239. NativeDeviceInfo *info;
  240. int err;
  241. if (!ctx || !dev) return;
  242. if (!text) jni_throw_arg_void(env, "text must not be null");
  243. if (!stroke) jni_throw_arg_void(env, "stroke must not be null");
  244. if (!from_jfloatArray(env, color, cs ? fz_colorspace_n(ctx, cs) : FZ_MAX_COLORS, jcolor)) return;
  245. info = lockNativeDevice(env, self, &err);
  246. if (err)
  247. return;
  248. fz_try(ctx)
  249. fz_stroke_text(ctx, dev, text, stroke, ctm, cs, color, alpha, cp);
  250. fz_always(ctx)
  251. unlockNativeDevice(env, info);
  252. fz_catch(ctx)
  253. jni_rethrow_void(env, ctx);
  254. }
  255. JNIEXPORT void JNICALL
  256. FUN(NativeDevice_clipText)(JNIEnv *env, jobject self, jobject jtext, jobject jctm)
  257. {
  258. fz_context *ctx = get_context(env);
  259. fz_device *dev = from_Device(env, self);
  260. fz_text *text = from_Text(env, jtext);
  261. fz_matrix ctm = from_Matrix(env, jctm);
  262. NativeDeviceInfo *info;
  263. int err;
  264. if (!ctx || !dev) return;
  265. if (!text) jni_throw_arg_void(env, "text must not be null");
  266. info = lockNativeDevice(env, self, &err);
  267. if (err)
  268. return;
  269. fz_try(ctx)
  270. fz_clip_text(ctx, dev, text, ctm, fz_infinite_rect);
  271. fz_always(ctx)
  272. unlockNativeDevice(env, info);
  273. fz_catch(ctx)
  274. jni_rethrow_void(env, ctx);
  275. }
  276. JNIEXPORT void JNICALL
  277. FUN(NativeDevice_clipStrokeText)(JNIEnv *env, jobject self, jobject jtext, jobject jstroke, jobject jctm)
  278. {
  279. fz_context *ctx = get_context(env);
  280. fz_device *dev = from_Device(env, self);
  281. fz_text *text = from_Text(env, jtext);
  282. fz_stroke_state *stroke = from_StrokeState(env, jstroke);
  283. fz_matrix ctm = from_Matrix(env, jctm);
  284. NativeDeviceInfo *info;
  285. int err;
  286. if (!ctx || !dev) return;
  287. if (!text) jni_throw_arg_void(env, "text must not be null");
  288. if (!stroke) jni_throw_arg_void(env, "stroke must not be null");
  289. info = lockNativeDevice(env, self, &err);
  290. if (err)
  291. return;
  292. fz_try(ctx)
  293. fz_clip_stroke_text(ctx, dev, text, stroke, ctm, fz_infinite_rect);
  294. fz_always(ctx)
  295. unlockNativeDevice(env, info);
  296. fz_catch(ctx)
  297. jni_rethrow_void(env, ctx);
  298. }
  299. JNIEXPORT void JNICALL
  300. FUN(NativeDevice_ignoreText)(JNIEnv *env, jobject self, jobject jtext, jobject jctm)
  301. {
  302. fz_context *ctx = get_context(env);
  303. fz_device *dev = from_Device(env, self);
  304. fz_text *text = from_Text(env, jtext);
  305. fz_matrix ctm = from_Matrix(env, jctm);
  306. NativeDeviceInfo *info;
  307. int err;
  308. if (!ctx || !dev) return;
  309. if (!text) jni_throw_arg_void(env, "text must not be null");
  310. info = lockNativeDevice(env, self, &err);
  311. if (err)
  312. return;
  313. fz_try(ctx)
  314. fz_ignore_text(ctx, dev, text, ctm);
  315. fz_always(ctx)
  316. unlockNativeDevice(env, info);
  317. fz_catch(ctx)
  318. jni_rethrow_void(env, ctx);
  319. }
  320. JNIEXPORT void JNICALL
  321. FUN(NativeDevice_fillShade)(JNIEnv *env, jobject self, jobject jshd, jobject jctm, jfloat alpha, jint jcp)
  322. {
  323. fz_context *ctx = get_context(env);
  324. fz_device *dev = from_Device(env, self);
  325. fz_shade *shd = from_Shade(env, jshd);
  326. fz_matrix ctm = from_Matrix(env, jctm);
  327. fz_color_params cp = from_ColorParams_safe(env, jcp);
  328. NativeDeviceInfo *info;
  329. int err;
  330. if (!ctx || !dev) return;
  331. if (!shd) jni_throw_arg_void(env, "shade must not be null");
  332. info = lockNativeDevice(env, self, &err);
  333. if (err)
  334. return;
  335. fz_try(ctx)
  336. fz_fill_shade(ctx, dev, shd, ctm, alpha, cp);
  337. fz_always(ctx)
  338. unlockNativeDevice(env, info);
  339. fz_catch(ctx)
  340. jni_rethrow_void(env, ctx);
  341. }
  342. JNIEXPORT void JNICALL
  343. FUN(NativeDevice_fillImage)(JNIEnv *env, jobject self, jobject jimg, jobject jctm, jfloat alpha, jint jcp)
  344. {
  345. fz_context *ctx = get_context(env);
  346. fz_device *dev = from_Device(env, self);
  347. fz_image *img = from_Image(env, jimg);
  348. fz_matrix ctm = from_Matrix(env, jctm);
  349. fz_color_params cp = from_ColorParams_safe(env, jcp);
  350. NativeDeviceInfo *info;
  351. int err;
  352. if (!ctx || !dev) return;
  353. if (!img) jni_throw_arg_void(env, "image must not be null");
  354. info = lockNativeDevice(env, self, &err);
  355. if (err)
  356. return;
  357. fz_try(ctx)
  358. fz_fill_image(ctx, dev, img, ctm, alpha, cp);
  359. fz_always(ctx)
  360. unlockNativeDevice(env, info);
  361. fz_catch(ctx)
  362. jni_rethrow_void(env, ctx);
  363. }
  364. JNIEXPORT void JNICALL
  365. FUN(NativeDevice_fillImageMask)(JNIEnv *env, jobject self, jobject jimg, jobject jctm, jobject jcs, jfloatArray jcolor, jfloat alpha, jint jcp)
  366. {
  367. fz_context *ctx = get_context(env);
  368. fz_device *dev = from_Device(env, self);
  369. fz_image *img = from_Image(env, jimg);
  370. fz_matrix ctm = from_Matrix(env, jctm);
  371. fz_colorspace *cs = from_ColorSpace(env, jcs);
  372. fz_color_params cp = from_ColorParams_safe(env, jcp);
  373. float color[FZ_MAX_COLORS];
  374. NativeDeviceInfo *info;
  375. int err;
  376. if (!ctx || !dev) return;
  377. if (!img) jni_throw_arg_void(env, "image must not be null");
  378. if (!from_jfloatArray(env, color, cs ? fz_colorspace_n(ctx, cs) : FZ_MAX_COLORS, jcolor)) return;
  379. info = lockNativeDevice(env, self, &err);
  380. if (err)
  381. return;
  382. fz_try(ctx)
  383. fz_fill_image_mask(ctx, dev, img, ctm, cs, color, alpha, cp);
  384. fz_always(ctx)
  385. unlockNativeDevice(env, info);
  386. fz_catch(ctx)
  387. jni_rethrow_void(env, ctx);
  388. }
  389. JNIEXPORT void JNICALL
  390. FUN(NativeDevice_clipImageMask)(JNIEnv *env, jobject self, jobject jimg, jobject jctm)
  391. {
  392. fz_context *ctx = get_context(env);
  393. fz_device *dev = from_Device(env, self);
  394. fz_image *img = from_Image(env, jimg);
  395. fz_matrix ctm = from_Matrix(env, jctm);
  396. NativeDeviceInfo *info;
  397. int err;
  398. if (!ctx || !dev) return;
  399. if (!img) jni_throw_arg_void(env, "image must not be null");
  400. info = lockNativeDevice(env, self, &err);
  401. if (err)
  402. return;
  403. fz_try(ctx)
  404. fz_clip_image_mask(ctx, dev, img, ctm, fz_infinite_rect);
  405. fz_always(ctx)
  406. unlockNativeDevice(env, info);
  407. fz_catch(ctx)
  408. jni_rethrow_void(env, ctx);
  409. }
  410. JNIEXPORT void JNICALL
  411. FUN(NativeDevice_popClip)(JNIEnv *env, jobject self)
  412. {
  413. fz_context *ctx = get_context(env);
  414. fz_device *dev = from_Device(env, self);
  415. NativeDeviceInfo *info;
  416. int err;
  417. if (!ctx || !dev) return;
  418. info = lockNativeDevice(env, self, &err);
  419. if (err)
  420. return;
  421. fz_try(ctx)
  422. fz_pop_clip(ctx, dev);
  423. fz_always(ctx)
  424. unlockNativeDevice(env, info);
  425. fz_catch(ctx)
  426. jni_rethrow_void(env, ctx);
  427. }
  428. JNIEXPORT void JNICALL
  429. FUN(NativeDevice_beginLayer)(JNIEnv *env, jobject self, jstring jname)
  430. {
  431. fz_context *ctx = get_context(env);
  432. fz_device *dev = from_Device(env, self);
  433. NativeDeviceInfo *info;
  434. const char *name;
  435. int err;
  436. if (!ctx || !dev) return;
  437. if (jname)
  438. {
  439. name = (*env)->GetStringUTFChars(env, jname, NULL);
  440. if (!name) return;
  441. }
  442. info = lockNativeDevice(env, self, &err);
  443. if (err)
  444. return;
  445. fz_try(ctx)
  446. fz_begin_layer(ctx, dev, name);
  447. fz_always(ctx)
  448. {
  449. (*env)->ReleaseStringUTFChars(env, jname, name);
  450. unlockNativeDevice(env, info);
  451. }
  452. fz_catch(ctx)
  453. jni_rethrow_void(env, ctx);
  454. }
  455. JNIEXPORT void JNICALL
  456. FUN(NativeDevice_endLayer)(JNIEnv *env, jobject self)
  457. {
  458. fz_context *ctx = get_context(env);
  459. fz_device *dev = from_Device(env, self);
  460. NativeDeviceInfo *info;
  461. int err;
  462. if (!ctx || !dev) return;
  463. info = lockNativeDevice(env, self, &err);
  464. if (err)
  465. return;
  466. fz_try(ctx)
  467. fz_end_layer(ctx, dev);
  468. fz_always(ctx)
  469. unlockNativeDevice(env, info);
  470. fz_catch(ctx)
  471. jni_rethrow_void(env, ctx);
  472. }
  473. JNIEXPORT void JNICALL
  474. FUN(NativeDevice_beginMask)(JNIEnv *env, jobject self, jobject jrect, jboolean luminosity, jobject jcs, jfloatArray jcolor, jint jcp)
  475. {
  476. fz_context *ctx = get_context(env);
  477. fz_device *dev = from_Device(env, self);
  478. fz_rect rect = from_Rect(env, jrect);
  479. fz_colorspace *cs = from_ColorSpace(env, jcs);
  480. fz_color_params cp = from_ColorParams_safe(env, jcp);
  481. float color[FZ_MAX_COLORS];
  482. NativeDeviceInfo *info;
  483. int err;
  484. if (!ctx || !dev) return;
  485. if (!from_jfloatArray(env, color, cs ? fz_colorspace_n(ctx, cs) : FZ_MAX_COLORS, jcolor)) return;
  486. info = lockNativeDevice(env, self, &err);
  487. if (err)
  488. return;
  489. fz_try(ctx)
  490. fz_begin_mask(ctx, dev, rect, luminosity, cs, color, cp);
  491. fz_always(ctx)
  492. unlockNativeDevice(env, info);
  493. fz_catch(ctx)
  494. jni_rethrow_void(env, ctx);
  495. }
  496. JNIEXPORT void JNICALL
  497. FUN(NativeDevice_endMask)(JNIEnv *env, jobject self)
  498. {
  499. fz_context *ctx = get_context(env);
  500. fz_device *dev = from_Device(env, self);
  501. NativeDeviceInfo *info;
  502. int err;
  503. if (!ctx || !dev) return;
  504. info = lockNativeDevice(env, self, &err);
  505. if (err)
  506. return;
  507. fz_try(ctx)
  508. fz_end_mask(ctx, dev);
  509. fz_always(ctx)
  510. unlockNativeDevice(env, info);
  511. fz_catch(ctx)
  512. jni_rethrow_void(env, ctx);
  513. }
  514. JNIEXPORT void JNICALL
  515. FUN(NativeDevice_beginGroup)(JNIEnv *env, jobject self, jobject jrect, jobject jcs, jboolean isolated, jboolean knockout, jint blendmode, jfloat alpha)
  516. {
  517. fz_context *ctx = get_context(env);
  518. fz_device *dev = from_Device(env, self);
  519. fz_rect rect = from_Rect(env, jrect);
  520. fz_colorspace *cs = from_ColorSpace(env, jcs);
  521. NativeDeviceInfo *info;
  522. int err;
  523. if (!ctx || !dev) return;
  524. info = lockNativeDevice(env, self, &err);
  525. if (err)
  526. return;
  527. fz_try(ctx)
  528. fz_begin_group(ctx, dev, rect, cs, isolated, knockout, blendmode, alpha);
  529. fz_always(ctx)
  530. unlockNativeDevice(env, info);
  531. fz_catch(ctx)
  532. jni_rethrow_void(env, ctx);
  533. }
  534. JNIEXPORT void JNICALL
  535. FUN(NativeDevice_endGroup)(JNIEnv *env, jobject self)
  536. {
  537. fz_context *ctx = get_context(env);
  538. fz_device *dev = from_Device(env, self);
  539. NativeDeviceInfo *info;
  540. int err;
  541. if (!ctx || !dev) return;
  542. info = lockNativeDevice(env, self, &err);
  543. if (err)
  544. return;
  545. fz_try(ctx)
  546. fz_end_group(ctx, dev);
  547. fz_always(ctx)
  548. unlockNativeDevice(env, info);
  549. fz_catch(ctx)
  550. jni_rethrow_void(env, ctx);
  551. }
  552. JNIEXPORT jint JNICALL
  553. FUN(NativeDevice_beginTile)(JNIEnv *env, jobject self, jobject jarea, jobject jview, jfloat xstep, jfloat ystep, jobject jctm, jint id)
  554. {
  555. fz_context *ctx = get_context(env);
  556. fz_device *dev = from_Device(env, self);
  557. fz_rect area = from_Rect(env, jarea);
  558. fz_rect view = from_Rect(env, jview);
  559. fz_matrix ctm = from_Matrix(env, jctm);
  560. NativeDeviceInfo *info;
  561. int i = 0;
  562. int err;
  563. if (!ctx || !dev) return 0;
  564. info = lockNativeDevice(env, self, &err);
  565. if (err)
  566. return 0;
  567. fz_try(ctx)
  568. i = fz_begin_tile_id(ctx, dev, area, view, xstep, ystep, ctm, id);
  569. fz_always(ctx)
  570. unlockNativeDevice(env, info);
  571. fz_catch(ctx)
  572. jni_rethrow(env, ctx);
  573. return i;
  574. }
  575. JNIEXPORT void JNICALL
  576. FUN(NativeDevice_endTile)(JNIEnv *env, jobject self)
  577. {
  578. fz_context *ctx = get_context(env);
  579. fz_device *dev = from_Device(env, self);
  580. NativeDeviceInfo *info;
  581. int err;
  582. if (!ctx || !dev) return;
  583. info = lockNativeDevice(env, self, &err);
  584. if (err)
  585. return;
  586. fz_try(ctx)
  587. fz_end_tile(ctx, dev);
  588. fz_always(ctx)
  589. unlockNativeDevice(env, info);
  590. fz_catch(ctx)
  591. jni_rethrow_void(env, ctx);
  592. }
  593. JNIEXPORT void JNICALL
  594. FUN(NativeDevice_beginStructure)(JNIEnv *env, jobject self, jint standard, jstring jraw, jint idx)
  595. {
  596. fz_context *ctx = get_context(env);
  597. fz_device *dev = from_Device(env, self);
  598. NativeDeviceInfo *info;
  599. const char *raw;
  600. int err;
  601. if (!ctx || !dev) return;
  602. if (jraw)
  603. {
  604. raw = (*env)->GetStringUTFChars(env, jraw, NULL);
  605. if (!raw) return;
  606. }
  607. info = lockNativeDevice(env, self, &err);
  608. if (err)
  609. return;
  610. fz_try(ctx)
  611. fz_begin_structure(ctx, dev, standard, raw, idx);
  612. fz_always(ctx)
  613. {
  614. (*env)->ReleaseStringUTFChars(env, jraw, raw);
  615. unlockNativeDevice(env, info);
  616. }
  617. fz_catch(ctx)
  618. jni_rethrow_void(env, ctx);
  619. }
  620. JNIEXPORT void JNICALL
  621. FUN(NativeDevice_endStructure)(JNIEnv *env, jobject self)
  622. {
  623. fz_context *ctx = get_context(env);
  624. fz_device *dev = from_Device(env, self);
  625. NativeDeviceInfo *info;
  626. int err;
  627. if (!ctx || !dev) return;
  628. info = lockNativeDevice(env, self, &err);
  629. if (err)
  630. return;
  631. fz_try(ctx)
  632. fz_end_structure(ctx, dev);
  633. fz_always(ctx)
  634. unlockNativeDevice(env, info);
  635. fz_catch(ctx)
  636. jni_rethrow_void(env, ctx);
  637. }
  638. JNIEXPORT void JNICALL
  639. FUN(NativeDevice_beginMetatext)(JNIEnv *env, jobject self, jint meta, jstring jtext)
  640. {
  641. fz_context *ctx = get_context(env);
  642. fz_device *dev = from_Device(env, self);
  643. NativeDeviceInfo *info;
  644. const char *text;
  645. int err;
  646. if (!ctx || !dev) return;
  647. if (jtext)
  648. {
  649. text = (*env)->GetStringUTFChars(env, jtext, NULL);
  650. if (!text) return;
  651. }
  652. info = lockNativeDevice(env, self, &err);
  653. if (err)
  654. return;
  655. fz_try(ctx)
  656. fz_begin_metatext(ctx, dev, meta, text);
  657. fz_always(ctx)
  658. {
  659. (*env)->ReleaseStringUTFChars(env, jtext, text);
  660. unlockNativeDevice(env, info);
  661. }
  662. fz_catch(ctx)
  663. jni_rethrow_void(env, ctx);
  664. }
  665. JNIEXPORT void JNICALL
  666. FUN(NativeDevice_endMetatext)(JNIEnv *env, jobject self)
  667. {
  668. fz_context *ctx = get_context(env);
  669. fz_device *dev = from_Device(env, self);
  670. NativeDeviceInfo *info;
  671. int err;
  672. if (!ctx || !dev) return;
  673. info = lockNativeDevice(env, self, &err);
  674. if (err)
  675. return;
  676. fz_try(ctx)
  677. fz_end_metatext(ctx, dev);
  678. fz_always(ctx)
  679. unlockNativeDevice(env, info);
  680. fz_catch(ctx)
  681. jni_rethrow_void(env, ctx);
  682. }
  683. JNIEXPORT void JNICALL
  684. FUN(NativeDevice_renderFlags)(JNIEnv *env, jobject self, jint set, jint clear)
  685. {
  686. fz_context *ctx = get_context(env);
  687. fz_device *dev = from_Device(env, self);
  688. NativeDeviceInfo *info;
  689. int err;
  690. if (!ctx || !dev) return;
  691. info = lockNativeDevice(env, self, &err);
  692. if (err)
  693. return;
  694. fz_try(ctx)
  695. fz_render_flags(ctx, dev, set, clear);
  696. fz_always(ctx)
  697. unlockNativeDevice(env, info);
  698. fz_catch(ctx)
  699. jni_rethrow_void(env, ctx);
  700. }
  701. JNIEXPORT void JNICALL
  702. FUN(NativeDevice_setDefaultColorSpaces)(JNIEnv *env, jobject self, jobject jdcs)
  703. {
  704. fz_context *ctx = get_context(env);
  705. fz_device *dev = from_Device(env, self);
  706. fz_default_colorspaces *dcs = from_DefaultColorSpaces(env, jdcs);
  707. NativeDeviceInfo *info;
  708. int err;
  709. if (!ctx || !dev) return;
  710. info = lockNativeDevice(env, self, &err);
  711. if (err)
  712. return;
  713. fz_try(ctx)
  714. fz_set_default_colorspaces(ctx, dev, dcs);
  715. fz_always(ctx)
  716. unlockNativeDevice(env, info);
  717. fz_catch(ctx)
  718. jni_rethrow_void(env, ctx);
  719. }