Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/platform/java/jni/pdfwidget.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 // Copyright (C) 2004-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 | |
| 23 /* PDFWidget interface */ | |
| 24 | |
| 25 JNIEXPORT jstring JNICALL | |
| 26 FUN(PDFWidget_getValue)(JNIEnv *env, jobject self) | |
| 27 { | |
| 28 fz_context *ctx = get_context(env); | |
| 29 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 30 const char *text = NULL; | |
| 31 | |
| 32 if (!ctx || !widget) return NULL; | |
| 33 | |
| 34 fz_try(ctx) | |
| 35 text = pdf_field_value(ctx, pdf_annot_obj(ctx, widget)); | |
| 36 fz_catch(ctx) | |
| 37 jni_rethrow(env, ctx); | |
| 38 | |
| 39 return (*env)->NewStringUTF(env, text); | |
| 40 } | |
| 41 | |
| 42 JNIEXPORT jboolean JNICALL | |
| 43 FUN(PDFWidget_setTextValue)(JNIEnv *env, jobject self, jstring jval) | |
| 44 { | |
| 45 fz_context *ctx = get_context(env); | |
| 46 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 47 const char *val = NULL; | |
| 48 jboolean accepted = JNI_FALSE; | |
| 49 | |
| 50 if (!ctx || !widget) return JNI_FALSE; | |
| 51 | |
| 52 if (jval) | |
| 53 val = (*env)->GetStringUTFChars(env, jval, NULL); | |
| 54 | |
| 55 fz_var(accepted); | |
| 56 fz_try(ctx) | |
| 57 accepted = pdf_set_text_field_value(ctx, widget, val); | |
| 58 fz_always(ctx) | |
| 59 if (jval) | |
| 60 (*env)->ReleaseStringUTFChars(env, jval, val); | |
| 61 fz_catch(ctx) | |
| 62 jni_rethrow(env, ctx); | |
| 63 | |
| 64 return accepted; | |
| 65 } | |
| 66 | |
| 67 JNIEXPORT jboolean JNICALL | |
| 68 FUN(PDFWidget_setChoiceValue)(JNIEnv *env, jobject self, jstring jval) | |
| 69 { | |
| 70 fz_context *ctx = get_context(env); | |
| 71 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 72 const char *val = NULL; | |
| 73 jboolean accepted = JNI_FALSE; | |
| 74 | |
| 75 if (!ctx || !widget) return JNI_FALSE; | |
| 76 | |
| 77 if (jval) | |
| 78 val = (*env)->GetStringUTFChars(env, jval, NULL); | |
| 79 | |
| 80 fz_var(accepted); | |
| 81 fz_try(ctx) | |
| 82 accepted = pdf_set_choice_field_value(ctx, widget, val); | |
| 83 fz_always(ctx) | |
| 84 if (jval) | |
| 85 (*env)->ReleaseStringUTFChars(env, jval, val); | |
| 86 fz_catch(ctx) | |
| 87 jni_rethrow(env, ctx); | |
| 88 | |
| 89 return accepted; | |
| 90 } | |
| 91 | |
| 92 JNIEXPORT jboolean JNICALL | |
| 93 FUN(PDFWidget_setValue)(JNIEnv *env, jobject self, jstring jval) | |
| 94 { | |
| 95 fz_context *ctx = get_context(env); | |
| 96 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 97 const char *val = NULL; | |
| 98 jboolean accepted = JNI_FALSE; | |
| 99 | |
| 100 if (!ctx || !widget) return JNI_FALSE; | |
| 101 | |
| 102 if (jval) | |
| 103 val = (*env)->GetStringUTFChars(env, jval, NULL); | |
| 104 | |
| 105 fz_var(accepted); | |
| 106 fz_try(ctx) | |
| 107 accepted = pdf_set_field_value(ctx, pdf_annot_page(ctx, widget)->doc, pdf_annot_obj(ctx, widget), (char *)val, pdf_get_widget_editing_state(ctx, widget)); | |
| 108 fz_always(ctx) | |
| 109 if (jval) | |
| 110 (*env)->ReleaseStringUTFChars(env, jval, val); | |
| 111 fz_catch(ctx) | |
| 112 jni_rethrow(env, ctx); | |
| 113 | |
| 114 return accepted; | |
| 115 } | |
| 116 | |
| 117 JNIEXPORT jboolean JNICALL | |
| 118 FUN(PDFWidget_toggle)(JNIEnv *env, jobject self) | |
| 119 { | |
| 120 fz_context *ctx = get_context(env); | |
| 121 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 122 jboolean accepted = JNI_FALSE; | |
| 123 | |
| 124 if (!ctx || !widget) return JNI_FALSE; | |
| 125 | |
| 126 fz_var(accepted); | |
| 127 fz_try(ctx) | |
| 128 accepted = pdf_toggle_widget(ctx, widget); | |
| 129 fz_catch(ctx) | |
| 130 jni_rethrow(env, ctx); | |
| 131 | |
| 132 return accepted; | |
| 133 } | |
| 134 | |
| 135 JNIEXPORT void JNICALL | |
| 136 FUN(PDFWidget_setEditing)(JNIEnv *env, jobject self, jboolean val) | |
| 137 { | |
| 138 fz_context *ctx = get_context(env); | |
| 139 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 140 | |
| 141 if (!ctx || !widget) return; | |
| 142 | |
| 143 fz_try(ctx) | |
| 144 pdf_set_widget_editing_state(ctx, widget, val); | |
| 145 fz_catch(ctx) | |
| 146 jni_rethrow_void(env, ctx); | |
| 147 } | |
| 148 | |
| 149 JNIEXPORT jboolean JNICALL | |
| 150 FUN(PDFWidget_isEditing)(JNIEnv *env, jobject self) | |
| 151 { | |
| 152 fz_context *ctx = get_context(env); | |
| 153 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 154 jboolean state = JNI_FALSE; | |
| 155 | |
| 156 if (!ctx || !widget) return JNI_FALSE; | |
| 157 | |
| 158 fz_var(state); | |
| 159 fz_try(ctx) | |
| 160 state = pdf_get_widget_editing_state(ctx, widget); | |
| 161 fz_catch(ctx) | |
| 162 jni_rethrow(env, ctx); | |
| 163 | |
| 164 return state; | |
| 165 } | |
| 166 | |
| 167 JNIEXPORT jobject JNICALL | |
| 168 FUN(PDFWidget_textQuads)(JNIEnv *env, jobject self) | |
| 169 { | |
| 170 fz_context *ctx = get_context(env); | |
| 171 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 172 jobject jquad; | |
| 173 jobjectArray array; | |
| 174 int i, nchars; | |
| 175 fz_stext_page *stext = NULL; | |
| 176 | |
| 177 if (!ctx || !widget) return NULL; | |
| 178 | |
| 179 fz_try(ctx) | |
| 180 { | |
| 181 fz_stext_options opts = { 0 }; | |
| 182 opts.flags = FZ_STEXT_INHIBIT_SPACES; | |
| 183 stext = pdf_new_stext_page_from_annot(ctx, widget, &opts); | |
| 184 } | |
| 185 fz_catch(ctx) | |
| 186 jni_rethrow(env, ctx); | |
| 187 | |
| 188 nchars = 0; | |
| 189 for (fz_stext_block *block = stext->first_block; block; block = block->next) | |
| 190 { | |
| 191 if (block->type == FZ_STEXT_BLOCK_TEXT) | |
| 192 { | |
| 193 for (fz_stext_line *line = block->u.t.first_line; line; line = line->next) | |
| 194 { | |
| 195 for (fz_stext_char *ch = line->first_char; ch; ch = ch->next) | |
| 196 { | |
| 197 nchars++; | |
| 198 } | |
| 199 } | |
| 200 } | |
| 201 } | |
| 202 | |
| 203 array = (*env)->NewObjectArray(env, nchars, cls_Quad, NULL); | |
| 204 if (!array || (*env)->ExceptionCheck(env)) | |
| 205 { | |
| 206 fz_drop_stext_page(ctx, stext); | |
| 207 return NULL; | |
| 208 } | |
| 209 | |
| 210 i = 0; | |
| 211 for (fz_stext_block *block = stext->first_block; block; block = block->next) | |
| 212 { | |
| 213 if (block->type == FZ_STEXT_BLOCK_TEXT) | |
| 214 { | |
| 215 for (fz_stext_line *line = block->u.t.first_line; line; line = line->next) | |
| 216 { | |
| 217 for (fz_stext_char *ch = line->first_char; ch; ch = ch->next) | |
| 218 { | |
| 219 jquad = to_Quad_safe(ctx, env, ch->quad); | |
| 220 if (!jquad) | |
| 221 { | |
| 222 fz_drop_stext_page(ctx, stext); | |
| 223 return NULL; | |
| 224 } | |
| 225 | |
| 226 (*env)->SetObjectArrayElement(env, array, i, jquad); | |
| 227 if ((*env)->ExceptionCheck(env)) | |
| 228 { | |
| 229 fz_drop_stext_page(ctx, stext); | |
| 230 return NULL; | |
| 231 } | |
| 232 | |
| 233 (*env)->DeleteLocalRef(env, jquad); | |
| 234 i++; | |
| 235 } | |
| 236 } | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 fz_drop_stext_page(ctx, stext); | |
| 241 return array; | |
| 242 } | |
| 243 | |
| 244 JNIEXPORT jint JNICALL | |
| 245 FUN(PDFWidget_validateSignature)(JNIEnv *env, jobject self) | |
| 246 { | |
| 247 fz_context *ctx = get_context(env); | |
| 248 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 249 int val = 0; | |
| 250 | |
| 251 if (!ctx || !widget) return 0; | |
| 252 | |
| 253 fz_try(ctx) | |
| 254 val = pdf_validate_signature(ctx, widget); | |
| 255 fz_catch(ctx) | |
| 256 jni_rethrow(env, ctx); | |
| 257 | |
| 258 return val; | |
| 259 } | |
| 260 | |
| 261 JNIEXPORT void JNICALL | |
| 262 FUN(PDFWidget_clearSignature)(JNIEnv *env, jobject self) | |
| 263 { | |
| 264 fz_context *ctx = get_context(env); | |
| 265 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 266 | |
| 267 if (!ctx || !widget) return; | |
| 268 | |
| 269 fz_try(ctx) | |
| 270 pdf_clear_signature(ctx, widget); | |
| 271 fz_catch(ctx) | |
| 272 jni_rethrow_void(env, ctx); | |
| 273 } | |
| 274 | |
| 275 JNIEXPORT jboolean JNICALL | |
| 276 FUN(PDFWidget_isSigned)(JNIEnv *env, jobject self) | |
| 277 { | |
| 278 fz_context *ctx = get_context(env); | |
| 279 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 280 jboolean val = JNI_FALSE; | |
| 281 | |
| 282 if (!ctx || !widget) return JNI_FALSE; | |
| 283 | |
| 284 fz_try(ctx) | |
| 285 val = !!pdf_widget_is_signed(ctx, widget); | |
| 286 fz_catch(ctx) | |
| 287 jni_rethrow(env, ctx); | |
| 288 | |
| 289 return val; | |
| 290 } | |
| 291 | |
| 292 JNIEXPORT jint JNICALL | |
| 293 FUN(PDFWidget_checkCertificate)(JNIEnv *env, jobject self, jobject jverifier) | |
| 294 { | |
| 295 fz_context *ctx = get_context(env); | |
| 296 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 297 pdf_document *pdf = pdf_annot_page(ctx, widget)->doc; | |
| 298 java_pkcs7_verifier *verifier = from_PKCS7Verifier_safe(env, jverifier); | |
| 299 pdf_signature_error ret = PDF_SIGNATURE_ERROR_UNKNOWN; | |
| 300 | |
| 301 if (!ctx || !widget || !pdf) return PDF_SIGNATURE_ERROR_UNKNOWN; | |
| 302 if (!verifier) jni_throw_arg(env, "verifier must not be null"); | |
| 303 | |
| 304 fz_try(ctx) | |
| 305 ret = pdf_check_certificate(ctx, &verifier->base, pdf, pdf_annot_obj(ctx, widget)); | |
| 306 fz_catch(ctx) | |
| 307 jni_rethrow(env, ctx); | |
| 308 | |
| 309 return ret; | |
| 310 } | |
| 311 | |
| 312 JNIEXPORT jint JNICALL | |
| 313 FUN(PDFWidget_checkDigest)(JNIEnv *env, jobject self, jobject jverifier) | |
| 314 { | |
| 315 fz_context *ctx = get_context(env); | |
| 316 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 317 java_pkcs7_verifier *verifier = from_PKCS7Verifier_safe(env, jverifier); | |
| 318 pdf_signature_error ret = PDF_SIGNATURE_ERROR_UNKNOWN; | |
| 319 | |
| 320 if (!ctx || !widget) return PDF_SIGNATURE_ERROR_UNKNOWN; | |
| 321 if (!verifier) jni_throw_arg(env, "verifier must not be null"); | |
| 322 | |
| 323 fz_try(ctx) | |
| 324 ret = pdf_check_widget_digest(ctx, &verifier->base, widget); | |
| 325 fz_catch(ctx) | |
| 326 jni_rethrow(env, ctx); | |
| 327 | |
| 328 return ret; | |
| 329 } | |
| 330 | |
| 331 JNIEXPORT jboolean JNICALL | |
| 332 FUN(PDFWidget_incrementalChangeSinceSigning)(JNIEnv *env, jobject self) | |
| 333 { | |
| 334 fz_context *ctx = get_context(env); | |
| 335 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 336 jboolean change = JNI_FALSE; | |
| 337 | |
| 338 if (!ctx || !widget) return JNI_FALSE; | |
| 339 | |
| 340 fz_try(ctx) | |
| 341 change = pdf_incremental_change_since_signing_widget(ctx, widget); | |
| 342 fz_catch(ctx) | |
| 343 jni_rethrow(env, ctx); | |
| 344 | |
| 345 return change; | |
| 346 } | |
| 347 | |
| 348 JNIEXPORT jobject JNICALL | |
| 349 FUN(PDFWidget_getDistinguishedName)(JNIEnv *env, jobject self, jobject jverifier) | |
| 350 { | |
| 351 fz_context *ctx = get_context(env); | |
| 352 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 353 java_pkcs7_verifier *verifier = from_PKCS7Verifier_safe(env, jverifier); | |
| 354 pdf_document *pdf = pdf_annot_page(ctx, widget)->doc; | |
| 355 jobject jcn, jo, jou, jemail, jc; | |
| 356 pdf_pkcs7_distinguished_name *name; | |
| 357 jobject jname; | |
| 358 | |
| 359 if (!ctx || !widget || !pdf) return NULL; | |
| 360 if (!verifier) jni_throw_arg(env, "verifier must not be null"); | |
| 361 | |
| 362 jname = (*env)->NewObject(env, cls_PKCS7DistinguishedName, mid_PKCS7DistinguishedName_init); | |
| 363 if ((*env)->ExceptionCheck(env)) return NULL; | |
| 364 if (!jname) jni_throw_run(env, "cannot create distinguished name object"); | |
| 365 | |
| 366 fz_try(ctx) | |
| 367 { | |
| 368 name = pdf_signature_get_widget_signatory(ctx, &verifier->base, widget); | |
| 369 | |
| 370 jcn = (*env)->NewStringUTF(env, name->cn); | |
| 371 if (!jcn) | |
| 372 jni_throw_run(env, "cannot create common name string"); | |
| 373 if ((*env)->ExceptionCheck(env)) | |
| 374 fz_throw_java(ctx, env); | |
| 375 jo = (*env)->NewStringUTF(env, name->o); | |
| 376 if (!jo) | |
| 377 jni_throw_run(env, "cannot create organization string"); | |
| 378 if ((*env)->ExceptionCheck(env)) | |
| 379 fz_throw_java(ctx, env); | |
| 380 jou = (*env)->NewStringUTF(env, name->ou); | |
| 381 if (!jou) | |
| 382 jni_throw_run(env, "cannot create organizational unit string"); | |
| 383 if ((*env)->ExceptionCheck(env)) | |
| 384 fz_throw_java(ctx, env); | |
| 385 jemail = (*env)->NewStringUTF(env, name->email); | |
| 386 if (!jemail) | |
| 387 jni_throw_run(env, "cannot create email string"); | |
| 388 if ((*env)->ExceptionCheck(env)) | |
| 389 fz_throw_java(ctx, env); | |
| 390 jc = (*env)->NewStringUTF(env, name->c); | |
| 391 if (!jc) | |
| 392 jni_throw_run(env, "cannot create country string"); | |
| 393 if ((*env)->ExceptionCheck(env)) | |
| 394 fz_throw_java(ctx, env); | |
| 395 } | |
| 396 fz_always(ctx) | |
| 397 pdf_signature_drop_distinguished_name(ctx, name); | |
| 398 fz_catch(ctx) | |
| 399 jni_rethrow(env, ctx); | |
| 400 | |
| 401 (*env)->SetObjectField(env, jname, fid_PKCS7DistinguishedName_cn, jcn); | |
| 402 (*env)->SetObjectField(env, jname, fid_PKCS7DistinguishedName_o, jo); | |
| 403 (*env)->SetObjectField(env, jname, fid_PKCS7DistinguishedName_ou, jou); | |
| 404 (*env)->SetObjectField(env, jname, fid_PKCS7DistinguishedName_email, jemail); | |
| 405 (*env)->SetObjectField(env, jname, fid_PKCS7DistinguishedName_c, jc); | |
| 406 | |
| 407 return jname; | |
| 408 } | |
| 409 | |
| 410 JNIEXPORT jstring JNICALL | |
| 411 FUN(PDFWidget_getSignatory)(JNIEnv *env, jobject self, jobject jverifier) | |
| 412 { | |
| 413 fz_context *ctx = get_context(env); | |
| 414 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 415 java_pkcs7_verifier *verifier = from_PKCS7Verifier_safe(env, jverifier); | |
| 416 pdf_document *pdf = pdf_annot_page(ctx, widget)->doc; | |
| 417 pdf_pkcs7_distinguished_name *name; | |
| 418 char *s = NULL; | |
| 419 char buf[800]; | |
| 420 | |
| 421 if (!ctx || !widget || !pdf) return NULL; | |
| 422 if (!verifier) jni_throw_arg(env, "verifier must not be null"); | |
| 423 | |
| 424 fz_var(s); | |
| 425 | |
| 426 fz_try(ctx) | |
| 427 { | |
| 428 name = pdf_signature_get_widget_signatory(ctx, &verifier->base, widget); | |
| 429 if (name) | |
| 430 { | |
| 431 s = pdf_signature_format_distinguished_name(ctx, name); | |
| 432 fz_strlcpy(buf, s, sizeof buf); | |
| 433 fz_free(ctx, s); | |
| 434 } | |
| 435 else | |
| 436 { | |
| 437 fz_strlcpy(buf, "Signature information missing.", sizeof buf); | |
| 438 } | |
| 439 } | |
| 440 fz_always(ctx) | |
| 441 pdf_signature_drop_distinguished_name(ctx, name); | |
| 442 fz_catch(ctx) | |
| 443 jni_rethrow(env, ctx); | |
| 444 | |
| 445 return to_String_safe(ctx, env, &buf[0]); | |
| 446 } | |
| 447 | |
| 448 JNIEXPORT jboolean JNICALL | |
| 449 FUN(PDFWidget_signNative)(JNIEnv *env, jobject self, jobject jsigner, jint flags, jobject jimage, jstring jreason, jstring jlocation) | |
| 450 { | |
| 451 fz_context *ctx = get_context(env); | |
| 452 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 453 pdf_document *pdf = pdf_annot_page(ctx, widget)->doc; | |
| 454 pdf_pkcs7_signer *signer = from_PKCS7Signer_safe(env, jsigner); | |
| 455 fz_image *image = from_Image_safe(env, jimage); | |
| 456 const char *reason = NULL; | |
| 457 const char *location = NULL; | |
| 458 | |
| 459 if (!ctx || !widget || !pdf) return JNI_FALSE; | |
| 460 if (!signer) jni_throw_arg(env, "signer must not be null"); | |
| 461 | |
| 462 if (jreason) | |
| 463 reason = (*env)->GetStringUTFChars(env, jreason, NULL); | |
| 464 if (jlocation) | |
| 465 location = (*env)->GetStringUTFChars(env, jlocation, NULL); | |
| 466 | |
| 467 fz_try(ctx) | |
| 468 pdf_sign_signature(ctx, widget, signer, flags, image, reason, location); | |
| 469 fz_always(ctx) | |
| 470 { | |
| 471 if (jreason) | |
| 472 (*env)->ReleaseStringUTFChars(env, jreason, reason); | |
| 473 if (jlocation) | |
| 474 (*env)->ReleaseStringUTFChars(env, jlocation, location); | |
| 475 } | |
| 476 fz_catch(ctx) | |
| 477 jni_rethrow(env, ctx); | |
| 478 | |
| 479 return JNI_TRUE; | |
| 480 } | |
| 481 | |
| 482 JNIEXPORT jobject JNICALL | |
| 483 FUN(PDFWidget_previewSignatureNative)(JNIEnv *env, jclass cls, jint width, jint height, jint lang, jobject jsigner, jint flags, jobject jimage, jstring jreason, jstring jlocation) | |
| 484 { | |
| 485 fz_context *ctx = get_context(env); | |
| 486 pdf_pkcs7_signer *signer = from_PKCS7Signer_safe(env, jsigner); | |
| 487 fz_image *image = from_Image_safe(env, jimage); | |
| 488 const char *reason = NULL; | |
| 489 const char *location = NULL; | |
| 490 fz_pixmap *pixmap = NULL; | |
| 491 | |
| 492 if (!ctx) return JNI_FALSE; | |
| 493 if (!signer) jni_throw_arg(env, "signer must not be null"); | |
| 494 | |
| 495 if (jreason) | |
| 496 reason = (*env)->GetStringUTFChars(env, jreason, NULL); | |
| 497 if (jlocation) | |
| 498 location = (*env)->GetStringUTFChars(env, jlocation, NULL); | |
| 499 | |
| 500 fz_var(pixmap); | |
| 501 | |
| 502 fz_try(ctx) | |
| 503 pixmap = pdf_preview_signature_as_pixmap(ctx, | |
| 504 width, height, lang, | |
| 505 signer, flags, image, | |
| 506 reason, location); | |
| 507 fz_always(ctx) | |
| 508 { | |
| 509 if (jreason) | |
| 510 (*env)->ReleaseStringUTFChars(env, jreason, reason); | |
| 511 if (jlocation) | |
| 512 (*env)->ReleaseStringUTFChars(env, jlocation, location); | |
| 513 } | |
| 514 fz_catch(ctx) | |
| 515 jni_rethrow(env, ctx); | |
| 516 | |
| 517 return to_Pixmap_safe_own(ctx, env, pixmap); | |
| 518 } | |
| 519 | |
| 520 JNIEXPORT jobject JNICALL | |
| 521 FUN(PDFWidget_layoutTextWidget)(JNIEnv *env, jobject self) | |
| 522 { | |
| 523 fz_context *ctx = get_context(env); | |
| 524 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 525 fz_layout_block *layout = NULL; | |
| 526 fz_layout_line *line = NULL; | |
| 527 fz_layout_char *chr = NULL; | |
| 528 jobject jlayout, jlines, jmatrix, jinvmatrix; | |
| 529 fz_rect bounds; | |
| 530 fz_matrix mat; | |
| 531 const char *s; | |
| 532 int nlines = 0; | |
| 533 int i; | |
| 534 | |
| 535 if (!ctx || !widget) return NULL; | |
| 536 | |
| 537 jlayout = (*env)->NewObject(env, cls_TextWidgetLayout, mid_TextWidgetLayout_init, self); | |
| 538 if ((*env)->ExceptionCheck(env)) return NULL; | |
| 539 if (!jlayout) jni_throw_run(env, "cannot create text widget layout object"); | |
| 540 | |
| 541 fz_try(ctx) | |
| 542 { | |
| 543 bounds = pdf_bound_widget(ctx, widget); | |
| 544 layout = pdf_layout_text_widget(ctx, widget); | |
| 545 mat = fz_concat(layout->inv_matrix, fz_translate(-bounds.x0, -bounds.y0)); | |
| 546 } | |
| 547 fz_catch(ctx) | |
| 548 jni_rethrow(env, ctx); | |
| 549 | |
| 550 jmatrix = to_Matrix_safe(ctx, env, layout->matrix); | |
| 551 if ((*env)->ExceptionCheck(env)) | |
| 552 { | |
| 553 fz_drop_layout(ctx, layout); | |
| 554 return NULL; | |
| 555 } | |
| 556 if (!jmatrix) | |
| 557 { | |
| 558 fz_drop_layout(ctx, layout); | |
| 559 jni_throw_run(env, "cannot create text widget layout matrix object"); | |
| 560 } | |
| 561 (*env)->SetObjectField(env, jlayout, fid_TextWidgetLayout_matrix, jmatrix); | |
| 562 | |
| 563 jinvmatrix = to_Matrix_safe(ctx, env, layout->inv_matrix); | |
| 564 if ((*env)->ExceptionCheck(env)) | |
| 565 { | |
| 566 fz_drop_layout(ctx, layout); | |
| 567 return NULL; | |
| 568 } | |
| 569 if (!jinvmatrix) | |
| 570 { | |
| 571 fz_drop_layout(ctx, layout); | |
| 572 jni_throw_run(env, "cannot create text widget layout inverted matrix object"); | |
| 573 } | |
| 574 (*env)->SetObjectField(env, jlayout, fid_TextWidgetLayout_invMatrix, jinvmatrix); | |
| 575 | |
| 576 for (line = layout->head; line; line = line->next) | |
| 577 nlines++; | |
| 578 | |
| 579 jlines = (*env)->NewObjectArray(env, nlines, cls_TextWidgetLineLayout, NULL); | |
| 580 if ((*env)->ExceptionCheck(env)) | |
| 581 { | |
| 582 fz_drop_layout(ctx, layout); | |
| 583 return NULL; | |
| 584 } | |
| 585 if (!jlines) | |
| 586 { | |
| 587 fz_drop_layout(ctx, layout); | |
| 588 jni_throw_run(env, "cannot create text widget line layout object"); | |
| 589 } | |
| 590 (*env)->SetObjectField(env, jlayout, fid_TextWidgetLayout_lines, jlines); | |
| 591 | |
| 592 s = layout->head->p; | |
| 593 | |
| 594 i = 0; | |
| 595 for (line = layout->head; line; line = line->next) | |
| 596 { | |
| 597 jobject jlinelayout, jchars, jlrect; | |
| 598 float y = line->y - line->font_size * 0.2f; | |
| 599 float b = line->y + line->font_size; | |
| 600 fz_rect lrect = fz_make_rect(line->x, y, line->x, b); | |
| 601 lrect = fz_transform_rect(lrect, mat); | |
| 602 int nchars = 0; | |
| 603 int k; | |
| 604 | |
| 605 jlinelayout = (*env)->NewObject(env, cls_TextWidgetLineLayout, mid_TextWidgetLineLayout_init, self); | |
| 606 if ((*env)->ExceptionCheck(env)) | |
| 607 { | |
| 608 fz_drop_layout(ctx, layout); | |
| 609 return NULL; | |
| 610 } | |
| 611 if (!jlinelayout) | |
| 612 { | |
| 613 fz_drop_layout(ctx, layout); | |
| 614 jni_throw_run(env, "cannot create text widget line layout object"); | |
| 615 } | |
| 616 | |
| 617 (*env)->SetObjectArrayElement(env, jlines, i, jlinelayout); | |
| 618 if ((*env)->ExceptionCheck(env)) | |
| 619 { | |
| 620 fz_drop_layout(ctx, layout); | |
| 621 return NULL; | |
| 622 } | |
| 623 i++; | |
| 624 | |
| 625 (*env)->SetFloatField(env, jlinelayout, fid_TextWidgetLineLayout_x, line->x); | |
| 626 (*env)->SetFloatField(env, jlinelayout, fid_TextWidgetLineLayout_y, line->y); | |
| 627 (*env)->SetFloatField(env, jlinelayout, fid_TextWidgetLineLayout_fontSize, line->font_size); | |
| 628 (*env)->SetIntField(env, jlinelayout, fid_TextWidgetLineLayout_index, fz_runeidx(s, line->p)); | |
| 629 | |
| 630 for (chr = line->text; chr; chr = chr->next) | |
| 631 nchars++; | |
| 632 | |
| 633 jchars = (*env)->NewObjectArray(env, nchars, cls_TextWidgetCharLayout, NULL); | |
| 634 if (!jchars || (*env)->ExceptionCheck(env)) | |
| 635 { | |
| 636 fz_drop_layout(ctx, layout); | |
| 637 return NULL; | |
| 638 } | |
| 639 (*env)->SetObjectField(env, jlinelayout, fid_TextWidgetLineLayout_chars, jchars); | |
| 640 | |
| 641 k = 0; | |
| 642 for (chr = line->text; chr; chr = chr->next) | |
| 643 { | |
| 644 jobject jcharlayout, jcrect; | |
| 645 fz_rect crect = fz_make_rect(chr->x, y, chr->x + chr->advance, b); | |
| 646 crect = fz_transform_rect(crect, mat); | |
| 647 lrect = fz_union_rect(lrect, crect); | |
| 648 | |
| 649 jcharlayout = (*env)->NewObject(env, cls_TextWidgetCharLayout, mid_TextWidgetCharLayout_init, self); | |
| 650 if ((*env)->ExceptionCheck(env)) | |
| 651 { | |
| 652 fz_drop_layout(ctx, layout); | |
| 653 return NULL; | |
| 654 } | |
| 655 if (!jcharlayout) | |
| 656 { | |
| 657 fz_drop_layout(ctx, layout); | |
| 658 jni_throw_run(env, "cannot create text widget character layout object"); | |
| 659 } | |
| 660 | |
| 661 (*env)->SetObjectArrayElement(env, jchars, k, jcharlayout); | |
| 662 if ((*env)->ExceptionCheck(env)) | |
| 663 { | |
| 664 fz_drop_layout(ctx, layout); | |
| 665 return NULL; | |
| 666 } | |
| 667 k++; | |
| 668 | |
| 669 jcrect = to_Rect_safe(ctx, env, crect); | |
| 670 (*env)->SetObjectField(env, jcharlayout, fid_TextWidgetCharLayout_rect, jcrect); | |
| 671 (*env)->SetFloatField(env, jcharlayout, fid_TextWidgetCharLayout_x, chr->x); | |
| 672 (*env)->SetFloatField(env, jcharlayout, fid_TextWidgetCharLayout_advance, chr->advance); | |
| 673 (*env)->SetIntField(env, jcharlayout, fid_TextWidgetCharLayout_index, fz_runeidx(s, chr->p)); | |
| 674 | |
| 675 (*env)->DeleteLocalRef(env, jcrect); | |
| 676 (*env)->DeleteLocalRef(env, jcharlayout); | |
| 677 } | |
| 678 | |
| 679 jlrect = to_Rect_safe(ctx, env, lrect); | |
| 680 (*env)->SetObjectField(env, jlinelayout, fid_TextWidgetLineLayout_rect, jlrect); | |
| 681 | |
| 682 (*env)->DeleteLocalRef(env, jlrect); | |
| 683 (*env)->DeleteLocalRef(env, jchars); | |
| 684 (*env)->DeleteLocalRef(env, jlinelayout); | |
| 685 } | |
| 686 | |
| 687 fz_drop_layout(ctx, layout); | |
| 688 | |
| 689 return jlayout; | |
| 690 } | |
| 691 | |
| 692 JNIEXPORT jstring JNICALL | |
| 693 FUN(PDFWidget_getLabel)(JNIEnv *env, jobject self) | |
| 694 { | |
| 695 fz_context *ctx = get_context(env); | |
| 696 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 697 const char *text = NULL; | |
| 698 | |
| 699 if (!ctx || !widget) return NULL; | |
| 700 | |
| 701 fz_try(ctx) | |
| 702 text = pdf_annot_field_label(ctx, widget); | |
| 703 fz_catch(ctx) | |
| 704 jni_rethrow(env, ctx); | |
| 705 | |
| 706 return (*env)->NewStringUTF(env, text); | |
| 707 } | |
| 708 | |
| 709 JNIEXPORT jstring JNICALL | |
| 710 FUN(PDFWidget_getName)(JNIEnv *env, jobject self) | |
| 711 { | |
| 712 fz_context *ctx = get_context(env); | |
| 713 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 714 char *name = NULL; | |
| 715 jstring jname; | |
| 716 | |
| 717 if (!ctx || !widget) return NULL; | |
| 718 | |
| 719 fz_try(ctx) | |
| 720 name = pdf_load_field_name(ctx, pdf_annot_obj(ctx, widget)); | |
| 721 fz_catch(ctx) | |
| 722 jni_rethrow(env, ctx); | |
| 723 | |
| 724 jname = (*env)->NewStringUTF(env, name); | |
| 725 fz_free(ctx, name); | |
| 726 if (!jname || (*env)->ExceptionCheck(env)) | |
| 727 jni_throw_run(env, "cannot create widget name string"); | |
| 728 return jname; | |
| 729 } | |
| 730 | |
| 731 JNIEXPORT jboolean JNICALL | |
| 732 FUN(PDFWidget_getEditingState)(JNIEnv *env, jobject self) | |
| 733 { | |
| 734 fz_context *ctx = get_context(env); | |
| 735 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 736 jboolean editing = JNI_FALSE; | |
| 737 | |
| 738 if (!ctx || !widget) return JNI_FALSE; | |
| 739 | |
| 740 fz_try(ctx) | |
| 741 editing = pdf_get_widget_editing_state(ctx, widget); | |
| 742 fz_catch(ctx) | |
| 743 jni_rethrow(env, ctx); | |
| 744 | |
| 745 return editing; | |
| 746 } | |
| 747 | |
| 748 JNIEXPORT void JNICALL | |
| 749 FUN(PDFWidget_setEditingState)(JNIEnv *env, jobject self, jboolean editing) | |
| 750 { | |
| 751 fz_context *ctx = get_context(env); | |
| 752 pdf_annot *widget = from_PDFWidget_safe(env, self); | |
| 753 | |
| 754 if (!ctx || !widget) return; | |
| 755 | |
| 756 fz_try(ctx) | |
| 757 pdf_set_widget_editing_state(ctx, widget, editing); | |
| 758 fz_catch(ctx) | |
| 759 jni_rethrow_void(env, ctx); | |
| 760 } |
