diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2018-07-06 14:20:26 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2018-08-10 12:09:10 +0200 |
commit | 0abcccc4aab4d893ac2a0ef116ff1f0c006fbc30 (patch) | |
tree | 8fe312208afaf28e2d759f4a1c53ec4ef131124f | |
parent | 6f8cb5606e426084160eaec82e9c11966e7fb5f4 (diff) | |
download | mupdf-0abcccc4aab4d893ac2a0ef116ff1f0c006fbc30.tar.xz |
Rejig pdf_update_page and pdf_update_annot.
The intent is for a user to iterate over the annotations on a page calling
pdf_update_annot for each one. If this function returns true, then the
annotation has changed since the last time it was called, and the user
needs to re-render.
pdf_update_page is a simple loop over the annotations on a page, for use
if you only care about page level granularity.
Users should no longer look at or change the pdf_annot.has_new_ap field.
-rw-r--r-- | include/mupdf/pdf/annot.h | 36 | ||||
-rw-r--r-- | include/mupdf/pdf/document.h | 20 | ||||
-rw-r--r-- | platform/gl/gl-main.c | 7 | ||||
-rw-r--r-- | platform/java/mupdf_native.c | 38 | ||||
-rw-r--r-- | platform/java/mupdf_native.h | 16 | ||||
-rw-r--r-- | platform/java/src/com/artifex/mupdf/fitz/PDFAnnotation.java | 2 | ||||
-rw-r--r-- | platform/java/src/com/artifex/mupdf/fitz/PDFPage.java | 2 | ||||
-rw-r--r-- | platform/x11/pdfapp.c | 39 | ||||
-rw-r--r-- | source/pdf/pdf-appearance.c | 7 | ||||
-rw-r--r-- | source/pdf/pdf-form.c | 3 | ||||
-rw-r--r-- | source/tools/murun.c | 26 |
11 files changed, 127 insertions, 69 deletions
diff --git a/include/mupdf/pdf/annot.h b/include/mupdf/pdf/annot.h index 5a97c4d5..adaf51c6 100644 --- a/include/mupdf/pdf/annot.h +++ b/include/mupdf/pdf/annot.h @@ -134,7 +134,6 @@ fz_link *pdf_load_link_annots(fz_context *ctx, pdf_document *, pdf_obj *annots, fz_matrix pdf_annot_transform(fz_context *ctx, pdf_annot *annot); void pdf_load_annots(fz_context *ctx, pdf_page *page, pdf_obj *annots); -void pdf_update_annot(fz_context *ctx, pdf_annot *annot); void pdf_drop_annots(fz_context *ctx, pdf_annot *annot_list); /* @@ -261,10 +260,41 @@ void pdf_set_annot_default_appearance(fz_context *ctx, pdf_annot *annot, const c pdf_new_annot: Internal function for creating a new pdf annotation. */ pdf_annot *pdf_new_annot(fz_context *ctx, pdf_page *page, pdf_obj *obj); - -void pdf_update_appearance(fz_context *ctx, pdf_annot *annot); void pdf_dirty_annot(fz_context *ctx, pdf_annot *annot); +/* + Recreate the appearance stream for an annotation. +*/ +void pdf_update_appearance(fz_context *ctx, pdf_annot *annot); void pdf_update_signature_appearance(fz_context *ctx, pdf_annot *annot, const char *name, const char *text, const char *date); +/* + Regenerate any appearance streams that are out of date and check for + cases where a different appearance stream should be selected because of + state changes. + + Note that a call to pdf_pass_event for one page may lead to changes on + any other, so an app should call pdf_update_annot for every annotation + it currently displays. Also it is important that the pdf_annot object + is the one used to last render the annotation. If instead the app were + to drop the page or annotations and reload them then a call to + pdf_update_annot would not reliably be able to report all changed + annotations. + + Returns true if the annotation appearance has changed since the last time + pdf_update_annot was called or the annotation was first loaded. +*/ +int pdf_update_annot(fz_context *ctx, pdf_annot *annot); + +/* + Loop through all annotations on the page and update them. Return true + if any of them were changed (by either event or javascript actions, or + by annotation editing) and need re-rendering. + + If you need more granularity, loop through the annotations and call + pdf_update_annot for each one to detect changes on a per-annotation + basis. +*/ +int pdf_update_page(fz_context *ctx, pdf_page *page); + #endif diff --git a/include/mupdf/pdf/document.h b/include/mupdf/pdf/document.h index 24e3aaed..9e9121df 100644 --- a/include/mupdf/pdf/document.h +++ b/include/mupdf/pdf/document.h @@ -514,26 +514,6 @@ int pdf_add_portfolio_entry(fz_context *ctx, pdf_document *doc, void pdf_set_portfolio_entry_info(fz_context *ctx, pdf_document *doc, int entry, int schema_entry, pdf_obj *data); /* - pdf_update_page: Update a page for the sake of changes caused by a call - to pdf_pass_event or annotation editing functions. - - pdf_update_page regenerates any appearance streams that are out of - date, checks for cases where different appearance streams should be - selected because of state changes, and records internally each - annotation that has changed appearance. - - Each annotation that has changed has its has_new_ap flag set to true. - - Note that a call to pdf_pass_event for one page may lead to changes on - any other, so an app should call pdf_update_page for every page it - currently displays. Also it is important that the pdf_page object is - the one used to last render the page. If instead the app were to drop - the page and reload it then a call to pdf_update_page would not - reliably be able to report all changed areas. -*/ -int pdf_update_page(fz_context *ctx, pdf_page *page); - -/* Determine whether changes have been made since the document was opened or last saved. */ diff --git a/platform/gl/gl-main.c b/platform/gl/gl-main.c index ed1591e4..5b5ae2b8 100644 --- a/platform/gl/gl-main.c +++ b/platform/gl/gl-main.c @@ -260,13 +260,6 @@ void render_page(void) fz_gamma_pixmap(ctx, pix, 1 / 1.4f); } - if (pdf) - { - pdf_annot *annot; - for (annot = page->annots; annot; annot = annot->next) - annot->has_new_ap = 0; - } - ui_texture_from_pixmap(&page_tex, pix); fz_drop_pixmap(ctx, pix); } diff --git a/platform/java/mupdf_native.c b/platform/java/mupdf_native.c index 07331db4..1af5cb1f 100644 --- a/platform/java/mupdf_native.c +++ b/platform/java/mupdf_native.c @@ -8761,6 +8761,23 @@ FUN(PDFPage_deleteAnnotation)(JNIEnv *env, jobject self, jobject jannot) jni_rethrow(env, ctx); } +JNIEXPORT jboolean JNICALL +FUN(PDFPage_update)(JNIEnv *env, jobject self) +{ + fz_context *ctx = get_context(env); + pdf_page *page = from_PDFPage(env, self); + jboolean changed = 0; + + if (!ctx || !page) return 0; + + fz_try(ctx) + changed = pdf_update_page(ctx, page); + fz_catch(ctx) + jni_rethrow(env, ctx); + + return changed; +} + /* PDFAnnotation interface */ JNIEXPORT jint JNICALL @@ -9211,15 +9228,28 @@ FUN(PDFAnnotation_updateAppearance)(JNIEnv *env, jobject self) if (!ctx || !annot) return; fz_try(ctx) - { - pdf_dict_del(ctx, annot->obj, PDF_NAME(AP)); /* nuke old AP */ pdf_update_appearance(ctx, annot); - pdf_update_annot(ctx, annot); /* ensure new AP is put into annot */ - } fz_catch(ctx) jni_rethrow(env, ctx); } +JNIEXPORT jboolean JNICALL +FUN(PDFAnnotation_update)(JNIEnv *env, jobject self) +{ + fz_context *ctx = get_context(env); + pdf_annot *annot = from_PDFAnnotation(env, self); + jboolean changed = 0; + + if (!ctx || !annot) return 0; + + fz_try(ctx) + changed = pdf_update_annot(ctx, annot); + fz_catch(ctx) + jni_rethrow(env, ctx); + + return changed; +} + JNIEXPORT jobject JNICALL FUN(PDFAnnotation_getInkList)(JNIEnv *env, jobject self) { diff --git a/platform/java/mupdf_native.h b/platform/java/mupdf_native.h index 37ea6ed2..07eac765 100644 --- a/platform/java/mupdf_native.h +++ b/platform/java/mupdf_native.h @@ -1689,6 +1689,14 @@ JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_setIsOpen JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_updateAppearance (JNIEnv *, jobject); +/* + * Class: com_artifex_mupdf_fitz_PDFAnnotation + * Method: update + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_com_artifex_mupdf_fitz_PDFAnnotation_update + (JNIEnv *, jobject); + #ifdef __cplusplus } #endif @@ -2469,6 +2477,14 @@ JNIEXPORT jobject JNICALL Java_com_artifex_mupdf_fitz_PDFPage_createAnnotation JNIEXPORT void JNICALL Java_com_artifex_mupdf_fitz_PDFPage_deleteAnnotation (JNIEnv *, jobject, jobject); +/* + * Class: com_artifex_mupdf_fitz_PDFPage + * Method: update + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_com_artifex_mupdf_fitz_PDFPage_update + (JNIEnv *, jobject); + #ifdef __cplusplus } #endif diff --git a/platform/java/src/com/artifex/mupdf/fitz/PDFAnnotation.java b/platform/java/src/com/artifex/mupdf/fitz/PDFAnnotation.java index 2e4a83cd..93c564b6 100644 --- a/platform/java/src/com/artifex/mupdf/fitz/PDFAnnotation.java +++ b/platform/java/src/com/artifex/mupdf/fitz/PDFAnnotation.java @@ -92,4 +92,6 @@ public class PDFAnnotation extends Annotation public native void setIsOpen(boolean open); public native void updateAppearance(); + + public native boolean update(); } diff --git a/platform/java/src/com/artifex/mupdf/fitz/PDFPage.java b/platform/java/src/com/artifex/mupdf/fitz/PDFPage.java index ca63d54a..ac8c6688 100644 --- a/platform/java/src/com/artifex/mupdf/fitz/PDFPage.java +++ b/platform/java/src/com/artifex/mupdf/fitz/PDFPage.java @@ -10,4 +10,6 @@ public class PDFPage extends Page public native PDFAnnotation createAnnotation(int subtype); public native void deleteAnnotation(Annotation annot); + + public native boolean update(); } diff --git a/platform/x11/pdfapp.c b/platform/x11/pdfapp.c index 01011b2b..22fb7f1b 100644 --- a/platform/x11/pdfapp.c +++ b/platform/x11/pdfapp.c @@ -799,40 +799,15 @@ static void pdfapp_runpage(pdfapp_t *app, fz_device *dev, const fz_matrix ctm, f static void pdfapp_updatepage(pdfapp_t *app) { - fz_device *idev; - fz_matrix ctm; - pdf_annot *pannot; - - pdfapp_viewctm(&ctm, app); - pdf_update_page(app->ctx, (pdf_page *)app->page); - pdfapp_recreate_annotationslist(app); - - for (pannot = pdf_first_annot(app->ctx, (pdf_page*)app->page); pannot; pannot = pdf_next_annot(app->ctx, pannot)) + if (pdf_update_page(app->ctx, (pdf_page*)app->page)) { - if (pannot->has_new_ap) - { - fz_annot *annot = (fz_annot*)pannot; - fz_rect bounds; - fz_irect ibounds; - bounds = fz_transform_rect(fz_bound_annot(app->ctx, annot), ctm); - ibounds = fz_round_rect(bounds); - bounds = fz_rect_from_irect(ibounds); - fz_clear_pixmap_rect_with_value(app->ctx, app->image, 255, ibounds); - idev = fz_new_draw_device_with_bbox(app->ctx, fz_identity, app->image, &ibounds); - fz_try(app->ctx) - { - pdfapp_runpage(app, idev, ctm, bounds, NULL); - fz_close_device(app->ctx, idev); - } - fz_always(app->ctx) - fz_drop_device(app->ctx, idev); - fz_catch(app->ctx) - fz_rethrow(app->ctx); - pannot->has_new_ap = 0; - } + pdfapp_recreate_annotationslist(app); + pdfapp_showpage(app, 0, 1, 1, 0, 0); + } + else + { + pdfapp_showpage(app, 0, 0, 1, 0, 0); } - - pdfapp_showpage(app, 0, 0, 1, 0, 0); } void pdfapp_reloadpage(pdfapp_t *app) diff --git a/source/pdf/pdf-appearance.c b/source/pdf/pdf-appearance.c index 67a01fa9..fb5b8343 100644 --- a/source/pdf/pdf-appearance.c +++ b/source/pdf/pdf-appearance.c @@ -1373,11 +1373,12 @@ void pdf_update_appearance(fz_context *ctx, pdf_annot *annot) } } -void +int pdf_update_annot(fz_context *ctx, pdf_annot *annot) { pdf_document *doc = annot->page->doc; pdf_obj *obj, *ap, *as, *n; + int changed = 0; /* TODO: handle form field updates without using the annot pdf_obj dirty flag */ obj = annot->obj; @@ -1415,4 +1416,8 @@ pdf_update_annot(fz_context *ctx, pdf_annot *annot) annot->has_new_ap = 1; } } + + changed = annot->has_new_ap; + annot->has_new_ap = 0; + return changed; } diff --git a/source/pdf/pdf-form.c b/source/pdf/pdf-form.c index 8521d63d..d6969ce7 100644 --- a/source/pdf/pdf-form.c +++ b/source/pdf/pdf-form.c @@ -633,8 +633,7 @@ pdf_update_page(fz_context *ctx, pdf_page *page) int changed = 0; for (annot = page->annots; annot; annot = annot->next) { - pdf_update_annot(ctx, annot); - if (annot->has_new_ap) + if (pdf_update_annot(ctx, annot)) changed = 1; } return changed; diff --git a/source/tools/murun.c b/source/tools/murun.c index c6ad673f..02144df4 100644 --- a/source/tools/murun.c +++ b/source/tools/murun.c @@ -4040,6 +4040,18 @@ static void ffi_PDFPage_deleteAnnotation(js_State *J) rethrow(J); } +static void ffi_PDFPage_update(js_State *J) +{ + fz_context *ctx = js_getcontext(J); + pdf_page *page = js_touserdata(J, 0, "pdf_page"); + int changed = 0; + fz_try(ctx) + changed = pdf_update_page(ctx, page); + fz_catch(ctx) + rethrow(J); + js_pushboolean(J, changed); +} + static void ffi_PDFAnnotation_getType(js_State *J) { fz_context *ctx = js_getcontext(J); @@ -4435,6 +4447,18 @@ static void ffi_PDFAnnotation_updateAppearance(js_State *J) rethrow(J); } +static void ffi_PDFAnnotation_update(js_State *J) +{ + fz_context *ctx = js_getcontext(J); + pdf_annot *annot = js_touserdata(J, 0, "pdf_annot"); + int changed = 0; + fz_try(ctx) + changed = pdf_update_annot(ctx, annot); + fz_catch(ctx) + rethrow(J); + js_pushboolean(J, changed); +} + #endif /* FZ_ENABLE_PDF */ int murun_main(int argc, char **argv) @@ -4737,6 +4761,7 @@ int murun_main(int argc, char **argv) { jsB_propfun(J, "PDFPage.createAnnotation", ffi_PDFPage_createAnnotation, 1); jsB_propfun(J, "PDFPage.deleteAnnotation", ffi_PDFPage_deleteAnnotation, 1); + jsB_propfun(J, "PDFPage.update", ffi_PDFPage_update, 0); } js_setregistry(J, "pdf_page"); @@ -4765,6 +4790,7 @@ int murun_main(int argc, char **argv) jsB_propfun(J, "PDFAnnotation.getModificationDate", ffi_PDFAnnotation_getModificationDate, 0); jsB_propfun(J, "PDFAnnotation.setModificationDate", ffi_PDFAnnotation_setModificationDate, 0); jsB_propfun(J, "PDFAnnotation.updateAppearance", ffi_PDFAnnotation_updateAppearance, 0); + jsB_propfun(J, "PDFAnnotation.update", ffi_PDFAnnotation_update, 0); } js_setregistry(J, "pdf_annot"); |