summaryrefslogtreecommitdiff
path: root/source/pdf/pdf-outline.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/pdf/pdf-outline.c')
-rw-r--r--source/pdf/pdf-outline.c72
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;
+}