diff options
Diffstat (limited to 'source/pdf/pdf-outline.c')
-rw-r--r-- | source/pdf/pdf-outline.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/source/pdf/pdf-outline.c b/source/pdf/pdf-outline.c new file mode 100644 index 00000000..584d60ea --- /dev/null +++ b/source/pdf/pdf-outline.c @@ -0,0 +1,72 @@ +#include "mupdf/pdf.h" + +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_var(first); + + 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); + + 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) + { + fz_free_outline(ctx, first); + fz_rethrow(ctx); + } + + return first; +} + +fz_outline * +pdf_load_outline(pdf_document *xref) +{ + pdf_obj *root, *obj, *first; + + root = pdf_dict_gets(pdf_trailer(xref), "Root"); + obj = pdf_dict_gets(root, "Outlines"); + first = pdf_dict_gets(obj, "First"); + if (first) + return pdf_load_outline_imp(xref, first); + + return NULL; +} |