summaryrefslogtreecommitdiff
path: root/source/pdf
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2016-09-22 16:00:21 +0200
committerTor Andersson <tor.andersson@artifex.com>2016-10-07 17:22:58 +0200
commit8e244f7e2add3606283c0c797d75067fd01ad740 (patch)
tree1d3d70646b637792865c0b14be37127eb5eef250 /source/pdf
parent170f35a5802ec7093b00fb2e39bbde3756516f15 (diff)
downloadmupdf-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.c116
-rw-r--r--source/pdf/pdf-annot.c3
-rw-r--r--source/pdf/pdf-appearance.c51
-rw-r--r--source/pdf/pdf-form.c61
-rw-r--r--source/pdf/pdf-page.c9
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)