1 /* Page interface */
2
3 JNIEXPORT void JNICALL
FUN(Page_finalize)4 FUN(Page_finalize)(JNIEnv *env, jobject self)
5 {
6 fz_context *ctx = get_context(env);
7 fz_page *page = from_Page_safe(env, self);
8 if (!ctx || !page) return;
9 (*env)->SetLongField(env, self, fid_Page_pointer, 0);
10 fz_drop_page(ctx, page);
11 }
12
13 JNIEXPORT jobject JNICALL
FUN(Page_toPixmap)14 FUN(Page_toPixmap)(JNIEnv *env, jobject self, jobject jctm, jobject jcs, jboolean alpha, jboolean showExtra)
15 {
16 fz_context *ctx = get_context(env);
17 fz_page *page = from_Page(env, self);
18 fz_colorspace *cs = from_ColorSpace(env, jcs);
19 fz_matrix ctm = from_Matrix(env, jctm);
20 fz_pixmap *pixmap = NULL;
21
22 if (!ctx || !page) return NULL;
23
24 fz_try(ctx)
25 {
26 if (showExtra)
27 pixmap = fz_new_pixmap_from_page(ctx, page, ctm, cs, alpha);
28 else
29 pixmap = fz_new_pixmap_from_page_contents(ctx, page, ctm, cs, alpha);
30 }
31 fz_catch(ctx)
32 jni_rethrow(env, ctx);
33
34 return to_Pixmap_safe_own(ctx, env, pixmap);
35 }
36
37 JNIEXPORT jobject JNICALL
FUN(Page_getBounds)38 FUN(Page_getBounds)(JNIEnv *env, jobject self)
39 {
40 fz_context *ctx = get_context(env);
41 fz_page *page = from_Page(env, self);
42 fz_rect rect;
43
44 if (!ctx || !page) return NULL;
45
46 fz_try(ctx)
47 rect = fz_bound_page(ctx, page);
48 fz_catch(ctx)
49 jni_rethrow(env, ctx);
50
51 return to_Rect_safe(ctx, env, rect);
52 }
53
54 JNIEXPORT void JNICALL
FUN(Page_run)55 FUN(Page_run)(JNIEnv *env, jobject self, jobject jdev, jobject jctm, jobject jcookie)
56 {
57 fz_context *ctx = get_context(env);
58 fz_page *page = from_Page(env, self);
59 fz_device *dev = from_Device(env, jdev);
60 fz_matrix ctm = from_Matrix(env, jctm);
61 fz_cookie *cookie = from_Cookie(env, jcookie);
62 NativeDeviceInfo *info;
63 int err;
64
65 if (!ctx || !page) return;
66 if (!dev) jni_throw_arg_void(env, "device must not be null");
67
68 info = lockNativeDevice(env, jdev, &err);
69 if (err)
70 return;
71 fz_try(ctx)
72 fz_run_page(ctx, page, dev, ctm, cookie);
73 fz_always(ctx)
74 unlockNativeDevice(env, info);
75 fz_catch(ctx)
76 jni_rethrow_void(env, ctx);
77 }
78
79 JNIEXPORT void JNICALL
FUN(Page_runPageContents)80 FUN(Page_runPageContents)(JNIEnv *env, jobject self, jobject jdev, jobject jctm, jobject jcookie)
81 {
82 fz_context *ctx = get_context(env);
83 fz_page *page = from_Page(env, self);
84 fz_device *dev = from_Device(env, jdev);
85 fz_matrix ctm = from_Matrix(env, jctm);
86 fz_cookie *cookie = from_Cookie(env, jcookie);
87 NativeDeviceInfo *info;
88 int err;
89
90 if (!ctx || !page) return;
91 if (!dev) jni_throw_arg_void(env, "device must not be null");
92
93 info = lockNativeDevice(env, jdev, &err);
94 if (err)
95 return;
96 fz_try(ctx)
97 fz_run_page_contents(ctx, page, dev, ctm, cookie);
98 fz_always(ctx)
99 unlockNativeDevice(env, info);
100 fz_catch(ctx)
101 jni_rethrow_void(env, ctx);
102 }
103
104 JNIEXPORT void JNICALL
FUN(Page_runPageAnnots)105 FUN(Page_runPageAnnots)(JNIEnv *env, jobject self, jobject jdev, jobject jctm, jobject jcookie)
106 {
107 fz_context *ctx = get_context(env);
108 fz_page *page = from_Page(env, self);
109 fz_device *dev = from_Device(env, jdev);
110 fz_matrix ctm = from_Matrix(env, jctm);
111 fz_cookie *cookie = from_Cookie(env, jcookie);
112 NativeDeviceInfo *info;
113 int err;
114
115 if (!ctx || !page) return;
116 if (!dev) jni_throw_arg_void(env, "device must not be null");
117
118 info = lockNativeDevice(env, jdev, &err);
119 if (err)
120 return;
121 fz_try(ctx)
122 fz_run_page_annots(ctx, page, dev, ctm, cookie);
123 fz_always(ctx)
124 unlockNativeDevice(env, info);
125 fz_catch(ctx)
126 jni_rethrow_void(env, ctx);
127 }
128
129 JNIEXPORT void JNICALL
FUN(Page_runPageWidgets)130 FUN(Page_runPageWidgets)(JNIEnv *env, jobject self, jobject jdev, jobject jctm, jobject jcookie)
131 {
132 fz_context *ctx = get_context(env);
133 fz_page *page = from_Page(env, self);
134 fz_device *dev = from_Device(env, jdev);
135 fz_matrix ctm = from_Matrix(env, jctm);
136 fz_cookie *cookie = from_Cookie(env, jcookie);
137 NativeDeviceInfo *info;
138 int err;
139
140 if (!ctx || !page) return;
141 if (!dev) jni_throw_arg_void(env, "device must not be null");
142
143 info = lockNativeDevice(env, jdev, &err);
144 if (err)
145 return;
146 fz_try(ctx)
147 fz_run_page_widgets(ctx, page, dev, ctm, cookie);
148 fz_always(ctx)
149 unlockNativeDevice(env, info);
150 fz_catch(ctx)
151 jni_rethrow_void(env, ctx);
152 }
153
154 JNIEXPORT jobject JNICALL
FUN(Page_getLinks)155 FUN(Page_getLinks)(JNIEnv *env, jobject self)
156 {
157 fz_context *ctx = get_context(env);
158 fz_page *page = from_Page(env, self);
159 fz_link *link = NULL;
160 fz_link *links = NULL;
161 jobject jlinks = NULL;
162 int link_count;
163 int i;
164
165 if (!ctx || !page) return NULL;
166
167 fz_var(links);
168
169 fz_try(ctx)
170 links = fz_load_links(ctx, page);
171 fz_catch(ctx)
172 {
173 fz_drop_link(ctx, links);
174 jni_rethrow(env, ctx);
175 }
176
177 /* count the links */
178 link = links;
179 for (link_count = 0; link; link_count++)
180 link = link->next;
181
182 /* no links, return NULL instead of empty array */
183 if (link_count == 0)
184 {
185 fz_drop_link(ctx, links);
186 return NULL;
187 }
188
189 /* now run through actually creating the link objects */
190 jlinks = (*env)->NewObjectArray(env, link_count, cls_Link, NULL);
191 if (!jlinks || (*env)->ExceptionCheck(env))
192 {
193 fz_drop_link(ctx, links);
194 return NULL;
195 }
196
197 link = links;
198 for (i = 0; link && i < link_count; i++)
199 {
200 jobject jbounds = NULL;
201 jobject jlink = NULL;
202 jobject juri = NULL;
203
204 jbounds = to_Rect_safe(ctx, env, link->rect);
205 if (!jbounds || (*env)->ExceptionCheck(env))
206 {
207 fz_drop_link(ctx, links);
208 return NULL;
209 }
210
211 juri = (*env)->NewStringUTF(env, link->uri);
212 if (!juri || (*env)->ExceptionCheck(env))
213 {
214 fz_drop_link(ctx, links);
215 return NULL;
216 }
217
218 jlink = (*env)->NewObject(env, cls_Link, mid_Link_init, jbounds, juri);
219 if (!jlink || (*env)->ExceptionCheck(env))
220 {
221 fz_drop_link(ctx, links);
222 return NULL;
223 }
224 (*env)->DeleteLocalRef(env, juri);
225 (*env)->DeleteLocalRef(env, jbounds);
226
227 (*env)->SetObjectArrayElement(env, jlinks, i, jlink);
228 if ((*env)->ExceptionCheck(env))
229 {
230 fz_drop_link(ctx, links);
231 return NULL;
232 }
233
234 (*env)->DeleteLocalRef(env, jlink);
235 link = link->next;
236 }
237
238 fz_drop_link(ctx, links);
239
240 return jlinks;
241 }
242
243 JNIEXPORT jobject JNICALL
FUN(Page_search)244 FUN(Page_search)(JNIEnv *env, jobject self, jstring jneedle)
245 {
246 fz_context *ctx = get_context(env);
247 fz_page *page = from_Page(env, self);
248 fz_quad hits[256];
249 const char *needle = NULL;
250 int n = 0;
251
252 if (!ctx || !page) return NULL;
253 if (!jneedle) jni_throw_arg(env, "needle must not be null");
254
255 needle = (*env)->GetStringUTFChars(env, jneedle, NULL);
256 if (!needle) return 0;
257
258 fz_try(ctx)
259 n = fz_search_page(ctx, page, needle, hits, nelem(hits));
260 fz_always(ctx)
261 (*env)->ReleaseStringUTFChars(env, jneedle, needle);
262 fz_catch(ctx)
263 jni_rethrow(env, ctx);
264
265 return to_QuadArray_safe(ctx, env, hits, n);
266 }
267
268 JNIEXPORT jobject JNICALL
FUN(Page_toDisplayList)269 FUN(Page_toDisplayList)(JNIEnv *env, jobject self, jboolean showExtra)
270 {
271 fz_context *ctx = get_context(env);
272 fz_page *page = from_Page(env, self);
273 fz_display_list *list = NULL;
274
275 if (!ctx || !page) return NULL;
276
277 fz_try(ctx)
278 if (showExtra)
279 list = fz_new_display_list_from_page(ctx, page);
280 else
281 list = fz_new_display_list_from_page_contents(ctx, page);
282 fz_catch(ctx)
283 jni_rethrow(env, ctx);
284
285 return to_DisplayList_safe_own(ctx, env, list);
286 }
287
288 JNIEXPORT jobject JNICALL
FUN(Page_toStructuredText)289 FUN(Page_toStructuredText)(JNIEnv *env, jobject self, jstring joptions)
290 {
291 fz_context *ctx = get_context(env);
292 fz_page *page = from_Page(env, self);
293 fz_stext_page *text = NULL;
294 const char *options= NULL;
295 fz_stext_options opts;
296
297 if (!ctx || !page) return NULL;
298
299 if (joptions)
300 {
301 options = (*env)->GetStringUTFChars(env, joptions, NULL);
302 if (!options) return NULL;
303 }
304
305 fz_try(ctx)
306 {
307 fz_parse_stext_options(ctx, &opts, options);
308 text = fz_new_stext_page_from_page(ctx, page, &opts);
309 }
310 fz_always(ctx)
311 {
312 if (options)
313 (*env)->ReleaseStringUTFChars(env, joptions, options);
314 }
315 fz_catch(ctx)
316 jni_rethrow(env, ctx);
317
318 return to_StructuredText_safe_own(ctx, env, text);
319 }
320
321 JNIEXPORT jbyteArray JNICALL
FUN(Page_textAsHtml)322 FUN(Page_textAsHtml)(JNIEnv *env, jobject self)
323 {
324 fz_context *ctx = get_context(env);
325 fz_page *page = from_Page(env, self);
326 fz_stext_page *text = NULL;
327 fz_device *dev = NULL;
328 fz_matrix ctm;
329 jbyteArray arr = NULL;
330 fz_buffer *buf = NULL;
331 fz_output *out = NULL;
332 unsigned char *data;
333 size_t len;
334
335 if (!ctx || !page) return NULL;
336
337 fz_var(text);
338 fz_var(dev);
339 fz_var(buf);
340 fz_var(out);
341
342 fz_try(ctx)
343 {
344 ctm = fz_identity;
345 text = fz_new_stext_page(ctx, fz_bound_page(ctx, page));
346 dev = fz_new_stext_device(ctx, text, NULL);
347 fz_run_page(ctx, page, dev, ctm, NULL);
348 fz_close_device(ctx, dev);
349
350 buf = fz_new_buffer(ctx, 256);
351 out = fz_new_output_with_buffer(ctx, buf);
352 fz_print_stext_header_as_html(ctx, out);
353 fz_print_stext_page_as_html(ctx, out, text, page->number);
354 fz_print_stext_trailer_as_html(ctx, out);
355 fz_close_output(ctx, out);
356
357 len = fz_buffer_storage(ctx, buf, &data);
358 arr = (*env)->NewByteArray(env, (jsize)len);
359 if ((*env)->ExceptionCheck(env))
360 fz_throw_java(ctx, env);
361 if (!arr)
362 fz_throw(ctx, FZ_ERROR_GENERIC, "cannot create byte array");
363
364 (*env)->SetByteArrayRegion(env, arr, 0, (jsize)len, (jbyte *)data);
365 if ((*env)->ExceptionCheck(env))
366 fz_throw_java(ctx, env);
367 }
368 fz_always(ctx)
369 {
370 fz_drop_output(ctx, out);
371 fz_drop_buffer(ctx, buf);
372 fz_drop_device(ctx, dev);
373 fz_drop_stext_page(ctx, text);
374 }
375 fz_catch(ctx)
376 jni_rethrow(env, ctx);
377
378 return arr;
379 }
380