/* SumatraPDF: synthesize appearance streams for a few more annotations */ static pdf_annot * pdf_create_annot(fz_context *ctx, fz_rect rect, fz_obj *base_obj, fz_buffer *content, fz_obj *resources, int transparency) { pdf_annot *annot; pdf_xobject *form; int rotate = fz_to_int(ctx, fz_dict_gets(ctx, fz_dict_gets(ctx, base_obj, "MK"), "R")); form = fz_malloc(ctx, sizeof(pdf_xobject)); memset(form, 0, sizeof(pdf_xobject)); form->refs = 1; form->matrix = fz_rotate(rotate); form->bbox.x1 = (rotate % 180 == 0) ? rect.x1 - rect.x0 : rect.y1 - rect.y0; form->bbox.y1 = (rotate % 180 == 0) ? rect.y1 - rect.y0 : rect.x1 - rect.x0; form->transparency = transparency; form->isolated = !transparency; form->contents = content; form->resources = resources; annot = fz_malloc(ctx, sizeof(pdf_annot)); annot->obj = base_obj; annot->rect = rect; annot->ap = form; annot->next = NULL; pdf_transform_annot(annot); return annot; }
void pdf_update_annot(pdf_document *doc, pdf_annot *annot) { /* SumatraPDF: prevent regressions */ #if 0 pdf_obj *obj, *ap, *as, *n; fz_context *ctx = doc->ctx; if (doc->update_appearance) doc->update_appearance(doc, annot); obj = annot->obj; ap = pdf_dict_gets(obj, "AP"); as = pdf_dict_gets(obj, "AS"); if (pdf_is_dict(ap)) { pdf_hotspot *hp = &doc->hotspot; n = NULL; if (hp->num == pdf_to_num(obj) && hp->gen == pdf_to_gen(obj) && (hp->state & HOTSPOT_POINTER_DOWN)) { n = pdf_dict_gets(ap, "D"); /* down state */ } if (n == NULL) n = pdf_dict_gets(ap, "N"); /* normal state */ /* lookup current state in sub-dictionary */ if (!pdf_is_stream(doc, pdf_to_num(n), pdf_to_gen(n))) n = pdf_dict_get(n, as); pdf_drop_xobject(ctx, annot->ap); annot->ap = NULL; if (pdf_is_stream(doc, pdf_to_num(n), pdf_to_gen(n))) { fz_try(ctx) { annot->ap = pdf_load_xobject(doc, n); pdf_transform_annot(annot); annot->ap_iteration = annot->ap->iteration; } fz_catch(ctx) { fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); fz_warn(ctx, "ignoring broken annotation"); } } } #endif }
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->gen == pdf_to_gen(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, doc, pdf_to_num(ctx, n), pdf_to_gen(ctx, n))) n = pdf_dict_get(ctx, n, as); pdf_drop_xobject(ctx, annot->ap); annot->ap = NULL; if (pdf_is_stream(ctx, doc, pdf_to_num(ctx, n), pdf_to_gen(ctx, n))) { fz_try(ctx) { annot->ap = pdf_load_xobject(ctx, doc, n); pdf_transform_annot(ctx, annot); annot->ap_iteration = annot->ap->iteration; } fz_catch(ctx) { fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); fz_warn(ctx, "ignoring broken annotation"); } } } }
void pdf_update_annot(pdf_document *xref, pdf_annot *annot) { pdf_obj *obj, *ap, *as, *n, *d, *c; fz_context *ctx = xref->ctx; int suitable; int mouse_states; pdf_hotspot *hp = &xref->hotspot; obj = annot->obj; if (hp->num == pdf_to_num(obj) && hp->gen == pdf_to_gen(obj) && (hp->state & HOTSPOT_POINTER_DOWN)) { mouse_states = MOUSE_DOWN_APPEARANCE; } else { mouse_states = MOUSE_UP_APPEARANCE; } suitable = (annot->mouse_states & mouse_states); if (pdf_update_appearance(xref, obj) || !suitable || annot->has_states) { ap = pdf_dict_gets(obj, "AP"); as = pdf_dict_gets(obj, "AS"); if (pdf_is_dict(ap)) { pdf_hotspot *hp = &xref->hotspot; n = pdf_dict_gets(ap, "N"); /* normal state */ d = pdf_dict_gets(ap, "D"); /* down state */ if (mouse_states == MOUSE_DOWN_APPEARANCE) c = d?d:n; else c = n?n:d; annot->has_states = 0; /* lookup current state in sub-dictionary */ if (!pdf_is_stream(xref, pdf_to_num(c), pdf_to_gen(c))) { annot->has_states = 1; c = pdf_dict_get(c, as); } /* This test is important to avoid losing the knowledge * that an appearance stream is for both mouse states */ if (!suitable) annot->mouse_states = mouse_states; pdf_drop_xobject(ctx, annot->ap); annot->ap = NULL; if (pdf_is_stream(xref, pdf_to_num(c), pdf_to_gen(c))) { fz_try(ctx) { annot->ap = pdf_load_xobject(xref, c); pdf_transform_annot(annot); } fz_catch(ctx) { fz_warn(ctx, "ignoring broken annotation"); } } if (obj == xref->focus_obj) xref->focus = annot; } }
pdf_annot * pdf_load_annots(pdf_document *xref, pdf_obj *annots, fz_matrix page_ctm) { pdf_annot *annot, *head, *tail; pdf_obj *obj, *ap, *as, *n, *d, *c, *rect; int i, len; int mouse_states; int has_states = 0; fz_context *ctx = xref->ctx; head = tail = NULL; annot = NULL; len = pdf_array_len(annots); for (i = 0; i < len; i++) { obj = pdf_array_get(annots, i); pdf_update_appearance(xref, obj); rect = pdf_dict_gets(obj, "Rect"); ap = pdf_dict_gets(obj, "AP"); as = pdf_dict_gets(obj, "AS"); if (pdf_is_dict(ap)) { pdf_hotspot *hp = &xref->hotspot; n = pdf_dict_gets(ap, "N"); /* normal state */ d = pdf_dict_gets(ap, "D"); /* down state */ if (n && d) { if (hp->num == pdf_to_num(obj) && hp->gen == pdf_to_gen(obj) && (hp->state & HOTSPOT_POINTER_DOWN)) { /* Use the down appearance, but as we also have * a normal appearance, it is suitable only for mouse * down */ c = d; mouse_states = MOUSE_DOWN_APPEARANCE; } else { /* Use the normal appearance, but as we also have * a down appearance, it is suitable only for mouse * up */ c = n; mouse_states = MOUSE_UP_APPEARANCE; } } else { /* Use whichever appearance we have for both states */ c = n?n:d; mouse_states = MOUSE_UP_APPEARANCE|MOUSE_DOWN_APPEARANCE; } /* lookup current state in sub-dictionary */ if (!pdf_is_stream(xref, pdf_to_num(c), pdf_to_gen(c))) { has_states = 1; c = pdf_dict_get(c, as); } annot = fz_malloc_struct(ctx, pdf_annot); annot->obj = pdf_keep_obj(obj); annot->rect = pdf_to_rect(ctx, rect); annot->pagerect = fz_transform_rect(page_ctm, annot->rect); annot->ap = NULL; annot->type = pdf_field_type(xref, obj); annot->mouse_states = mouse_states; annot->has_states = has_states; if (pdf_is_stream(xref, pdf_to_num(c), pdf_to_gen(c))) { fz_try(ctx) { annot->ap = pdf_load_xobject(xref, c); pdf_transform_annot(annot); } fz_catch(ctx) { fz_warn(ctx, "ignoring broken annotation"); } } annot->next = NULL; if (obj == xref->focus_obj) xref->focus = annot; if (!head) head = tail = annot; else { tail->next = annot; tail = annot; } } } return head; }
void pdf_load_annots(pdf_annot **annotp, pdf_xref *xref, fz_obj *annots) { pdf_annot *annot, *head, *tail; fz_obj *obj, *ap, *as, *n, *rect; pdf_xobject *form; fz_error error; int i; fz_context *ctx = xref->ctx; head = tail = NULL; annot = NULL; for (i = 0; i < fz_array_len(ctx, annots); i++) { obj = fz_array_get(ctx, annots, i); /* cf. http://bugs.ghostscript.com/show_bug.cgi?id=692078 */ if ((annot = pdf_update_tx_widget_annot(xref, obj))) { if (!head) head = tail = annot; else { tail->next = annot; tail = annot; } continue; } rect = fz_dict_gets(ctx, obj, "Rect"); ap = fz_dict_gets(ctx, obj, "AP"); as = fz_dict_gets(ctx, obj, "AS"); if (fz_is_dict(ctx, ap)) { n = fz_dict_gets(ctx, ap, "N"); /* normal state */ /* lookup current state in sub-dictionary */ if (!pdf_is_stream(xref, fz_to_num(n), fz_to_gen(n))) n = fz_dict_get(ctx, n, as); if (pdf_is_stream(xref, fz_to_num(n), fz_to_gen(n))) { error = pdf_load_xobject(&form, xref, n); if (error) { fz_error_handle(ctx, error, "ignoring broken annotation"); continue; } annot = fz_malloc(ctx, sizeof(pdf_annot)); annot->obj = fz_keep_obj(obj); annot->rect = pdf_to_rect(ctx, rect); annot->ap = form; annot->next = NULL; pdf_transform_annot(annot); if (annot) { if (!head) head = tail = annot; else { tail->next = annot; tail = annot; } } } } /* SumatraPDF: synthesize appearance streams for a few more annotations */ else if ((annot = pdf_create_annot_with_appearance(xref, obj))) { if (!head) head = tail = annot; else { tail->next = annot; tail = annot; } } } *annotp = head; }