static fz_outline * pdf_load_outline_imp(pdf_document *xref, pdf_obj *dict) { fz_context *ctx = xref->ctx; fz_outline *node, **prev, *first; pdf_obj *obj; pdf_obj *odict = dict; fz_var(dict); fz_try(ctx) { first = NULL; prev = &first; while (dict && pdf_is_dict(dict)) { if (pdf_obj_mark(dict)) break; node = fz_malloc_struct(ctx, fz_outline); node->title = NULL; node->dest.kind = FZ_LINK_NONE; node->down = NULL; node->next = NULL; *prev = node; prev = &node->next; obj = pdf_dict_gets(dict, "Title"); if (obj) node->title = pdf_to_utf8(xref, obj); /* SumatraPDF: support expansion states */ node->is_open = pdf_to_int(pdf_dict_gets(dict, "Count")) >= 0; if ((obj = pdf_dict_gets(dict, "Dest"))) node->dest = pdf_parse_link_dest(xref, obj); else if ((obj = pdf_dict_gets(dict, "A"))) node->dest = pdf_parse_action(xref, obj); obj = pdf_dict_gets(dict, "First"); if (obj) node->down = pdf_load_outline_imp(xref, obj); dict = pdf_dict_gets(dict, "Next"); } } fz_always(ctx) { for (dict = odict; dict && pdf_obj_marked(dict); dict = pdf_dict_gets(dict, "Next")) pdf_obj_unmark(dict); } fz_catch(ctx) { /* SumatraPDF: fix memory leak */ fz_free_outline(ctx, first); fz_rethrow(ctx); } return first; }
static fz_outline * pdf_load_outline_imp(pdf_document *xref, fz_obj *dict) { fz_context *ctx = xref->ctx; fz_outline *node, **prev, *first; fz_obj *obj; fz_obj *odict = dict; fz_var(dict); fz_try(ctx) { first = NULL; prev = &first; while (dict && fz_is_dict(dict)) { if (fz_dict_mark(dict)) break; node = fz_malloc_struct(ctx, fz_outline); node->title = NULL; node->dest.kind = FZ_LINK_NONE; node->down = NULL; node->next = NULL; *prev = node; prev = &node->next; obj = fz_dict_gets(dict, "Title"); if (obj) node->title = pdf_to_utf8(ctx, obj); if ((obj = fz_dict_gets(dict, "Dest"))) node->dest = pdf_parse_link_dest(xref, obj); else if ((obj = fz_dict_gets(dict, "A"))) node->dest = pdf_parse_action(xref, obj); obj = fz_dict_gets(dict, "First"); if (obj) node->down = pdf_load_outline_imp(xref, obj); dict = fz_dict_gets(dict, "Next"); } } fz_catch(ctx) { for (dict = odict; dict && fz_dict_marked(dict); dict = fz_dict_gets(dict, "Next")) fz_dict_unmark(dict); fz_rethrow(ctx); } for (dict = odict; dict && fz_dict_marked(dict); dict = fz_dict_gets(dict, "Next")) fz_dict_unmark(dict); return first; }
static fz_link * pdf_load_link(pdf_document *xref, pdf_obj *dict, fz_matrix page_ctm) { pdf_obj *dest = NULL; pdf_obj *action; pdf_obj *obj; fz_rect bbox; fz_context *ctx = xref->ctx; fz_link_dest ld; dest = NULL; obj = pdf_dict_gets(dict, "Rect"); if (obj) bbox = pdf_to_rect(ctx, obj); else bbox = fz_empty_rect; bbox = fz_transform_rect(page_ctm, bbox); obj = pdf_dict_gets(dict, "Dest"); if (obj) { dest = resolve_dest(xref, obj); ld = pdf_parse_link_dest(xref, dest); } else { action = pdf_dict_gets(dict, "A"); /* fall back to additional action button's down/up action */ if (!action) action = pdf_dict_getsa(pdf_dict_gets(dict, "AA"), "U", "D"); ld = pdf_parse_action(xref, action); } if (ld.kind == FZ_LINK_NONE) return NULL; return fz_new_link(ctx, bbox, ld); }