summaryrefslogtreecommitdiff
path: root/source/pdf/pdf-annot.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/pdf/pdf-annot.c')
-rw-r--r--source/pdf/pdf-annot.c137
1 files changed, 27 insertions, 110 deletions
diff --git a/source/pdf/pdf-annot.c b/source/pdf/pdf-annot.c
index 3325c828..56b42e48 100644
--- a/source/pdf/pdf-annot.c
+++ b/source/pdf/pdf-annot.c
@@ -400,16 +400,19 @@ pdf_annot_transform(fz_context *ctx, pdf_annot *annot, fz_matrix *annot_ctm)
fz_pre_scale(fz_translate(annot_ctm, x, y), w, h);
}
-pdf_annot *pdf_new_annot(fz_context *ctx, pdf_page *page)
+pdf_annot *pdf_new_annot(fz_context *ctx, pdf_page *page, pdf_obj *obj)
{
- pdf_annot *annot = fz_new_derived_annot(ctx, pdf_annot);
+ pdf_annot *annot;
+
+ annot = fz_new_derived_annot(ctx, pdf_annot);
annot->super.drop_annot = (fz_annot_drop_fn*)pdf_drop_annot_imp;
annot->super.bound_annot = (fz_annot_bound_fn*)pdf_bound_annot;
annot->super.run_annot = (fz_annot_run_fn*)pdf_run_annot;
annot->super.next_annot = (fz_annot_next_fn*)pdf_next_annot;
- annot->page = page;
+ annot->page = page; /* only borrowed, as the page owns the annot */
+ annot->obj = pdf_keep_obj(ctx, obj);
return annot;
}
@@ -417,121 +420,35 @@ pdf_annot *pdf_new_annot(fz_context *ctx, pdf_page *page)
void
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;
-
- fz_var(annot);
- fz_var(itr);
- fz_var(keep_annot);
-
- itr = &page->annots;
-
- len = pdf_array_len(ctx, annots);
- /*
- Create an initial linked list of pdf_annot structures with only the obj field
- filled in. We do this because update_appearance has the potential to change
- the annot array, so we don't want to be iterating through the array while
- that happens.
- */
- fz_try(ctx)
- {
- for (i = 0; i < len; i++)
- {
- obj = pdf_array_get(ctx, annots, i);
-
- annot = pdf_new_annot(ctx, page);
- *itr = annot;
- annot->obj = pdf_keep_obj(ctx, obj);
- itr = &annot->next;
- }
- }
- fz_catch(ctx)
- {
- pdf_drop_annots(ctx, page->annots);
- page->annots = NULL;
- fz_rethrow(ctx);
- }
+ pdf_annot *annot;
+ pdf_obj *subtype;
+ int i, n;
- /*
- Iterate through the newly created annot linked list, using a double pointer to
- facilitate deleting broken annotations.
- */
- itr = &page->annots;
- while (*itr)
+ n = pdf_array_len(ctx, annots);
+ for (i = 0; i < n; ++i)
{
- annot = *itr;
-
- fz_try(ctx)
+ pdf_obj *obj = pdf_array_get(ctx, annots, i);
+ if (obj)
{
- pdf_hotspot *hp = &doc->hotspot;
-
- n = NULL;
-
- 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);
-
- /* We only collect annotations with an appearance
- * stream into this list, so remove any that don't
- * (such as links) and continue. */
- keep_annot = pdf_is_dict(ctx, ap);
- if (!keep_annot)
- break;
-
- if (hp->num == pdf_to_num(ctx, obj) && (hp->state & HOTSPOT_POINTER_DOWN))
+ subtype = pdf_dict_get(ctx, obj, PDF_NAME_Subtype);
+ if (pdf_name_eq(ctx, subtype, PDF_NAME_Link))
+ continue;
+ if (pdf_name_eq(ctx, subtype, PDF_NAME_Popup))
+ continue;
+
+ annot = pdf_new_annot(ctx, page, obj);
+ fz_try(ctx)
{
- n = pdf_dict_get(ctx, ap, PDF_NAME_D); /* down state */
+ pdf_update_annot(ctx, annot);
+ annot->has_new_ap = 0;
}
+ fz_catch(ctx)
+ fz_warn(ctx, "could not update appearance for annotation");
- 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);
-
- annot->ap = NULL;
- annot->has_new_ap = 1;
-
- if (pdf_is_stream(ctx, n))
- {
- annot->ap = pdf_keep_obj(ctx, n);
- }
- else
- fz_warn(ctx, "no appearance stream for annotation %d 0 R", pdf_to_num(ctx, annot->obj));
-
- if (obj == doc->focus_obj)
- doc->focus = annot;
-
- /* Move to next item in the linked list */
- itr = &annot->next;
- }
- fz_catch(ctx)
- {
- if (fz_caught(ctx) == FZ_ERROR_TRYLATER)
- {
- pdf_drop_annots(ctx, page->annots);
- page->annots = NULL;
- fz_rethrow(ctx);
- }
- keep_annot = 0;
- fz_warn(ctx, "ignoring broken annotation");
- }
- if (!keep_annot)
- {
- /* Move to next item in the linked list, dropping this one */
- *itr = annot->next;
- annot->next = NULL; /* Required because pdf_drop_annots follows the "next" chain */
- pdf_drop_annots(ctx, annot);
+ *page->annot_tailp = annot;
+ page->annot_tailp = &annot->next;
}
}
-
- page->annot_tailp = itr;
}
pdf_annot *