", "(FFFFC)V");
if (ctor == NULL) return NULL;
fz_var(sheet);
fz_var(text);
fz_var(dev);
fz_try(ctx)
{
int b, l, s, c;
zoom = glo->resolution / 72;
fz_scale(&ctm, zoom, zoom);
sheet = fz_new_text_sheet(ctx);
text = fz_new_text_page(ctx);
dev = fz_new_text_device(ctx, sheet, text);
fz_run_page(doc, pc->page, dev, &ctm, NULL);
fz_free_device(dev);
dev = NULL;
barr = (*env)->NewObjectArray(env, text->len, textBlockClass, NULL);
if (barr == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "NewObjectArray failed");
for (b = 0; b < text->len; b++)
{
fz_text_block *block;
jobjectArray *larr;
if (text->blocks[b].type != FZ_PAGE_BLOCK_TEXT)
continue;
block = text->blocks[b].u.text;
larr = (*env)->NewObjectArray(env, block->len, textLineClass, NULL);
if (larr == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "NewObjectArray failed");
for (l = 0; l < block->len; l++)
{
fz_text_line *line = &block->lines[l];
jobjectArray *sarr;
fz_text_span *span;
int len = 0;
for (span = line->first_span; span; span = span->next)
len++;
sarr = (*env)->NewObjectArray(env, len, textSpanClass, NULL);
if (sarr == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "NewObjectArray failed");
for (s=0, span = line->first_span; span; s++, span = span->next)
{
jobjectArray *carr = (*env)->NewObjectArray(env, span->len, textCharClass, NULL);
if (carr == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "NewObjectArray failed");
for (c = 0; c < span->len; c++)
{
fz_text_char *ch = &span->text[c];
fz_rect bbox;
fz_text_char_bbox(&bbox, span, c);
jobject cobj = (*env)->NewObject(env, textCharClass, ctor, bbox.x0, bbox.y0, bbox.x1, bbox.y1, ch->c);
if (cobj == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "NewObjectfailed");
(*env)->SetObjectArrayElement(env, carr, c, cobj);
(*env)->DeleteLocalRef(env, cobj);
}
(*env)->SetObjectArrayElement(env, sarr, s, carr);
(*env)->DeleteLocalRef(env, carr);
}
(*env)->SetObjectArrayElement(env, larr, l, sarr);
(*env)->DeleteLocalRef(env, sarr);
}
(*env)->SetObjectArrayElement(env, barr, b, larr);
(*env)->DeleteLocalRef(env, larr);
}
}
fz_always(ctx)
{
fz_free_text_page(ctx, text);
fz_free_text_sheet(ctx, sheet);
fz_free_device(dev);
}
fz_catch(ctx)
{
jclass cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
if (cls != NULL)
(*env)->ThrowNew(env, cls, "Out of memory in MuPDFCore_text");
(*env)->DeleteLocalRef(env, cls);
return NULL;
}
return barr;
}
JNIEXPORT jbyteArray JNICALL
JNI_FN(MuPDFCore_textAsHtml)(JNIEnv * env, jobject thiz)
{
fz_text_sheet *sheet = NULL;
fz_text_page *text = NULL;
fz_device *dev = NULL;
fz_matrix ctm;
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
fz_document *doc = glo->doc;
page_cache *pc = &glo->pages[glo->current];
jbyteArray bArray = NULL;
fz_buffer *buf = NULL;
fz_output *out = NULL;
fz_var(sheet);
fz_var(text);
fz_var(dev);
fz_try(ctx)
{
int b, l, s, c;
ctm = fz_identity;
sheet = fz_new_text_sheet(ctx);
text = fz_new_text_page(ctx);
dev = fz_new_text_device(ctx, sheet, text);
fz_run_page(doc, pc->page, dev, &ctm, NULL);
fz_free_device(dev);
dev = NULL;
fz_analyze_text(ctx, sheet, text);
buf = fz_new_buffer(ctx, 256);
out = fz_new_output_with_buffer(ctx, buf);
fz_printf(out, "\n");
fz_printf(out, "\n");
fz_printf(out, "");
fz_print_text_page_html(ctx, out, text);
fz_printf(out, "
\n");
fz_printf(out, "\n\n");
fz_close_output(out);
out = NULL;
bArray = (*env)->NewByteArray(env, buf->len);
if (bArray == NULL)
fz_throw(ctx, FZ_ERROR_GENERIC, "Failed to make byteArray");
(*env)->SetByteArrayRegion(env, bArray, 0, buf->len, buf->data);
}
fz_always(ctx)
{
fz_free_text_page(ctx, text);
fz_free_text_sheet(ctx, sheet);
fz_free_device(dev);
fz_close_output(out);
fz_drop_buffer(ctx, buf);
}
fz_catch(ctx)
{
jclass cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
if (cls != NULL)
(*env)->ThrowNew(env, cls, "Out of memory in MuPDFCore_textAsHtml");
(*env)->DeleteLocalRef(env, cls);
return NULL;
}
return bArray;
}
JNIEXPORT void JNICALL
JNI_FN(MuPDFCore_addMarkupAnnotationInternal)(JNIEnv * env, jobject thiz, jobjectArray points, fz_annot_type type)
{
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
fz_document *doc = glo->doc;
pdf_document *idoc = pdf_specifics(doc);
page_cache *pc = &glo->pages[glo->current];
jclass pt_cls;
jfieldID x_fid, y_fid;
int i, n;
fz_point *pts = NULL;
float color[3];
float alpha;
float line_height;
float line_thickness;
if (idoc == NULL)
return;
switch (type)
{
case FZ_ANNOT_HIGHLIGHT:
color[0] = 1.0;
color[1] = 1.0;
color[2] = 0.0;
alpha = 0.5;
line_thickness = 1.0;
line_height = 0.5;
break;
case FZ_ANNOT_UNDERLINE:
color[0] = 0.0;
color[1] = 0.0;
color[2] = 1.0;
alpha = 1.0;
line_thickness = LINE_THICKNESS;
line_height = UNDERLINE_HEIGHT;
break;
case FZ_ANNOT_STRIKEOUT:
color[0] = 1.0;
color[1] = 0.0;
color[2] = 0.0;
alpha = 1.0;
line_thickness = LINE_THICKNESS;
line_height = STRIKE_HEIGHT;
break;
default:
return;
}
fz_var(pts);
fz_try(ctx)
{
fz_annot *annot;
fz_matrix ctm;
float zoom = glo->resolution / 72;
zoom = 1.0 / zoom;
fz_scale(&ctm, zoom, zoom);
pt_cls = (*env)->FindClass(env, "android.graphics.PointF");
if (pt_cls == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "FindClass");
x_fid = (*env)->GetFieldID(env, pt_cls, "x", "F");
if (x_fid == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "GetFieldID(x)");
y_fid = (*env)->GetFieldID(env, pt_cls, "y", "F");
if (y_fid == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "GetFieldID(y)");
n = (*env)->GetArrayLength(env, points);
pts = fz_malloc_array(ctx, n, sizeof(fz_point));
for (i = 0; i < n; i++)
{
jobject opt = (*env)->GetObjectArrayElement(env, points, i);
pts[i].x = opt ? (*env)->GetFloatField(env, opt, x_fid) : 0.0f;
pts[i].y = opt ? (*env)->GetFloatField(env, opt, y_fid) : 0.0f;
fz_transform_point(&pts[i], &ctm);
}
annot = (fz_annot *)pdf_create_annot(idoc, (pdf_page *)pc->page, type);
pdf_set_markup_annot_quadpoints(idoc, (pdf_annot *)annot, pts, n);
pdf_set_markup_appearance(idoc, (pdf_annot *)annot, color, alpha, line_thickness, line_height);
dump_annotation_display_lists(glo);
}
fz_always(ctx)
{
fz_free(ctx, pts);
}
fz_catch(ctx)
{
LOGE("addStrikeOutAnnotation: %s failed", ctx->error->message);
jclass cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
if (cls != NULL)
(*env)->ThrowNew(env, cls, "Out of memory in MuPDFCore_searchPage");
(*env)->DeleteLocalRef(env, cls);
}
}
JNIEXPORT void JNICALL
JNI_FN(MuPDFCore_addInkAnnotationInternal)(JNIEnv * env, jobject thiz, jobjectArray arcs)
{
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
fz_document *doc = glo->doc;
pdf_document *idoc = pdf_specifics(doc);
page_cache *pc = &glo->pages[glo->current];
jclass pt_cls;
jfieldID x_fid, y_fid;
int i, j, k, n;
fz_point *pts = NULL;
int *counts = NULL;
int total = 0;
float color[3];
if (idoc == NULL)
return;
color[0] = 1.0;
color[1] = 0.0;
color[2] = 0.0;
fz_var(pts);
fz_var(counts);
fz_try(ctx)
{
fz_annot *annot;
fz_matrix ctm;
float zoom = glo->resolution / 72;
zoom = 1.0 / zoom;
fz_scale(&ctm, zoom, zoom);
pt_cls = (*env)->FindClass(env, "android.graphics.PointF");
if (pt_cls == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "FindClass");
x_fid = (*env)->GetFieldID(env, pt_cls, "x", "F");
if (x_fid == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "GetFieldID(x)");
y_fid = (*env)->GetFieldID(env, pt_cls, "y", "F");
if (y_fid == NULL) fz_throw(ctx, FZ_ERROR_GENERIC, "GetFieldID(y)");
n = (*env)->GetArrayLength(env, arcs);
counts = fz_malloc_array(ctx, n, sizeof(int));
for (i = 0; i < n; i++)
{
jobjectArray arc = (jobjectArray)(*env)->GetObjectArrayElement(env, arcs, i);
int count = (*env)->GetArrayLength(env, arc);
counts[i] = count;
total += count;
}
pts = fz_malloc_array(ctx, total, sizeof(fz_point));
k = 0;
for (i = 0; i < n; i++)
{
jobjectArray arc = (jobjectArray)(*env)->GetObjectArrayElement(env, arcs, i);
int count = counts[i];
for (j = 0; j < count; j++)
{
jobject pt = (*env)->GetObjectArrayElement(env, arc, j);
pts[k].x = pt ? (*env)->GetFloatField(env, pt, x_fid) : 0.0f;
pts[k].y = pt ? (*env)->GetFloatField(env, pt, y_fid) : 0.0f;
fz_transform_point(&pts[k], &ctm);
k++;
}
}
annot = (fz_annot *)pdf_create_annot(idoc, (pdf_page *)pc->page, FZ_ANNOT_INK);
pdf_set_ink_annot_list(idoc, (pdf_annot *)annot, pts, counts, n, color, INK_THICKNESS);
dump_annotation_display_lists(glo);
}
fz_always(ctx)
{
fz_free(ctx, pts);
fz_free(ctx, counts);
}
fz_catch(ctx)
{
LOGE("addInkAnnotation: %s failed", ctx->error->message);
jclass cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
if (cls != NULL)
(*env)->ThrowNew(env, cls, "Out of memory in MuPDFCore_searchPage");
(*env)->DeleteLocalRef(env, cls);
}
}
JNIEXPORT void JNICALL
JNI_FN(MuPDFCore_deleteAnnotationInternal)(JNIEnv * env, jobject thiz, int annot_index)
{
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
fz_document *doc = glo->doc;
pdf_document *idoc = pdf_specifics(doc);
page_cache *pc = &glo->pages[glo->current];
fz_annot *annot;
int i;
if (idoc == NULL)
return;
fz_try(ctx)
{
annot = fz_first_annot(glo->doc, pc->page);
for (i = 0; i < annot_index && annot; i++)
annot = fz_next_annot(glo->doc, annot);
if (annot)
{
pdf_delete_annot(idoc, (pdf_page *)pc->page, (pdf_annot *)annot);
dump_annotation_display_lists(glo);
}
}
fz_catch(ctx)
{
LOGE("deleteAnnotationInternal: %s", ctx->error->message);
}
}
/* Close the document, at least enough to be able to save over it. This
* may be called again later, so must be idempotent. */
static void close_doc(globals *glo)
{
int i;
fz_free(glo->ctx, glo->hit_bbox);
glo->hit_bbox = NULL;
for (i = 0; i < NUM_CACHE; i++)
drop_page_cache(glo, &glo->pages[i]);
alerts_fin(glo);
fz_close_document(glo->doc);
glo->doc = NULL;
}
JNIEXPORT void JNICALL
JNI_FN(MuPDFCore_destroying)(JNIEnv * env, jobject thiz)
{
globals *glo = get_globals(env, thiz);
if (glo == NULL)
return;
LOGI("Destroying");
fz_free(glo->ctx, glo->current_path);
glo->current_path = NULL;
close_doc(glo);
fz_free_context(glo->ctx);
glo->ctx = NULL;
free(glo);
#ifdef MEMENTO
LOGI("Destroying dump start");
Memento_listBlocks();
Memento_stats();
LOGI("Destroying dump end");
#endif
#ifdef NDK_PROFILER
// Apparently we should really be writing to whatever path we get
// from calling getFilesDir() in the java part, which supposedly
// gives /sdcard/data/data/com.artifex.MuPDF/gmon.out, but that's
// unfriendly.
setenv("CPUPROFILE", "/sdcard/gmon.out", 1);
moncleanup();
#endif
}
JNIEXPORT jobjectArray JNICALL
JNI_FN(MuPDFCore_getPageLinksInternal)(JNIEnv * env, jobject thiz, int pageNumber)
{
jclass linkInfoClass;
jclass linkInfoInternalClass;
jclass linkInfoExternalClass;
jclass linkInfoRemoteClass;
jmethodID ctorInternal;
jmethodID ctorExternal;
jmethodID ctorRemote;
jobjectArray arr;
jobject linkInfo;
fz_matrix ctm;
float zoom;
fz_link *list;
fz_link *link;
int count;
page_cache *pc;
globals *glo = get_globals(env, thiz);
linkInfoClass = (*env)->FindClass(env, PACKAGENAME "/LinkInfo");
if (linkInfoClass == NULL) return NULL;
linkInfoInternalClass = (*env)->FindClass(env, PACKAGENAME "/LinkInfoInternal");
if (linkInfoInternalClass == NULL) return NULL;
linkInfoExternalClass = (*env)->FindClass(env, PACKAGENAME "/LinkInfoExternal");
if (linkInfoExternalClass == NULL) return NULL;
linkInfoRemoteClass = (*env)->FindClass(env, PACKAGENAME "/LinkInfoRemote");
if (linkInfoRemoteClass == NULL) return NULL;
ctorInternal = (*env)->GetMethodID(env, linkInfoInternalClass, "", "(FFFFI)V");
if (ctorInternal == NULL) return NULL;
ctorExternal = (*env)->GetMethodID(env, linkInfoExternalClass, "", "(FFFFLjava/lang/String;)V");
if (ctorExternal == NULL) return NULL;
ctorRemote = (*env)->GetMethodID(env, linkInfoRemoteClass, "", "(FFFFLjava/lang/String;IZ)V");
if (ctorRemote == NULL) return NULL;
JNI_FN(MuPDFCore_gotoPageInternal)(env, thiz, pageNumber);
pc = &glo->pages[glo->current];
if (pc->page == NULL || pc->number != pageNumber)
return NULL;
zoom = glo->resolution / 72;
fz_scale(&ctm, zoom, zoom);
list = fz_load_links(glo->doc, pc->page);
count = 0;
for (link = list; link; link = link->next)
{
switch (link->dest.kind)
{
case FZ_LINK_GOTO:
case FZ_LINK_GOTOR:
case FZ_LINK_URI:
count++ ;
}
}
arr = (*env)->NewObjectArray(env, count, linkInfoClass, NULL);
if (arr == NULL)
{
fz_drop_link(glo->ctx, list);
return NULL;
}
count = 0;
for (link = list; link; link = link->next)
{
fz_rect rect = link->rect;
fz_transform_rect(&rect, &ctm);
switch (link->dest.kind)
{
case FZ_LINK_GOTO:
{
linkInfo = (*env)->NewObject(env, linkInfoInternalClass, ctorInternal,
(float)rect.x0, (float)rect.y0, (float)rect.x1, (float)rect.y1,
link->dest.ld.gotor.page);
break;
}
case FZ_LINK_GOTOR:
{
jstring juri = (*env)->NewStringUTF(env, link->dest.ld.gotor.file_spec);
linkInfo = (*env)->NewObject(env, linkInfoRemoteClass, ctorRemote,
(float)rect.x0, (float)rect.y0, (float)rect.x1, (float)rect.y1,
juri, link->dest.ld.gotor.page, link->dest.ld.gotor.new_window ? JNI_TRUE : JNI_FALSE);
break;
}
case FZ_LINK_URI:
{
jstring juri = (*env)->NewStringUTF(env, link->dest.ld.uri.uri);
linkInfo = (*env)->NewObject(env, linkInfoExternalClass, ctorExternal,
(float)rect.x0, (float)rect.y0, (float)rect.x1, (float)rect.y1,
juri);
break;
}
default:
continue;
}
if (linkInfo == NULL)
{
fz_drop_link(glo->ctx, list);
return NULL;
}
(*env)->SetObjectArrayElement(env, arr, count, linkInfo);
(*env)->DeleteLocalRef(env, linkInfo);
count++;
}
fz_drop_link(glo->ctx, list);
return arr;
}
JNIEXPORT jobjectArray JNICALL
JNI_FN(MuPDFCore_getWidgetAreasInternal)(JNIEnv * env, jobject thiz, int pageNumber)
{
jclass rectFClass;
jmethodID ctor;
jobjectArray arr;
jobject rectF;
pdf_document *idoc;
pdf_widget *widget;
fz_matrix ctm;
float zoom;
int count;
page_cache *pc;
globals *glo = get_globals(env, thiz);
rectFClass = (*env)->FindClass(env, "android/graphics/RectF");
if (rectFClass == NULL) return NULL;
ctor = (*env)->GetMethodID(env, rectFClass, "", "(FFFF)V");
if (ctor == NULL) return NULL;
JNI_FN(MuPDFCore_gotoPageInternal)(env, thiz, pageNumber);
pc = &glo->pages[glo->current];
if (pc->number != pageNumber || pc->page == NULL)
return NULL;
idoc = pdf_specifics(glo->doc);
if (idoc == NULL)
return NULL;
zoom = glo->resolution / 72;
fz_scale(&ctm, zoom, zoom);
count = 0;
for (widget = pdf_first_widget(idoc, (pdf_page *)pc->page); widget; widget = pdf_next_widget(widget))
count ++;
arr = (*env)->NewObjectArray(env, count, rectFClass, NULL);
if (arr == NULL) return NULL;
count = 0;
for (widget = pdf_first_widget(idoc, (pdf_page *)pc->page); widget; widget = pdf_next_widget(widget))
{
fz_rect rect;
pdf_bound_widget(widget, &rect);
fz_transform_rect(&rect, &ctm);
rectF = (*env)->NewObject(env, rectFClass, ctor,
(float)rect.x0, (float)rect.y0, (float)rect.x1, (float)rect.y1);
if (rectF == NULL) return NULL;
(*env)->SetObjectArrayElement(env, arr, count, rectF);
(*env)->DeleteLocalRef(env, rectF);
count ++;
}
return arr;
}
JNIEXPORT jobjectArray JNICALL
JNI_FN(MuPDFCore_getAnnotationsInternal)(JNIEnv * env, jobject thiz, int pageNumber)
{
jclass annotClass;
jmethodID ctor;
jobjectArray arr;
jobject jannot;
fz_annot *annot;
fz_matrix ctm;
float zoom;
int count;
page_cache *pc;
globals *glo = get_globals(env, thiz);
annotClass = (*env)->FindClass(env, PACKAGENAME "/Annotation");
if (annotClass == NULL) return NULL;
ctor = (*env)->GetMethodID(env, annotClass, "", "(FFFFI)V");
if (ctor == NULL) return NULL;
JNI_FN(MuPDFCore_gotoPageInternal)(env, thiz, pageNumber);
pc = &glo->pages[glo->current];
if (pc->number != pageNumber || pc->page == NULL)
return NULL;
zoom = glo->resolution / 72;
fz_scale(&ctm, zoom, zoom);
count = 0;
for (annot = fz_first_annot(glo->doc, pc->page); annot; annot = fz_next_annot(glo->doc, annot))
count ++;
arr = (*env)->NewObjectArray(env, count, annotClass, NULL);
if (arr == NULL) return NULL;
count = 0;
for (annot = fz_first_annot(glo->doc, pc->page); annot; annot = fz_next_annot(glo->doc, annot))
{
fz_rect rect;
fz_annot_type type = pdf_annot_type((pdf_annot *)annot);
fz_bound_annot(glo->doc, annot, &rect);
fz_transform_rect(&rect, &ctm);
jannot = (*env)->NewObject(env, annotClass, ctor,
(float)rect.x0, (float)rect.y0, (float)rect.x1, (float)rect.y1, type);
if (jannot == NULL) return NULL;
(*env)->SetObjectArrayElement(env, arr, count, jannot);
(*env)->DeleteLocalRef(env, jannot);
count ++;
}
return arr;
}
JNIEXPORT int JNICALL
JNI_FN(MuPDFCore_passClickEventInternal)(JNIEnv * env, jobject thiz, int pageNumber, float x, float y)
{
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
fz_matrix ctm;
pdf_document *idoc = pdf_specifics(glo->doc);
float zoom;
fz_point p;
pdf_ui_event event;
int changed = 0;
page_cache *pc;
if (idoc == NULL)
return 0;
JNI_FN(MuPDFCore_gotoPageInternal)(env, thiz, pageNumber);
pc = &glo->pages[glo->current];
if (pc->number != pageNumber || pc->page == NULL)
return 0;
p.x = x;
p.y = y;
/* Ultimately we should probably return a pointer to a java structure
* with the link details in, but for now, page number will suffice.
*/
zoom = glo->resolution / 72;
fz_scale(&ctm, zoom, zoom);
fz_invert_matrix(&ctm, &ctm);
fz_transform_point(&p, &ctm);
fz_try(ctx)
{
event.etype = PDF_EVENT_TYPE_POINTER;
event.event.pointer.pt = p;
event.event.pointer.ptype = PDF_POINTER_DOWN;
changed = pdf_pass_event(idoc, (pdf_page *)pc->page, &event);
event.event.pointer.ptype = PDF_POINTER_UP;
changed |= pdf_pass_event(idoc, (pdf_page *)pc->page, &event);
if (changed) {
dump_annotation_display_lists(glo);
}
}
fz_catch(ctx)
{
LOGE("passClickEvent: %s", ctx->error->message);
}
return changed;
}
JNIEXPORT jstring JNICALL
JNI_FN(MuPDFCore_getFocusedWidgetTextInternal)(JNIEnv * env, jobject thiz)
{
char *text = "";
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
fz_try(ctx)
{
pdf_document *idoc = pdf_specifics(glo->doc);
if (idoc)
{
pdf_widget *focus = pdf_focused_widget(idoc);
if (focus)
text = pdf_text_widget_text(idoc, focus);
}
}
fz_catch(ctx)
{
LOGE("getFocusedWidgetText failed: %s", ctx->error->message);
}
return (*env)->NewStringUTF(env, text);
}
JNIEXPORT int JNICALL
JNI_FN(MuPDFCore_setFocusedWidgetTextInternal)(JNIEnv * env, jobject thiz, jstring jtext)
{
const char *text;
int result = 0;
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
text = (*env)->GetStringUTFChars(env, jtext, NULL);
if (text == NULL)
{
LOGE("Failed to get text");
return 0;
}
fz_try(ctx)
{
pdf_document *idoc = pdf_specifics(glo->doc);
if (idoc)
{
pdf_widget *focus = pdf_focused_widget(idoc);
if (focus)
{
result = pdf_text_widget_set_text(idoc, focus, (char *)text);
dump_annotation_display_lists(glo);
}
}
}
fz_catch(ctx)
{
LOGE("setFocusedWidgetText failed: %s", ctx->error->message);
}
(*env)->ReleaseStringUTFChars(env, jtext, text);
return result;
}
JNIEXPORT jobjectArray JNICALL
JNI_FN(MuPDFCore_getFocusedWidgetChoiceOptions)(JNIEnv * env, jobject thiz)
{
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
pdf_document *idoc = pdf_specifics(glo->doc);
pdf_widget *focus;
int type;
int nopts, i;
char **opts = NULL;
jclass stringClass;
jobjectArray arr;
if (idoc == NULL)
return NULL;
focus = pdf_focused_widget(idoc);
if (focus == NULL)
return NULL;
type = pdf_widget_get_type(focus);
if (type != PDF_WIDGET_TYPE_LISTBOX && type != PDF_WIDGET_TYPE_COMBOBOX)
return NULL;
fz_var(opts);
fz_try(ctx)
{
nopts = pdf_choice_widget_options(idoc, focus, NULL);
opts = fz_malloc(ctx, nopts * sizeof(*opts));
(void)pdf_choice_widget_options(idoc, focus, opts);
}
fz_catch(ctx)
{
fz_free(ctx, opts);
LOGE("Failed in getFocuseedWidgetChoiceOptions");
return NULL;
}
stringClass = (*env)->FindClass(env, "java/lang/String");
arr = (*env)->NewObjectArray(env, nopts, stringClass, NULL);
for (i = 0; i < nopts; i++)
{
jstring s = (*env)->NewStringUTF(env, opts[i]);
if (s != NULL)
(*env)->SetObjectArrayElement(env, arr, i, s);
(*env)->DeleteLocalRef(env, s);
}
fz_free(ctx, opts);
return arr;
}
JNIEXPORT jobjectArray JNICALL
JNI_FN(MuPDFCore_getFocusedWidgetChoiceSelected)(JNIEnv * env, jobject thiz)
{
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
pdf_document *idoc = pdf_specifics(glo->doc);
pdf_widget *focus;
int type;
int nsel, i;
char **sel = NULL;
jclass stringClass;
jobjectArray arr;
if (idoc == NULL)
return NULL;
focus = pdf_focused_widget(idoc);
if (focus == NULL)
return NULL;
type = pdf_widget_get_type(focus);
if (type != PDF_WIDGET_TYPE_LISTBOX && type != PDF_WIDGET_TYPE_COMBOBOX)
return NULL;
fz_var(sel);
fz_try(ctx)
{
nsel = pdf_choice_widget_value(idoc, focus, NULL);
sel = fz_malloc(ctx, nsel * sizeof(*sel));
(void)pdf_choice_widget_value(idoc, focus, sel);
}
fz_catch(ctx)
{
fz_free(ctx, sel);
LOGE("Failed in getFocuseedWidgetChoiceOptions");
return NULL;
}
stringClass = (*env)->FindClass(env, "java/lang/String");
arr = (*env)->NewObjectArray(env, nsel, stringClass, NULL);
for (i = 0; i < nsel; i++)
{
jstring s = (*env)->NewStringUTF(env, sel[i]);
if (s != NULL)
(*env)->SetObjectArrayElement(env, arr, i, s);
(*env)->DeleteLocalRef(env, s);
}
fz_free(ctx, sel);
return arr;
}
JNIEXPORT void JNICALL
JNI_FN(MuPDFCore_setFocusedWidgetChoiceSelectedInternal)(JNIEnv * env, jobject thiz, jobjectArray arr)
{
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
pdf_document *idoc = pdf_specifics(glo->doc);
pdf_widget *focus;
int type;
int nsel, i;
char **sel = NULL;
jstring *objs = NULL;
if (idoc == NULL)
return;
focus = pdf_focused_widget(idoc);
if (focus == NULL)
return;
type = pdf_widget_get_type(focus);
if (type != PDF_WIDGET_TYPE_LISTBOX && type != PDF_WIDGET_TYPE_COMBOBOX)
return;
nsel = (*env)->GetArrayLength(env, arr);
sel = calloc(nsel, sizeof(*sel));
objs = calloc(nsel, sizeof(*objs));
if (objs == NULL || sel == NULL)
{
free(sel);
free(objs);
LOGE("Failed in setFocusWidgetChoiceSelected");
return;
}
for (i = 0; i < nsel; i++)
{
objs[i] = (jstring)(*env)->GetObjectArrayElement(env, arr, i);
sel[i] = (char *)(*env)->GetStringUTFChars(env, objs[i], NULL);
}
fz_try(ctx)
{
pdf_choice_widget_set_value(idoc, focus, nsel, sel);
dump_annotation_display_lists(glo);
}
fz_catch(ctx)
{
LOGE("Failed in setFocusWidgetChoiceSelected");
}
for (i = 0; i < nsel; i++)
(*env)->ReleaseStringUTFChars(env, objs[i], sel[i]);
free(sel);
free(objs);
}
JNIEXPORT int JNICALL
JNI_FN(MuPDFCore_getFocusedWidgetTypeInternal)(JNIEnv * env, jobject thiz)
{
globals *glo = get_globals(env, thiz);
pdf_document *idoc = pdf_specifics(glo->doc);
pdf_widget *focus;
if (idoc == NULL)
return NONE;
focus = pdf_focused_widget(idoc);
if (focus == NULL)
return NONE;
switch (pdf_widget_get_type(focus))
{
case PDF_WIDGET_TYPE_TEXT: return TEXT;
case PDF_WIDGET_TYPE_LISTBOX: return LISTBOX;
case PDF_WIDGET_TYPE_COMBOBOX: return COMBOBOX;
}
return NONE;
}
JNIEXPORT jobject JNICALL
JNI_FN(MuPDFCore_waitForAlertInternal)(JNIEnv * env, jobject thiz)
{
globals *glo = get_globals(env, thiz);
jclass alertClass;
jmethodID ctor;
jstring title;
jstring message;
int alert_present;
pdf_alert_event alert;
LOGT("Enter waitForAlert");
pthread_mutex_lock(&glo->fin_lock);
pthread_mutex_lock(&glo->alert_lock);
while (glo->alerts_active && !glo->alert_request)
pthread_cond_wait(&glo->alert_request_cond, &glo->alert_lock);
glo->alert_request = 0;
alert_present = (glo->alerts_active && glo->current_alert);
if (alert_present)
alert = *glo->current_alert;
pthread_mutex_unlock(&glo->alert_lock);
pthread_mutex_unlock(&glo->fin_lock);
LOGT("Exit waitForAlert %d", alert_present);
if (!alert_present)
return NULL;
alertClass = (*env)->FindClass(env, PACKAGENAME "/MuPDFAlertInternal");
if (alertClass == NULL)
return NULL;
ctor = (*env)->GetMethodID(env, alertClass, "", "(Ljava/lang/String;IILjava/lang/String;I)V");
if (ctor == NULL)
return NULL;
title = (*env)->NewStringUTF(env, alert.title);
if (title == NULL)
return NULL;
message = (*env)->NewStringUTF(env, alert.message);
if (message == NULL)
return NULL;
return (*env)->NewObject(env, alertClass, ctor, message, alert.icon_type, alert.button_group_type, title, alert.button_pressed);
}
JNIEXPORT void JNICALL
JNI_FN(MuPDFCore_replyToAlertInternal)(JNIEnv * env, jobject thiz, jobject alert)
{
globals *glo = get_globals(env, thiz);
jclass alertClass;
jfieldID field;
int button_pressed;
alertClass = (*env)->FindClass(env, PACKAGENAME "/MuPDFAlertInternal");
if (alertClass == NULL)
return;
field = (*env)->GetFieldID(env, alertClass, "buttonPressed", "I");
if (field == NULL)
return;
button_pressed = (*env)->GetIntField(env, alert, field);
LOGT("Enter replyToAlert");
pthread_mutex_lock(&glo->alert_lock);
if (glo->alerts_active && glo->current_alert)
{
// Fill in button_pressed and signal reply received.
glo->current_alert->button_pressed = button_pressed;
glo->alert_reply = 1;
pthread_cond_signal(&glo->alert_reply_cond);
}
pthread_mutex_unlock(&glo->alert_lock);
LOGT("Exit replyToAlert");
}
JNIEXPORT void JNICALL
JNI_FN(MuPDFCore_startAlertsInternal)(JNIEnv * env, jobject thiz)
{
globals *glo = get_globals(env, thiz);
if (!glo->alerts_initialised)
return;
LOGT("Enter startAlerts");
pthread_mutex_lock(&glo->alert_lock);
glo->alert_reply = 0;
glo->alert_request = 0;
glo->alerts_active = 1;
glo->current_alert = NULL;
pthread_mutex_unlock(&glo->alert_lock);
LOGT("Exit startAlerts");
}
JNIEXPORT void JNICALL
JNI_FN(MuPDFCore_stopAlertsInternal)(JNIEnv * env, jobject thiz)
{
globals *glo = get_globals(env, thiz);
if (!glo->alerts_initialised)
return;
LOGT("Enter stopAlerts");
pthread_mutex_lock(&glo->alert_lock);
glo->alert_reply = 0;
glo->alert_request = 0;
glo->alerts_active = 0;
glo->current_alert = NULL;
pthread_cond_signal(&glo->alert_reply_cond);
pthread_cond_signal(&glo->alert_request_cond);
pthread_mutex_unlock(&glo->alert_lock);
LOGT("Exit stopAleerts");
}
JNIEXPORT jboolean JNICALL
JNI_FN(MuPDFCore_hasChangesInternal)(JNIEnv * env, jobject thiz)
{
globals *glo = get_globals(env, thiz);
pdf_document *idoc = pdf_specifics(glo->doc);
return (idoc && pdf_has_unsaved_changes(idoc)) ? JNI_TRUE : JNI_FALSE;
}
static char *tmp_path(char *path)
{
int f;
char *buf = malloc(strlen(path) + 6 + 1);
if (!buf)
return NULL;
strcpy(buf, path);
strcat(buf, "XXXXXX");
f = mkstemp(buf);
if (f >= 0)
{
close(f);
return buf;
}
else
{
free(buf);
return NULL;
}
}
JNIEXPORT void JNICALL
JNI_FN(MuPDFCore_saveInternal)(JNIEnv * env, jobject thiz)
{
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
if (glo->doc && glo->current_path)
{
char *tmp;
fz_write_options opts;
opts.do_incremental = 1;
opts.do_ascii = 0;
opts.do_expand = 0;
opts.do_garbage = 0;
opts.do_linear = 0;
tmp = tmp_path(glo->current_path);
if (tmp)
{
int written = 0;
fz_var(written);
fz_try(ctx)
{
FILE *fin = fopen(glo->current_path, "rb");
FILE *fout = fopen(tmp, "wb");
char buf[256];
int n, err = 1;
if (fin && fout)
{
while ((n = fread(buf, 1, sizeof(buf), fin)) > 0)
fwrite(buf, 1, n, fout);
err = (ferror(fin) || ferror(fout));
}
if (fin)
fclose(fin);
if (fout)
fclose(fout);
if (!err)
{
fz_write_document(glo->doc, tmp, &opts);
written = 1;
}
}
fz_catch(ctx)
{
written = 0;
}
if (written)
{
close_doc(glo);
rename(tmp, glo->current_path);
}
free(tmp);
}
}
}
JNIEXPORT void JNICALL
JNI_FN(MuPDFCore_dumpMemoryInternal)(JNIEnv * env, jobject thiz)
{
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
#ifdef MEMENTO
LOGE("dumpMemoryInternal start");
Memento_listNewBlocks();
Memento_stats();
LOGE("dumpMemoryInternal end");
#endif
}
mupdf-1.3-source/platform/android/local.properties.sample 0000664 0000000 0000000 00000000437 12202675360 0023731 0 ustar 00root root 0000000 0000000 # Uncomment and edit the appropriate line below.
# Resave this file as local.properties.
# For MacOS/Linux you want a line such as:
#sdk.dir=/Library/android-sdk-mac_x86
# For Windows/Cygwin you want something like the following:
#sdk.dir=C:\\Program Files (x86)\\Android\\android-sdk
mupdf-1.3-source/platform/android/project.properties 0000664 0000000 0000000 00000000551 12202675360 0023022 0 ustar 00root root 0000000 0000000 # This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "ant.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-11
mupdf-1.3-source/platform/android/res/ 0000775 0000000 0000000 00000000000 12202675360 0020026 5 ustar 00root root 0000000 0000000 mupdf-1.3-source/platform/android/res/animator/ 0000775 0000000 0000000 00000000000 12202675360 0021640 5 ustar 00root root 0000000 0000000 mupdf-1.3-source/platform/android/res/animator/info.xml 0000664 0000000 0000000 00000000732 12202675360 0023317 0 ustar 00root root 0000000 0000000
mupdf-1.3-source/platform/android/res/drawable-hdpi/ 0000775 0000000 0000000 00000000000 12202675360 0022531 5 ustar 00root root 0000000 0000000 mupdf-1.3-source/platform/android/res/drawable-hdpi/icon.png 0000664 0000000 0000000 00000011267 12202675360 0024176 0 ustar 00root root 0000000 0000000 PNG
IHDR H H Uí³G gAMA ħüa sRGB Îé cHRM z&