diff options
Diffstat (limited to 'source/pdf/pdf-annot.c')
-rw-r--r-- | source/pdf/pdf-annot.c | 137 |
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 * |