helpers.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988
  1. // Copyright (C) 2025 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. typedef struct {
  23. JNIEnv *env;
  24. jobject hits;
  25. int error;
  26. } search_state;
  27. static int hit_callback(fz_context *ctx, void *opaque, int quads, fz_quad *quad)
  28. {
  29. search_state *state = (search_state *) opaque;
  30. JNIEnv *env = state->env;
  31. jobjectArray arr;
  32. int i;
  33. jboolean changed = JNI_FALSE;
  34. arr = (*env)->NewObjectArray(env, quads, cls_Quad, NULL);
  35. if (!arr || (*env)->ExceptionCheck(env))
  36. {
  37. state->error = 1;
  38. return 1;
  39. }
  40. changed = (*env)->CallBooleanMethod(env, state->hits, mid_ArrayList_add, arr);
  41. if (!changed || (*env)->ExceptionCheck(env))
  42. {
  43. state->error = 1;
  44. return 1;
  45. }
  46. for (i = 0; i < quads; i++)
  47. {
  48. jobject jquad = to_Quad_safe(ctx, env, quad[i]);
  49. if (!jquad || (*env)->ExceptionCheck(env))
  50. {
  51. state->error = 1;
  52. return 1;
  53. }
  54. (*env)->SetObjectArrayElement(env, arr, i, jquad);
  55. if ((*env)->ExceptionCheck(env))
  56. {
  57. state->error = 1;
  58. return 1;
  59. }
  60. (*env)->DeleteLocalRef(env, jquad);
  61. }
  62. (*env)->DeleteLocalRef(env, arr);
  63. return 0;
  64. }
  65. typedef struct resources_stack
  66. {
  67. struct resources_stack *next;
  68. pdf_obj *resources;
  69. } resources_stack;
  70. typedef struct
  71. {
  72. pdf_processor super;
  73. resources_stack *rstack;
  74. int extgstate;
  75. JNIEnv *env;
  76. jobject self;
  77. } pdf_java_processor;
  78. #define PROC_BEGIN(OP) \
  79. jobject jproc = ((pdf_java_processor*) proc)->self; \
  80. jboolean detach = JNI_FALSE; \
  81. JNIEnv *env = jni_attach_thread(&detach); \
  82. if (env == NULL) \
  83. fz_throw(ctx, FZ_ERROR_GENERIC, "cannot attach to JVM in java_proc_%s", OP);
  84. #define PROC_END(N) \
  85. if ((*env)->ExceptionCheck(env)) \
  86. fz_throw_java_and_detach_thread(ctx, env, detach); \
  87. jni_detach_thread(detach);
  88. static int java_is_ascii(unsigned char *str, size_t len)
  89. {
  90. size_t i, is_ascii = 1;
  91. for (i = 0; i < len; ++i)
  92. if (str[i] == 0 || str[i] > 127)
  93. is_ascii = 0;
  94. return is_ascii;
  95. }
  96. static jstring java_to_string(JNIEnv *env, fz_context *ctx, unsigned char *str, size_t len)
  97. {
  98. jstring jstr = (*env)->NewStringUTF(env, (char *) str);
  99. if ((*env)->ExceptionCheck(env))
  100. return NULL;
  101. return jstr;
  102. }
  103. static jobject java_to_byte_array(JNIEnv *env, fz_context *ctx, unsigned char *str, size_t len)
  104. {
  105. size_t i;
  106. jobject jarray = (*env)->NewByteArray(env, len);
  107. if ((*env)->ExceptionCheck(env))
  108. return NULL;
  109. for (i = 0; i < len; ++i)
  110. {
  111. jbyte v = str[i];
  112. (*env)->SetByteArrayRegion(env, jarray, i, 1, &v);
  113. }
  114. return jarray;
  115. }
  116. static void java_proc_w(fz_context *ctx, pdf_processor *proc, float linewidth)
  117. {
  118. PROC_BEGIN("w");
  119. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_w, linewidth);
  120. PROC_END("w");
  121. }
  122. static void java_proc_j(fz_context *ctx, pdf_processor *proc, int linejoin)
  123. {
  124. PROC_BEGIN("j");
  125. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_j, linejoin);
  126. PROC_END("j");
  127. }
  128. static void java_proc_J(fz_context *ctx, pdf_processor *proc, int linecap)
  129. {
  130. PROC_BEGIN("J");
  131. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_J, linecap);
  132. PROC_END("J");
  133. }
  134. static void java_proc_M(fz_context *ctx, pdf_processor *proc, float miterlimit)
  135. {
  136. PROC_BEGIN("M");
  137. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_M, miterlimit);
  138. PROC_END("M");
  139. }
  140. static void java_proc_d(fz_context *ctx, pdf_processor *proc, pdf_obj *array_, float phase)
  141. {
  142. jfloatArray jarray;
  143. int i, n;
  144. PROC_BEGIN("d");
  145. n = pdf_array_len(ctx, array_);
  146. jarray = (*env)->NewFloatArray(env, n);
  147. if ((*env)->ExceptionCheck(env))
  148. fz_throw_java_and_detach_thread(ctx, env, detach);
  149. if (!jarray)
  150. fz_throw(ctx, FZ_ERROR_GENERIC, "cannot allocate float array");
  151. for (i = 0; i < n; i++)
  152. {
  153. float v = pdf_array_get_real(ctx, array_, i);
  154. (*env)->SetFloatArrayRegion(env, jarray, i, 1, &v);
  155. if ((*env)->ExceptionCheck(env))
  156. fz_throw_java_and_detach_thread(ctx, env, detach);
  157. }
  158. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_d, jarray, phase);
  159. (*env)->DeleteLocalRef(env, jarray);
  160. PROC_END("d");
  161. }
  162. static void java_proc_ri(fz_context *ctx, pdf_processor *proc, const char *intent)
  163. {
  164. PROC_BEGIN("i");
  165. jstring jintent = (*env)->NewStringUTF(env, intent);
  166. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_ri, jintent);
  167. (*env)->DeleteLocalRef(env, jintent);
  168. PROC_END("i");
  169. }
  170. static void java_proc_i(fz_context *ctx, pdf_processor *proc, float flatness)
  171. {
  172. PROC_BEGIN("i");
  173. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_i, flatness);
  174. PROC_END("i");
  175. }
  176. static void java_proc_gs_begin(fz_context *ctx, pdf_processor *proc, const char *name, pdf_obj *extgstate)
  177. {
  178. PROC_BEGIN("gs");
  179. ((pdf_java_processor*)proc)->extgstate = 1;
  180. jstring jname = (*env)->NewStringUTF(env, name);
  181. jobject jextgstate = to_PDFObject_safe(ctx, env, extgstate);
  182. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_gs, jname, jextgstate);
  183. (*env)->DeleteLocalRef(env, jextgstate);
  184. (*env)->DeleteLocalRef(env, jname);
  185. PROC_END("gs");
  186. }
  187. static void java_proc_gs_end(fz_context *ctx, pdf_processor *proc)
  188. {
  189. ((pdf_java_processor*)proc)->extgstate = 0;
  190. }
  191. static void java_proc_q(fz_context *ctx, pdf_processor *proc)
  192. {
  193. PROC_BEGIN("q");
  194. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_q);
  195. PROC_END("q");
  196. }
  197. static void java_proc_Q(fz_context *ctx, pdf_processor *proc)
  198. {
  199. PROC_BEGIN("Q");
  200. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_q);
  201. PROC_END("Q");
  202. }
  203. static void java_proc_cm(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f)
  204. {
  205. PROC_BEGIN("cm");
  206. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_cm, a, b, c, d, e, f);
  207. PROC_END("cm");
  208. }
  209. static void java_proc_m(fz_context *ctx, pdf_processor *proc, float x, float y)
  210. {
  211. PROC_BEGIN("m");
  212. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_m, x, y);
  213. PROC_END("m");
  214. }
  215. static void java_proc_l(fz_context *ctx, pdf_processor *proc, float x, float y)
  216. {
  217. PROC_BEGIN("l");
  218. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_l, x, y);
  219. PROC_END("l");
  220. }
  221. static void java_proc_c(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x2, float y2, float x3, float y3)
  222. {
  223. PROC_BEGIN("c");
  224. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_c, x1, y1, x2, y2, x3, y3);
  225. PROC_END("c");
  226. }
  227. static void java_proc_v(fz_context *ctx, pdf_processor *proc, float x2, float y2, float x3, float y3)
  228. {
  229. PROC_BEGIN("v");
  230. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_v, x2, y2, x3, y3);
  231. PROC_END("v");
  232. }
  233. static void java_proc_y(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x3, float y3)
  234. {
  235. PROC_BEGIN("y");
  236. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_y, x1, y1, x3, y3);
  237. PROC_END("y");
  238. }
  239. static void java_proc_h(fz_context *ctx, pdf_processor *proc)
  240. {
  241. PROC_BEGIN("h");
  242. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_h);
  243. PROC_END("h");
  244. }
  245. static void java_proc_re(fz_context *ctx, pdf_processor *proc, float x, float y, float w, float h)
  246. {
  247. PROC_BEGIN("re");
  248. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_re, x, y, w, h);
  249. PROC_END("re");
  250. }
  251. static void java_proc_S(fz_context *ctx, pdf_processor *proc)
  252. {
  253. PROC_BEGIN("S");
  254. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_S);
  255. PROC_END("S");
  256. }
  257. static void java_proc_s(fz_context *ctx, pdf_processor *proc)
  258. {
  259. PROC_BEGIN("s");
  260. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_s);
  261. PROC_END("s");
  262. }
  263. static void java_proc_F(fz_context *ctx, pdf_processor *proc)
  264. {
  265. PROC_BEGIN("F");
  266. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_F);
  267. PROC_END("F");
  268. }
  269. static void java_proc_f(fz_context *ctx, pdf_processor *proc)
  270. {
  271. PROC_BEGIN("f");
  272. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_f);
  273. PROC_END("f");
  274. }
  275. static void java_proc_fstar(fz_context *ctx, pdf_processor *proc)
  276. {
  277. PROC_BEGIN("fstar");
  278. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_fstar);
  279. PROC_END("fstar");
  280. }
  281. static void java_proc_B(fz_context *ctx, pdf_processor *proc)
  282. {
  283. PROC_BEGIN("B");
  284. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_B);
  285. PROC_END("B");
  286. }
  287. static void java_proc_Bstar(fz_context *ctx, pdf_processor *proc)
  288. {
  289. PROC_BEGIN("Bstar");
  290. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Bstar);
  291. PROC_END("Bstar");
  292. }
  293. static void java_proc_b(fz_context *ctx, pdf_processor *proc)
  294. {
  295. PROC_BEGIN("b");
  296. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_b);
  297. PROC_END("b");
  298. }
  299. static void java_proc_bstar(fz_context *ctx, pdf_processor *proc)
  300. {
  301. PROC_BEGIN("bstar");
  302. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_bstar);
  303. PROC_END("bstar");
  304. }
  305. static void java_proc_n(fz_context *ctx, pdf_processor *proc)
  306. {
  307. PROC_BEGIN("n");
  308. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_n);
  309. PROC_END("n");
  310. }
  311. static void java_proc_W(fz_context *ctx, pdf_processor *proc)
  312. {
  313. PROC_BEGIN("W");
  314. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_W);
  315. PROC_END("W");
  316. }
  317. static void java_proc_Wstar(fz_context *ctx, pdf_processor *proc)
  318. {
  319. PROC_BEGIN("Wstar");
  320. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Wstar);
  321. PROC_END("Wstar");
  322. }
  323. static void java_proc_BT(fz_context *ctx, pdf_processor *proc)
  324. {
  325. PROC_BEGIN("BT");
  326. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_BT);
  327. PROC_END("BT");
  328. }
  329. static void java_proc_ET(fz_context *ctx, pdf_processor *proc)
  330. {
  331. PROC_BEGIN("ET");
  332. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_ET);
  333. PROC_END("ET");
  334. }
  335. static void java_proc_Tc(fz_context *ctx, pdf_processor *proc, float charspace)
  336. {
  337. PROC_BEGIN("Tc");
  338. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Tc, charspace);
  339. PROC_END("Tc");
  340. }
  341. static void java_proc_Tw(fz_context *ctx, pdf_processor *proc, float wordspace)
  342. {
  343. PROC_BEGIN("Tw");
  344. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Tw, wordspace);
  345. PROC_END("Tw");
  346. }
  347. static void java_proc_Tz(fz_context *ctx, pdf_processor *proc, float scale)
  348. {
  349. PROC_BEGIN("Tz");
  350. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Tz, scale);
  351. PROC_END("Tz");
  352. }
  353. static void java_proc_TL(fz_context *ctx, pdf_processor *proc, float leading)
  354. {
  355. PROC_BEGIN("TL");
  356. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_TL, leading);
  357. PROC_END("TL");
  358. }
  359. static void java_proc_Tf(fz_context *ctx, pdf_processor *proc, const char *name, pdf_font_desc *font, float size)
  360. {
  361. if (!((pdf_java_processor*) proc)->extgstate)
  362. {
  363. jobject jname;
  364. PROC_BEGIN("Tf");
  365. jname = (*env)->NewStringUTF(env, name);
  366. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Tf, jname, size);
  367. (*env)->DeleteLocalRef(env, jname);
  368. PROC_END("Tf");
  369. }
  370. }
  371. static void java_proc_Tr(fz_context *ctx, pdf_processor *proc, int render)
  372. {
  373. PROC_BEGIN("Tr");
  374. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Tr, render);
  375. PROC_END("Tr");
  376. }
  377. static void java_proc_Ts(fz_context *ctx, pdf_processor *proc, float rise)
  378. {
  379. PROC_BEGIN("Ts");
  380. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Ts, rise);
  381. PROC_END("Ts");
  382. }
  383. static void java_proc_Td(fz_context *ctx, pdf_processor *proc, float tx, float ty)
  384. {
  385. PROC_BEGIN("Td");
  386. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Td, tx, ty);
  387. PROC_END("Td");
  388. }
  389. static void java_proc_TD(fz_context *ctx, pdf_processor *proc, float tx, float ty)
  390. {
  391. PROC_BEGIN("TD");
  392. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_TD, tx, ty);
  393. PROC_END("TD");
  394. }
  395. static void java_proc_Tm(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f)
  396. {
  397. PROC_BEGIN("Tm");
  398. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Tm, a, b, c, d, e, f);
  399. PROC_END("Tm");
  400. }
  401. static void java_proc_Tstar(fz_context *ctx, pdf_processor *proc)
  402. {
  403. PROC_BEGIN("Tstar");
  404. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Tstar);
  405. PROC_END("Tstar");
  406. }
  407. static void java_proc_TJ(fz_context *ctx, pdf_processor *proc, pdf_obj *array)
  408. {
  409. PROC_BEGIN("TJ");
  410. int i, n = pdf_array_len(ctx, array);
  411. pdf_obj *obj;
  412. jobject jarray = (*env)->NewObjectArray(env, n, cls_Object, NULL);
  413. for (i = 0; i < n; i++)
  414. {
  415. jobject jelem;
  416. obj = pdf_array_get(ctx, array, i);
  417. if (pdf_is_number(ctx, obj))
  418. jelem = (*env)->NewObject(env, cls_Float, mid_Float_init, pdf_to_real(ctx, obj));
  419. else
  420. {
  421. char *str = pdf_to_str_buf(ctx, obj);
  422. size_t len = pdf_to_str_len(ctx, obj);
  423. if (java_is_ascii((unsigned char *) str, len))
  424. jelem = java_to_string(env, ctx, (unsigned char *) str, len);
  425. else
  426. jelem = java_to_byte_array(env, ctx, (unsigned char *) str, len);
  427. if (!jelem)
  428. fz_throw_java_and_detach_thread(ctx, env, detach);
  429. }
  430. (*env)->SetObjectArrayElement(env, jarray, i, jelem);
  431. (*env)->DeleteLocalRef(env, jelem);
  432. }
  433. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_TJ, jarray);
  434. (*env)->DeleteLocalRef(env, jarray);
  435. PROC_END("TJ");
  436. }
  437. static void java_proc_Tj(fz_context *ctx, pdf_processor *proc, char *str, size_t len)
  438. {
  439. PROC_BEGIN("Tj");
  440. if (java_is_ascii((unsigned char *) str, len))
  441. {
  442. jstring jstr = java_to_string(env, ctx, (unsigned char *) str, len);
  443. if (!jstr)
  444. fz_throw_java_and_detach_thread(ctx, env, detach);
  445. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Tj_string, jstr);
  446. (*env)->DeleteLocalRef(env, jstr);
  447. }
  448. else
  449. {
  450. jobject jarr = java_to_byte_array(env, ctx, (unsigned char *) str, len);
  451. if (!jarr)
  452. fz_throw_java_and_detach_thread(ctx, env, detach);
  453. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Tj_byte_array, jarr);
  454. (*env)->DeleteLocalRef(env, jarr);
  455. }
  456. PROC_END("Tj");
  457. }
  458. static void java_proc_squote(fz_context *ctx, pdf_processor *proc, char *str, size_t len)
  459. {
  460. PROC_BEGIN("dquote");
  461. if (java_is_ascii((unsigned char *) str, len))
  462. {
  463. jstring jstr = java_to_string(env, ctx, (unsigned char *) str, len);
  464. if (!jstr)
  465. fz_throw_java_and_detach_thread(ctx, env, detach);
  466. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_squote_string, jstr);
  467. (*env)->DeleteLocalRef(env, jstr);
  468. }
  469. else
  470. {
  471. jobject jarr = java_to_byte_array(env, ctx, (unsigned char *) str, len);
  472. if (!jarr)
  473. fz_throw_java_and_detach_thread(ctx, env, detach);
  474. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_squote_byte_array, jarr);
  475. (*env)->DeleteLocalRef(env, jarr);
  476. }
  477. PROC_END("squote");
  478. }
  479. static void java_proc_dquote(fz_context *ctx, pdf_processor *proc, float aw, float ac, char *str, size_t len)
  480. {
  481. PROC_BEGIN("dquote");
  482. if (java_is_ascii((unsigned char *) str, len))
  483. {
  484. jstring jstr = java_to_string(env, ctx, (unsigned char *) str, len);
  485. if (!jstr)
  486. fz_throw_java_and_detach_thread(ctx, env, detach);
  487. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_dquote_string, aw, ac, jstr);
  488. (*env)->DeleteLocalRef(env, jstr);
  489. }
  490. else
  491. {
  492. jobject jarr = java_to_byte_array(env, ctx, (unsigned char *) str, len);
  493. if (!jarr)
  494. fz_throw_java_and_detach_thread(ctx, env, detach);
  495. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_dquote_byte_array, aw, ac, jarr);
  496. (*env)->DeleteLocalRef(env, jarr);
  497. }
  498. PROC_END("dquote");
  499. }
  500. static void java_proc_d0(fz_context *ctx, pdf_processor *proc, float wx, float wy)
  501. {
  502. PROC_BEGIN("d0");
  503. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_d0, wx, wy);
  504. PROC_END("d0");
  505. }
  506. static void java_proc_d1(fz_context *ctx, pdf_processor *proc,
  507. float wx, float wy, float llx, float lly, float urx, float ury)
  508. {
  509. PROC_BEGIN("d1");
  510. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_d1, wx, wy, llx, lly, urx, ury);
  511. PROC_END("d1");
  512. }
  513. static void java_proc_CS(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *cs)
  514. {
  515. PROC_BEGIN("CS");
  516. jstring jname = (*env)->NewStringUTF(env, name);
  517. jobject jcs = to_ColorSpace_safe(ctx, env, cs);
  518. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_CS, jname, jcs);
  519. (*env)->DeleteLocalRef(env, jcs);
  520. (*env)->DeleteLocalRef(env, jname);
  521. PROC_END("CS");
  522. }
  523. static void java_proc_cs(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *cs)
  524. {
  525. PROC_BEGIN("cs");
  526. jstring jname = (*env)->NewStringUTF(env, name);
  527. jobject jcs = to_ColorSpace_safe(ctx, env, cs);
  528. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_cs, jname, jcs);
  529. (*env)->DeleteLocalRef(env, jcs);
  530. (*env)->DeleteLocalRef(env, jname);
  531. PROC_END("cs");
  532. }
  533. static void java_proc_SC_pattern(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color)
  534. {
  535. PROC_BEGIN("SC_pattern");
  536. int i;
  537. jstring jname = (*env)->NewStringUTF(env, name);
  538. jobject jcolor = (*env)->NewFloatArray(env, n);
  539. if ((*env)->ExceptionCheck(env))
  540. fz_throw_java_and_detach_thread(ctx, env, detach);
  541. for (i = 0; i < n; ++i)
  542. (*env)->SetFloatArrayRegion(env, jcolor, i, 1, &color[i]);
  543. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_SC_pattern, jname, pat->id, jcolor);
  544. (*env)->DeleteLocalRef(env, jcolor);
  545. (*env)->DeleteLocalRef(env, jname);
  546. PROC_END("SC_pattern");
  547. }
  548. static void java_proc_sc_pattern(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color)
  549. {
  550. PROC_BEGIN("sc_pattern");
  551. int i;
  552. jstring jname = (*env)->NewStringUTF(env, name);
  553. jobject jcolor = (*env)->NewFloatArray(env, n);
  554. if ((*env)->ExceptionCheck(env))
  555. fz_throw_java_and_detach_thread(ctx, env, detach);
  556. for (i = 0; i < n; ++i)
  557. (*env)->SetFloatArrayRegion(env, jcolor, i, 1, &color[i]);
  558. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_sc_pattern, jname, pat->id, jcolor);
  559. (*env)->DeleteLocalRef(env, jcolor);
  560. (*env)->DeleteLocalRef(env, jname);
  561. PROC_END("sc_pattern");
  562. }
  563. static void java_proc_SC_shade(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
  564. {
  565. PROC_BEGIN("SC_shade");
  566. jstring jname = (*env)->NewStringUTF(env, name);
  567. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_SC_shade, jname);
  568. (*env)->DeleteLocalRef(env, jname);
  569. PROC_END("SC_shade");
  570. }
  571. static void java_proc_sc_shade(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
  572. {
  573. PROC_BEGIN("sc_shade");
  574. jstring jname = (*env)->NewStringUTF(env, name);
  575. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_sc_shade, jname);
  576. (*env)->DeleteLocalRef(env, jname);
  577. PROC_END("sc_shade");
  578. }
  579. static void java_proc_SC_color(fz_context *ctx, pdf_processor *proc, int n, float *color)
  580. {
  581. PROC_BEGIN("SC_color");
  582. int i;
  583. jobject jcolor = (*env)->NewFloatArray(env, n);
  584. if ((*env)->ExceptionCheck(env))
  585. fz_throw_java_and_detach_thread(ctx, env, detach);
  586. for (i = 0; i < n; ++i)
  587. (*env)->SetFloatArrayRegion(env, jcolor, i, 1, &color[i]);
  588. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_SC_color, jcolor);
  589. (*env)->DeleteLocalRef(env, jcolor);
  590. PROC_END("SC_color");
  591. }
  592. static void java_proc_sc_color(fz_context *ctx, pdf_processor *proc, int n, float *color)
  593. {
  594. PROC_BEGIN("sc_color");
  595. int i;
  596. jobject jcolor = (*env)->NewFloatArray(env, n);
  597. if ((*env)->ExceptionCheck(env))
  598. fz_throw_java_and_detach_thread(ctx, env, detach);
  599. for (i = 0; i < n; ++i)
  600. (*env)->SetFloatArrayRegion(env, jcolor, i, 1, &color[i]);
  601. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_sc_color, jcolor);
  602. (*env)->DeleteLocalRef(env, jcolor);
  603. PROC_END("sc_color");
  604. }
  605. static void java_proc_G(fz_context *ctx, pdf_processor *proc, float g)
  606. {
  607. PROC_BEGIN("g");
  608. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_g, g);
  609. PROC_END("g");
  610. }
  611. static void java_proc_g(fz_context *ctx, pdf_processor *proc, float g)
  612. {
  613. PROC_BEGIN("G");
  614. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_G, g);
  615. PROC_END("G");
  616. }
  617. static void java_proc_RG(fz_context *ctx, pdf_processor *proc, float r, float g, float b)
  618. {
  619. PROC_BEGIN("RG");
  620. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_RG, r, g, b);
  621. PROC_END("RG");
  622. }
  623. static void java_proc_rg(fz_context *ctx, pdf_processor *proc, float r, float g, float b)
  624. {
  625. PROC_BEGIN("rg");
  626. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_rg, r, g, b);
  627. PROC_END("rg");
  628. }
  629. static void java_proc_K(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k)
  630. {
  631. PROC_BEGIN("K");
  632. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_K, c, m, y, k);
  633. PROC_END("K");
  634. }
  635. static void java_proc_k(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k)
  636. {
  637. PROC_BEGIN("k");
  638. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_k, c, m, y, k);
  639. PROC_END("k");
  640. }
  641. static void java_proc_BI(fz_context *ctx, pdf_processor *proc, fz_image *img, const char *colorspace)
  642. {
  643. PROC_BEGIN("BI");
  644. jobject jimg = to_Image_safe(ctx, env, img);
  645. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_BI, jimg);
  646. (*env)->DeleteLocalRef(env, jimg);
  647. PROC_END("BI");
  648. }
  649. static void java_proc_sh(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade)
  650. {
  651. PROC_BEGIN("sh");
  652. jstring jname = (*env)->NewStringUTF(env, name);
  653. jobject jshade = to_Shade_safe(ctx, env, shade);
  654. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_sh, jname, jshade);
  655. (*env)->DeleteLocalRef(env, jshade);
  656. (*env)->DeleteLocalRef(env, jname);
  657. PROC_END("sh");
  658. }
  659. static void java_proc_Do_image(fz_context *ctx, pdf_processor *proc, const char *name, fz_image *image)
  660. {
  661. PROC_BEGIN("Do_image");
  662. jstring jname = (*env)->NewStringUTF(env, name);
  663. jobject jimage = to_Image_safe(ctx, env, image);
  664. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Do_image, jname, jimage);
  665. (*env)->DeleteLocalRef(env, jimage);
  666. (*env)->DeleteLocalRef(env, jname);
  667. PROC_END("Do_image");
  668. }
  669. static void java_proc_Do_form(fz_context *ctx, pdf_processor *proc, const char *name, pdf_obj *xobj)
  670. {
  671. PROC_BEGIN("Do_image");
  672. jstring jname = (*env)->NewStringUTF(env, name);
  673. jobject jform = to_PDFObject_safe(ctx, env, xobj);
  674. jobject jres = NULL;
  675. if (((pdf_java_processor *) proc)->rstack)
  676. jres = to_PDFObject_safe(ctx, env, ((pdf_java_processor *) proc)->rstack->resources);
  677. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_Do_image, jname, jform, jres);
  678. (*env)->DeleteLocalRef(env, jres);
  679. (*env)->DeleteLocalRef(env, jform);
  680. (*env)->DeleteLocalRef(env, jname);
  681. PROC_END("Do_image");
  682. }
  683. static void java_proc_MP(fz_context *ctx, pdf_processor *proc, const char *tag)
  684. {
  685. PROC_BEGIN("MP");
  686. jobject jtag = (*env)->NewStringUTF(env, tag);
  687. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_MP, jtag);
  688. (*env)->DeleteLocalRef(env, jtag);
  689. PROC_END("MP");
  690. }
  691. static void java_proc_DP(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *raw, pdf_obj *cooked)
  692. {
  693. PROC_BEGIN("DP");
  694. jstring jtag = (*env)->NewStringUTF(env, tag);
  695. jobject jraw = to_PDFObject_safe(ctx, env, raw);
  696. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_DP, jtag, jraw);
  697. (*env)->DeleteLocalRef(env, jraw);
  698. (*env)->DeleteLocalRef(env, jtag);
  699. PROC_END("DP");
  700. }
  701. static void java_proc_BMC(fz_context *ctx, pdf_processor *proc, const char *tag)
  702. {
  703. PROC_BEGIN("BMC");
  704. jstring jtag = (*env)->NewStringUTF(env, tag);
  705. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_BMC, jtag);
  706. (*env)->DeleteLocalRef(env, jtag);
  707. PROC_END("BMC");
  708. }
  709. static void java_proc_BDC(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *raw, pdf_obj *cooked)
  710. {
  711. PROC_BEGIN("BDC");
  712. jstring jtag = (*env)->NewStringUTF(env, tag);
  713. jobject jraw = to_PDFObject_safe(ctx, env, raw);
  714. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_BDC, jtag, jraw);
  715. (*env)->DeleteLocalRef(env, jraw);
  716. (*env)->DeleteLocalRef(env, jtag);
  717. PROC_END("BDC");
  718. }
  719. static void java_proc_EMC(fz_context *ctx, pdf_processor *proc)
  720. {
  721. PROC_BEGIN("EMC");
  722. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_EMC);
  723. PROC_END("EMC");
  724. }
  725. static void java_proc_BX(fz_context *ctx, pdf_processor *proc)
  726. {
  727. PROC_BEGIN("BX");
  728. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_BX);
  729. PROC_END("BX");
  730. }
  731. static void java_proc_EX(fz_context *ctx, pdf_processor *proc)
  732. {
  733. PROC_BEGIN("EX");
  734. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_EX);
  735. PROC_END("EX");
  736. }
  737. static void java_proc_push_resources(fz_context *ctx, pdf_processor *proc, pdf_obj *res)
  738. {
  739. PROC_BEGIN("pushResources");
  740. jobject jres = to_PDFObject_safe(ctx, env, res);
  741. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_pushResources, jres);
  742. (*env)->DeleteLocalRef(env, jres);
  743. PROC_END("pushResources");
  744. }
  745. static pdf_obj *java_proc_pop_resources(fz_context *ctx, pdf_processor *proc)
  746. {
  747. PROC_BEGIN("popResources");
  748. (*env)->CallVoidMethod(env, jproc, mid_PDFProcessor_op_popResources);
  749. PROC_END("popResources");
  750. return NULL;
  751. }
  752. static void java_proc_drop(fz_context *ctx, pdf_processor *proc)
  753. {
  754. pdf_java_processor *pr = (pdf_java_processor *)proc;
  755. while (pr->rstack)
  756. {
  757. resources_stack *stk = pr->rstack;
  758. pr->rstack = stk->next;
  759. pdf_drop_obj(ctx, stk->resources);
  760. fz_free(ctx, stk);
  761. }
  762. }
  763. pdf_processor *make_pdf_processor(JNIEnv *env, fz_context *ctx, jobject jproc)
  764. {
  765. pdf_java_processor *proc = pdf_new_processor(ctx, sizeof *proc);
  766. proc->super.close_processor = NULL;
  767. proc->super.drop_processor = java_proc_drop;
  768. proc->super.push_resources = java_proc_push_resources;
  769. proc->super.pop_resources = java_proc_pop_resources;
  770. /* general graphics state */
  771. proc->super.op_w = java_proc_w;
  772. proc->super.op_j = java_proc_j;
  773. proc->super.op_J = java_proc_J;
  774. proc->super.op_M = java_proc_M;
  775. proc->super.op_d = java_proc_d;
  776. proc->super.op_ri = java_proc_ri;
  777. proc->super.op_i = java_proc_i;
  778. proc->super.op_gs_begin = java_proc_gs_begin;
  779. proc->super.op_gs_end = java_proc_gs_end;
  780. /* transparency graphics state */
  781. proc->super.op_gs_BM = NULL;
  782. proc->super.op_gs_CA = NULL;
  783. proc->super.op_gs_ca = NULL;
  784. proc->super.op_gs_SMask = NULL;
  785. /* special graphics state */
  786. proc->super.op_q = java_proc_q;
  787. proc->super.op_Q = java_proc_Q;
  788. proc->super.op_cm = java_proc_cm;
  789. /* path construction */
  790. proc->super.op_m = java_proc_m;
  791. proc->super.op_l = java_proc_l;
  792. proc->super.op_c = java_proc_c;
  793. proc->super.op_v = java_proc_v;
  794. proc->super.op_y = java_proc_y;
  795. proc->super.op_h = java_proc_h;
  796. proc->super.op_re = java_proc_re;
  797. /* path painting */
  798. proc->super.op_S = java_proc_S;
  799. proc->super.op_s = java_proc_s;
  800. proc->super.op_F = java_proc_F;
  801. proc->super.op_f = java_proc_f;
  802. proc->super.op_fstar = java_proc_fstar;
  803. proc->super.op_B = java_proc_B;
  804. proc->super.op_Bstar = java_proc_Bstar;
  805. proc->super.op_b = java_proc_b;
  806. proc->super.op_bstar = java_proc_bstar;
  807. proc->super.op_n = java_proc_n;
  808. /* clipping paths */
  809. proc->super.op_W = java_proc_W;
  810. proc->super.op_Wstar = java_proc_Wstar;
  811. /* text objects */
  812. proc->super.op_BT = java_proc_BT;
  813. proc->super.op_ET = java_proc_ET;
  814. /* text state */
  815. proc->super.op_Tc = java_proc_Tc;
  816. proc->super.op_Tw = java_proc_Tw;
  817. proc->super.op_Tz = java_proc_Tz;
  818. proc->super.op_TL = java_proc_TL;
  819. proc->super.op_Tf = java_proc_Tf;
  820. proc->super.op_Tr = java_proc_Tr;
  821. proc->super.op_Ts = java_proc_Ts;
  822. /* text positioning */
  823. proc->super.op_Td = java_proc_Td;
  824. proc->super.op_TD = java_proc_TD;
  825. proc->super.op_Tm = java_proc_Tm;
  826. proc->super.op_Tstar = java_proc_Tstar;
  827. /* text showing */
  828. proc->super.op_TJ = java_proc_TJ;
  829. proc->super.op_Tj = java_proc_Tj;
  830. proc->super.op_squote = java_proc_squote;
  831. proc->super.op_dquote = java_proc_dquote;
  832. /* type 3 fonts */
  833. proc->super.op_d0 = java_proc_d0;
  834. proc->super.op_d1 = java_proc_d1;
  835. /* color */
  836. proc->super.op_CS = java_proc_CS;
  837. proc->super.op_cs = java_proc_cs;
  838. proc->super.op_SC_color = java_proc_SC_color;
  839. proc->super.op_sc_color = java_proc_sc_color;
  840. proc->super.op_SC_pattern = java_proc_SC_pattern;
  841. proc->super.op_sc_pattern = java_proc_sc_pattern;
  842. proc->super.op_SC_shade = java_proc_SC_shade;
  843. proc->super.op_sc_shade = java_proc_sc_shade;
  844. proc->super.op_G = java_proc_G;
  845. proc->super.op_g = java_proc_g;
  846. proc->super.op_RG = java_proc_RG;
  847. proc->super.op_rg = java_proc_rg;
  848. proc->super.op_K = java_proc_K;
  849. proc->super.op_k = java_proc_k;
  850. /* shadings, images, xobjects */
  851. proc->super.op_BI = java_proc_BI;
  852. proc->super.op_sh = java_proc_sh;
  853. proc->super.op_Do_image = java_proc_Do_image;
  854. proc->super.op_Do_form = java_proc_Do_form;
  855. /* marked content */
  856. proc->super.op_MP = java_proc_MP;
  857. proc->super.op_DP = java_proc_DP;
  858. proc->super.op_BMC = java_proc_BMC;
  859. proc->super.op_BDC = java_proc_BDC;
  860. proc->super.op_EMC = java_proc_EMC;
  861. /* compatibility */
  862. proc->super.op_BX = java_proc_BX;
  863. proc->super.op_EX = java_proc_EX;
  864. /* extgstate */
  865. proc->super.op_gs_OP = NULL;
  866. proc->super.op_gs_op = NULL;
  867. proc->super.op_gs_OPM = NULL;
  868. proc->super.op_gs_UseBlackPtComp = NULL;
  869. proc->self = jproc;
  870. proc->env = env;
  871. return (pdf_processor*)proc;
  872. }