summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2018-07-06 14:20:26 +0200
committerTor Andersson <tor.andersson@artifex.com>2018-08-10 12:09:10 +0200
commit0abcccc4aab4d893ac2a0ef116ff1f0c006fbc30 (patch)
tree8fe312208afaf28e2d759f4a1c53ec4ef131124f
parent6f8cb5606e426084160eaec82e9c11966e7fb5f4 (diff)
downloadmupdf-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.h36
-rw-r--r--include/mupdf/pdf/document.h20
-rw-r--r--platform/gl/gl-main.c7
-rw-r--r--platform/java/mupdf_native.c38
-rw-r--r--platform/java/mupdf_native.h16
-rw-r--r--platform/java/src/com/artifex/mupdf/fitz/PDFAnnotation.java2
-rw-r--r--platform/java/src/com/artifex/mupdf/fitz/PDFPage.java2
-rw-r--r--platform/x11/pdfapp.c39
-rw-r--r--source/pdf/pdf-appearance.c7
-rw-r--r--source/pdf/pdf-form.c3
-rw-r--r--source/tools/murun.c26
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");