diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2016-09-22 16:00:21 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2016-10-07 17:22:58 +0200 |
commit | 8e244f7e2add3606283c0c797d75067fd01ad740 (patch) | |
tree | 1d3d70646b637792865c0b14be37127eb5eef250 /source/pdf | |
parent | 170f35a5802ec7093b00fb2e39bbde3756516f15 (diff) | |
download | mupdf-8e244f7e2add3606283c0c797d75067fd01ad740.tar.xz |
Remove separate tmp/deleted/changed annotation lists.
Use a flag in the pdf_annot struct instead.
Don't pass pdf_document to annotation edit functions.
Diffstat (limited to 'source/pdf')
-rw-r--r-- | source/pdf/pdf-annot-edit.c | 116 | ||||
-rw-r--r-- | source/pdf/pdf-annot.c | 3 | ||||
-rw-r--r-- | source/pdf/pdf-appearance.c | 51 | ||||
-rw-r--r-- | source/pdf/pdf-form.c | 61 | ||||
-rw-r--r-- | source/pdf/pdf-page.c | 9 |
5 files changed, 87 insertions, 153 deletions
diff --git a/source/pdf/pdf-annot-edit.c b/source/pdf/pdf-annot-edit.c index 32c3f353..63a05e1c 100644 --- a/source/pdf/pdf-annot-edit.c +++ b/source/pdf/pdf-annot-edit.c @@ -35,60 +35,11 @@ static const char *annot_type_str(fz_annot_type type) } } -void -pdf_update_annot(fz_context *ctx, pdf_document *doc, pdf_annot *annot) -{ - pdf_obj *obj, *ap, *as, *n; - - if (doc->update_appearance) - doc->update_appearance(ctx, doc, annot); - - obj = annot->obj; - - ap = pdf_dict_get(ctx, obj, PDF_NAME_AP); - as = pdf_dict_get(ctx, obj, PDF_NAME_AS); - - if (pdf_is_dict(ctx, ap)) - { - pdf_hotspot *hp = &doc->hotspot; - - n = NULL; - - if (hp->num == pdf_to_num(ctx, obj) && (hp->state & HOTSPOT_POINTER_DOWN)) - { - n = pdf_dict_get(ctx, ap, PDF_NAME_D); /* down state */ - } - - if (n == NULL) - n = pdf_dict_get(ctx, ap, PDF_NAME_N); /* normal state */ - - /* lookup current state in sub-dictionary */ - if (!pdf_is_stream(ctx, n)) - n = pdf_dict_get(ctx, n, as); - - pdf_drop_xobject(ctx, annot->ap); - annot->ap = NULL; - - if (pdf_is_stream(ctx, n)) - { - fz_try(ctx) - { - annot->ap = pdf_load_xobject(ctx, doc, n); - annot->ap_iteration = annot->ap->iteration; - } - fz_catch(ctx) - { - fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); - fz_warn(ctx, "ignoring broken annotation"); - } - } - } -} - pdf_annot * -pdf_create_annot(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_annot_type type) +pdf_create_annot(fz_context *ctx, pdf_page *page, fz_annot_type type) { pdf_annot *annot = NULL; + pdf_document *doc = page->doc; pdf_obj *annot_obj = pdf_new_dict(ctx, doc, 0); pdf_obj *ind_obj = NULL; @@ -153,11 +104,12 @@ pdf_create_annot(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_annot_ty } void -pdf_delete_annot(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_annot *annot) +pdf_delete_annot(fz_context *ctx, pdf_page *page, pdf_annot *annot) { + pdf_document *doc = annot->page->doc; pdf_annot **annotptr; - pdf_obj *old_annot_arr; pdf_obj *annot_arr; + int i; if (annot == NULL) return; @@ -174,55 +126,35 @@ pdf_delete_annot(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_annot * return; *annotptr = annot->next; + /* If the removed annotation was the last in the list adjust the end pointer */ if (*annotptr == NULL) page->annot_tailp = annotptr; - /* Stick it in the deleted list */ - annot->next = page->deleted_annots; - page->deleted_annots = annot; - - pdf_drop_xobject(ctx, annot->ap); - annot->ap = NULL; - - /* Recreate the "Annots" array with this annot removed */ - old_annot_arr = pdf_dict_get(ctx, page->obj, PDF_NAME_Annots); - - if (old_annot_arr) + /* If the removed annotation has the focus, blur it. */ + if (doc->focus == annot) { - int i, n = pdf_array_len(ctx, old_annot_arr); - annot_arr = pdf_new_array(ctx, doc, n?(n-1):0); + doc->focus = NULL; + doc->focus_obj = NULL; + } - fz_try(ctx) - { - for (i = 0; i < n; i++) - { - pdf_obj *obj = pdf_array_get(ctx, old_annot_arr, i); + /* Remove the annot from the "Annots" array. */ + annot_arr = pdf_dict_get(ctx, page->obj, PDF_NAME_Annots); + i = pdf_array_find(ctx, annot_arr, annot->obj); + if (i >= 0) + pdf_array_delete(ctx, annot_arr, i); - if (obj != annot->obj) - pdf_array_push(ctx, annot_arr, obj); - } + if (pdf_is_indirect(ctx, annot_arr)) + pdf_update_object(ctx, doc, pdf_to_num(ctx, annot_arr), annot_arr); + else + pdf_dict_put(ctx, page->obj, PDF_NAME_Annots, annot_arr); - if (pdf_is_indirect(ctx, old_annot_arr)) - pdf_update_object(ctx, doc, pdf_to_num(ctx, old_annot_arr), annot_arr); - else - pdf_dict_put(ctx, page->obj, PDF_NAME_Annots, annot_arr); + /* The garbage collection pass when saving will remove the annot object, + * removing it here may break files if multiple pages use the same annot. */ - if (pdf_is_indirect(ctx, annot->obj)) - pdf_delete_object(ctx, doc, pdf_to_num(ctx, annot->obj)); - } - fz_always(ctx) - { - pdf_drop_obj(ctx, annot_arr); - } - fz_catch(ctx) - { - fz_rethrow(ctx); - } - } + /* And free it. */ + fz_drop_annot(ctx, (fz_annot*)annot); - pdf_drop_obj(ctx, annot->obj); - annot->obj = NULL; doc->dirty = 1; } diff --git a/source/pdf/pdf-annot.c b/source/pdf/pdf-annot.c index d1ca7de0..ae6bd907 100644 --- a/source/pdf/pdf-annot.c +++ b/source/pdf/pdf-annot.c @@ -502,8 +502,9 @@ pdf_annot *pdf_new_annot(fz_context *ctx, pdf_page *page) } void -pdf_load_annots(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_obj *annots) +pdf_load_annots(fz_context *ctx, pdf_page *page, pdf_obj *annots) { + pdf_document *doc = page->doc; pdf_annot *annot, **itr; pdf_obj *obj, *ap, *as, *n; int i, len, keep_annot; diff --git a/source/pdf/pdf-appearance.c b/source/pdf/pdf-appearance.c index f22c97c8..5982ca88 100644 --- a/source/pdf/pdf-appearance.c +++ b/source/pdf/pdf-appearance.c @@ -2527,3 +2527,54 @@ void pdf_update_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *annot) pdf_clean_obj(ctx, obj); } } + +void +pdf_update_annot(fz_context *ctx, pdf_annot *annot) +{ + pdf_document *doc = annot->page->doc; + pdf_obj *obj, *ap, *as, *n; + + if (doc->update_appearance) + doc->update_appearance(ctx, doc, annot); + + obj = annot->obj; + + ap = pdf_dict_get(ctx, obj, PDF_NAME_AP); + as = pdf_dict_get(ctx, obj, PDF_NAME_AS); + + if (pdf_is_dict(ctx, ap)) + { + pdf_hotspot *hp = &doc->hotspot; + + n = NULL; + + if (hp->num == pdf_to_num(ctx, obj) && (hp->state & HOTSPOT_POINTER_DOWN)) + { + n = pdf_dict_get(ctx, ap, PDF_NAME_D); /* down state */ + } + + if (n == NULL) + n = pdf_dict_get(ctx, ap, PDF_NAME_N); /* normal state */ + + /* lookup current state in sub-dictionary */ + if (!pdf_is_stream(ctx, n)) + n = pdf_dict_get(ctx, n, as); + + pdf_drop_xobject(ctx, annot->ap); + annot->ap = NULL; + + if (pdf_is_stream(ctx, n)) + { + fz_try(ctx) + { + annot->ap = pdf_load_xobject(ctx, doc, n); + annot->ap_iteration = annot->ap->iteration; + } + fz_catch(ctx) + { + fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); + fz_warn(ctx, "ignoring broken annotation"); + } + } + } +} diff --git a/source/pdf/pdf-form.c b/source/pdf/pdf-form.c index 045e1b86..9dc40f30 100644 --- a/source/pdf/pdf-form.c +++ b/source/pdf/pdf-form.c @@ -667,24 +667,15 @@ int pdf_pass_event(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_ui_ev return changed; } -void pdf_update_page(fz_context *ctx, pdf_document *doc, pdf_page *page) +void pdf_update_page(fz_context *ctx, pdf_page *page) { pdf_annot *annot; /* Reset changed_annots to empty */ - page->changed_annots = NULL; - - /* - Free all annots in tmp_annots, since these were - referenced only from changed_annots. - */ - if (page->tmp_annots) - { - pdf_drop_annots(ctx, page->tmp_annots); - page->tmp_annots = NULL; - } + for (annot = page->annots; annot; annot = annot->next) + annot->changed = 0; - /* Add all changed annots to the list */ + /* Flag all changed annots */ for (annot = page->annots; annot; annot = annot->next) { pdf_xobject *ap = pdf_keep_xobject(ctx, annot->ap); @@ -692,51 +683,15 @@ void pdf_update_page(fz_context *ctx, pdf_document *doc, pdf_page *page) fz_try(ctx) { - pdf_update_annot(ctx, doc, annot); - + pdf_update_annot(ctx, annot); if ((ap != annot->ap || ap_iteration != annot->ap_iteration)) - { - annot->next_changed = page->changed_annots; - page->changed_annots = annot; - } + annot->changed = 1; } fz_always(ctx) - { pdf_drop_xobject(ctx, ap); - } fz_catch(ctx) - { fz_rethrow(ctx); - } } - - /* - Add all deleted annots to the list, since these also - warrant a screen update - */ - for (annot = page->deleted_annots; annot; annot = annot->next) - { - annot->next_changed = page->changed_annots; - page->changed_annots = annot; - } - - /* - Move deleted_annots to tmp_annots to keep them separate - from any future deleted ones. They cannot yet be freed - since they are linked into changed_annots - */ - page->tmp_annots = page->deleted_annots; - page->deleted_annots = NULL; -} - -pdf_annot *pdf_poll_changed_annot(fz_context *ctx, pdf_document *idoc, pdf_page *page) -{ - pdf_annot *annot = page->changed_annots; - - if (annot) - page->changed_annots = annot->next_changed; - - return annot; } pdf_widget *pdf_focused_widget(fz_context *ctx, pdf_document *doc) @@ -771,7 +726,7 @@ pdf_widget *pdf_create_widget(fz_context *ctx, pdf_document *doc, pdf_page *page { pdf_obj *form = NULL; int old_sigflags = pdf_to_int(ctx, pdf_dict_getp(ctx, pdf_trailer(ctx, doc), "Root/AcroForm/SigFlags")); - pdf_annot *annot = pdf_create_annot(ctx, doc, page, PDF_ANNOT_WIDGET); + pdf_annot *annot = pdf_create_annot(ctx, page, PDF_ANNOT_WIDGET); fz_try(ctx) { @@ -799,7 +754,7 @@ pdf_widget *pdf_create_widget(fz_context *ctx, pdf_document *doc, pdf_page *page } fz_catch(ctx) { - pdf_delete_annot(ctx, doc, page, annot); + pdf_delete_annot(ctx, page, annot); /* An empty Fields array may have been created, but that is harmless */ diff --git a/source/pdf/pdf-page.c b/source/pdf/pdf-page.c index dae0d49d..73d01480 100644 --- a/source/pdf/pdf-page.c +++ b/source/pdf/pdf-page.c @@ -511,10 +511,7 @@ pdf_drop_page_imp(fz_context *ctx, pdf_page *page) fz_drop_link(ctx, page->links); if (page->annots) pdf_drop_annots(ctx, page->annots); - if (page->deleted_annots) - pdf_drop_annots(ctx, page->deleted_annots); - if (page->tmp_annots) - pdf_drop_annots(ctx, page->tmp_annots); + /* doc->focus, when not NULL, refers to one of * the annotations and must be NULLed when the * annotations are destroyed. doc->focus_obj @@ -551,8 +548,6 @@ pdf_new_page(fz_context *ctx, pdf_document *doc) page->links = NULL; page->annots = NULL; page->annot_tailp = &page->annots; - page->deleted_annots = NULL; - page->tmp_annots = NULL; page->incomplete = 0; return page; @@ -587,7 +582,7 @@ pdf_load_page(fz_context *ctx, pdf_document *doc, int number) fz_matrix page_ctm; pdf_page_transform(ctx, page, &page_mediabox, &page_ctm); page->links = pdf_load_link_annots(ctx, doc, obj, &page_ctm); - pdf_load_annots(ctx, doc, page, obj); + pdf_load_annots(ctx, page, obj); } } fz_catch(ctx) |