summaryrefslogtreecommitdiff
path: root/android/jni
diff options
context:
space:
mode:
authorPaul Gardiner <paulg.artifex@glidos.net>2013-01-30 18:39:27 +0000
committerRobin Watts <robin.watts@artifex.com>2013-01-31 11:17:41 +0000
commitcbf75f8b27794290c6bd18ccc0a2cbc79abc49cb (patch)
tree4186095acd838b8cc99fad0255c6150ec3e8fc3d /android/jni
parentcea4109277d5e558f4cfa0707aee7e371ed06504 (diff)
downloadmupdf-cbf75f8b27794290c6bd18ccc0a2cbc79abc49cb.tar.xz
Android: use a single fz_page to render both main and hq bitmaps
Diffstat (limited to 'android/jni')
-rw-r--r--android/jni/mupdf.c114
1 files changed, 70 insertions, 44 deletions
diff --git a/android/jni/mupdf.c b/android/jni/mupdf.c
index f0a625eb..b22b4c69 100644
--- a/android/jni/mupdf.c
+++ b/android/jni/mupdf.c
@@ -41,6 +41,14 @@ enum
COMBOBOX
};
+typedef struct rect_node_s rect_node;
+
+struct rect_node_s
+{
+ fz_rect rect;
+ rect_node *next;
+};
+
typedef struct
{
int number;
@@ -48,7 +56,8 @@ typedef struct
int height;
fz_rect media_box;
fz_page *page;
- fz_page *hq_page;
+ rect_node *changed_rects;
+ rect_node *hq_changed_rects;
fz_display_list *page_list;
fz_display_list *annot_list;
} page_cache;
@@ -100,6 +109,19 @@ struct globals_s
static jfieldID global_fid;
static jfieldID buffer_fid;
+static void drop_changed_rects(fz_context *ctx, rect_node **nodePtr)
+{
+ rect_node *node = *nodePtr;
+ while (node)
+ {
+ rect_node *tnode = node;
+ node = node->next;
+ fz_free(ctx, tnode);
+ }
+
+ *nodePtr = NULL;
+}
+
static void drop_page_cache(globals *glo, page_cache *pc)
{
fz_context *ctx = glo->ctx;
@@ -112,19 +134,8 @@ static void drop_page_cache(globals *glo, page_cache *pc)
pc->annot_list = NULL;
fz_free_page(doc, pc->page);
pc->page = NULL;
- fz_free_page(doc, pc->hq_page);
- pc->hq_page = NULL;
-}
-
-static void clear_hq_pages(globals *glo)
-{
- int i;
- fz_document *doc = glo->doc;
-
- for (i = 0; i < NUM_CACHE; i++) {
- fz_free_page(doc, glo->pages[i].hq_page);
- glo->pages[i].hq_page = NULL;
- }
+ drop_changed_rects(ctx, &pc->changed_rects);
+ drop_changed_rects(ctx, &pc->hq_changed_rects);
}
static void dump_annotation_display_lists(globals *glo)
@@ -527,6 +538,25 @@ JNI_FN(MuPDFCore_javascriptSupported)(JNIEnv *env, jobject thiz)
return fz_javascript_supported();
}
+static void update_changed_rects(globals *glo, page_cache *pc, fz_interactive *idoc)
+{
+ fz_annot *annot;
+
+ fz_update_page(idoc, pc->page);
+ while ((annot = fz_poll_changed_annot(idoc, pc->page)) != NULL)
+ {
+ rect_node *node = fz_malloc_struct(glo->ctx, rect_node);
+ node->rect = fz_bound_annot(glo->doc, annot);
+ node->next = pc->changed_rects;
+ pc->changed_rects = node;
+
+ node = fz_malloc_struct(glo->ctx, rect_node);
+ node->rect = fz_bound_annot(glo->doc, annot);
+ node->next = pc->hq_changed_rects;
+ pc->hq_changed_rects = node;
+ }
+}
+
JNIEXPORT jboolean JNICALL
JNI_FN(MuPDFCore_drawPage)(JNIEnv *env, jobject thiz, jobject bitmap,
int pageW, int pageH, int patchX, int patchY, int patchW, int patchH)
@@ -579,23 +609,14 @@ JNI_FN(MuPDFCore_drawPage)(JNIEnv *env, jobject thiz, jobject bitmap,
{
fz_interactive *idoc = fz_interact(doc);
- // Call fz_update_page now to ensure future calls yield the
- // changes from the current state
if (idoc)
- fz_update_page(idoc, pc->page);
-
- if (hq) {
- // This is a rendering of the hq patch. Ensure there's a second copy of the
- // page for use when updating this patch
- if (pc->hq_page) {
- if (idoc)
- fz_update_page(idoc, pc->hq_page);
- } else {
- // There is only ever one hq patch, so we need
- // cache only one page object for the sake of hq
- clear_hq_pages(glo);
- pc->hq_page = fz_load_page(doc, pc->number);
- }
+ {
+ /* Update the changed-rects for both hq patch and main bitmap */
+ update_changed_rects(glo, pc, idoc);
+
+ /* Then drop the changed-rects for the bitmap we're about to
+ render because we are rendering the entire area */
+ drop_changed_rects(ctx, hq ? &pc->hq_changed_rects : &pc->changed_rects);
}
if (pc->page_list == NULL)
@@ -709,6 +730,7 @@ JNI_FN(MuPDFCore_updatePageInternal)(JNIEnv *env, jobject thiz, jobject bitmap,
globals *glo = get_globals(env, thiz);
fz_context *ctx = glo->ctx;
fz_document *doc = glo->doc;
+ rect_node *crect;
for (i = 0; i < NUM_CACHE; i++)
{
@@ -719,8 +741,10 @@ JNI_FN(MuPDFCore_updatePageInternal)(JNIEnv *env, jobject thiz, jobject bitmap,
}
}
- if (pc == NULL || (hq && pc->hq_page == NULL))
+ if (pc == NULL)
{
+ /* Without a cached page object we cannot perform a partial update so
+ render the entire bitmap instead */
JNI_FN(MuPDFCore_gotoPageInternal)(env, thiz, page);
return JNI_FN(MuPDFCore_drawPage)(env, thiz, bitmap, pageW, pageH, patchX, patchY, patchW, patchH);
}
@@ -755,19 +779,19 @@ JNI_FN(MuPDFCore_updatePageInternal)(JNIEnv *env, jobject thiz, jobject bitmap,
fz_try(ctx)
{
fz_annot *annot;
- // Unimportant which page object we use for rendering but we
- // must use the correct one for calculating updates
- fz_page *page = hq ? pc->hq_page : pc->page;
if (idoc)
- fz_update_page(idoc, page);
+ {
+ /* Update the changed-rects for both hq patch and main bitmap */
+ update_changed_rects(glo, pc, idoc);
+ }
if (pc->page_list == NULL)
{
/* Render to list */
pc->page_list = fz_new_display_list(ctx);
dev = fz_new_list_device(ctx, pc->page_list);
- fz_run_page_contents(doc, page, dev, fz_identity, NULL);
+ fz_run_page_contents(doc, pc->page, dev, fz_identity, NULL);
}
if (pc->annot_list == NULL) {
@@ -777,8 +801,8 @@ JNI_FN(MuPDFCore_updatePageInternal)(JNIEnv *env, jobject thiz, jobject bitmap,
}
pc->annot_list = fz_new_display_list(ctx);
dev = fz_new_list_device(ctx, pc->annot_list);
- for (annot = fz_first_annot(doc, page); annot; annot = fz_next_annot(doc, annot))
- fz_run_annot(doc, page, annot, dev, fz_identity, NULL);
+ for (annot = fz_first_annot(doc, pc->page); annot; annot = fz_next_annot(doc, annot))
+ fz_run_annot(doc, pc->page, annot, dev, fz_identity, NULL);
}
bbox.x0 = patchX;
@@ -797,16 +821,15 @@ JNI_FN(MuPDFCore_updatePageInternal)(JNIEnv *env, jobject thiz, jobject bitmap,
ctm = fz_concat(ctm, fz_scale(xscale, yscale));
rect = fz_transform_rect(ctm, pc->media_box);
- LOGI("Start polling for updates");
- while (idoc && (annot = fz_poll_changed_annot(idoc, page)) != NULL)
+ LOGI("Start partial update");
+ for (crect = hq ? pc->hq_changed_rects : pc->changed_rects; crect; crect = crect->next)
{
fz_bbox abox;
- fz_rect arect = fz_transform_rect(ctm, fz_bound_annot(doc, annot));
+ fz_rect arect = fz_transform_rect(ctm, crect->rect);
arect = fz_intersect_rect(arect, rect);
abox = fz_round_rect(arect);
- LOGI("Update rectangle for %s - (%d, %d, %d, %d)", widget_type_string(fz_widget_get_type((fz_widget*)annot)),
- arect.x0, arect.y0, arect.x1, arect.y1);
+ LOGI("Update rectangle (%d, %d, %d, %d)", abox.x0, abox.y0, abox.x1, abox.y1);
if (!fz_is_empty_rect(abox))
{
LOGI("And it isn't empty");
@@ -820,7 +843,10 @@ JNI_FN(MuPDFCore_updatePageInternal)(JNIEnv *env, jobject thiz, jobject bitmap,
dev = NULL;
}
}
- LOGI("Done polling for updates");
+ LOGI("End partial update");
+
+ /* Drop the changed rects we've just rendered */
+ drop_changed_rects(ctx, hq ? &pc->hq_changed_rects : &pc->changed_rects);
LOGE("Rendered");
}