From aa82af227964f2a914314c7184d22e5e7a98aea7 Mon Sep 17 00:00:00 2001 From: Masamichi Hosoda Date: Sun, 25 Sep 2016 23:39:12 +0900 Subject: [PATCH v4] Add poppler_document_build_dests_tree() to glib frontend Builds named destinations balanced binary tree in document. bug 97262 --- glib/poppler-document.cc | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ glib/poppler-document.h | 2 ++ 2 files changed, 93 insertions(+) diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc index 334f9b6..d4a4fd2 100644 --- a/glib/poppler-document.cc +++ b/glib/poppler-document.cc @@ -2,6 +2,7 @@ * Copyright (C) 2005, Red Hat, Inc. * * Copyright (C) 2016 Jakub Alba + * Copyright (C) 2016 Masamichi Hosoda * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -712,6 +713,96 @@ poppler_document_find_dest (PopplerDocument *document, return dest; } +static gint +_poppler_dest_compare_gbytes (gconstpointer a, + gconstpointer b, + gpointer user_data) +{ + return g_bytes_compare (a, b); +} + +static void +_poppler_dest_destroy_key (gpointer key) +{ + g_bytes_unref (static_cast(key)); +} + +static void +_poppler_dest_destroy_value (gpointer value) +{ + poppler_dest_free (static_cast(value)); +} + +/** + * poppler_document_build_dests_tree: + * @document: A #PopplerDocument + * + * Builds named destinations balanced binary tree in @document + * + * Return value: a #GTree or %NULL if @document is not valid. + * The tree key is the #GBytes which constains a destination name. + * Note that the names can contain \0, so it is GBytes instead of gchar*. + * The tree value the #PopplerDest which contains a named destination. + * Returned value must be freed with #g_tree_destroy. + * + * Since: 0.50 + **/ +GTree * +poppler_document_build_dests_tree (PopplerDocument *document) +{ + GTree *tree; + Catalog *catalog; + LinkDest *link_dest; + PopplerDest *dest; + int i, len; + GBytes *key; + + g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL); + + catalog = document->doc->getCatalog (); + if (catalog == NULL) + return NULL; + + tree = g_tree_new_full (_poppler_dest_compare_gbytes, NULL, + _poppler_dest_destroy_key, + _poppler_dest_destroy_value); + + // Iterate from name-dict + len = catalog->numDests (); + for (i = 0; i < len; ++i) { + // The names of name-dict cannot contain \0, + // so we can use strlen(). + key = g_bytes_new (catalog->getDestsName (i), + strlen (catalog->getDestsName (i))); + link_dest = catalog->getDestsDest (i); + if (link_dest) { + dest = _poppler_dest_new_goto (document, link_dest); + delete link_dest; + } else + dest = NULL; + g_tree_insert (tree, key, dest); + } + + // Iterate form name-tree + len = catalog->numDestNameTree (); + for (i = 0; i < len; ++i) { + // The names of name-tree can contain \0, + // so we use GBytes instead of gchar*. + key = g_bytes_new + (catalog->getDestNameTreeName (i)->getCString (), + catalog->getDestNameTreeName (i)->getLength ()); + link_dest = catalog->getDestNameTreeDest (i); + if (link_dest) { + dest = _poppler_dest_new_goto (document, link_dest); + delete link_dest; + } else + dest = NULL; + g_tree_insert (tree, key, dest); + } + + return tree; +} + char *_poppler_goo_string_to_utf8(GooString *s) { if (s == NULL) { diff --git a/glib/poppler-document.h b/glib/poppler-document.h index a7fcea1..3b211ae 100644 --- a/glib/poppler-document.h +++ b/glib/poppler-document.h @@ -2,6 +2,7 @@ * Copyright (C) 2004, Red Hat, Inc. * * Copyright (C) 2016 Jakub Alba + * Copyright (C) 2016 Masamichi Hosoda * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -240,6 +241,7 @@ GList *poppler_document_get_attachments (PopplerDocument *do /* Links */ PopplerDest *poppler_document_find_dest (PopplerDocument *document, const gchar *link_name); +GTree *poppler_document_build_dests_tree (PopplerDocument *document); /* Form */ PopplerFormField *poppler_document_get_form_field (PopplerDocument *document, -- 2.8.3