[evince] djvu: add support for file identifiers



commit 809d3c53c3cda251d502e92525e1542a7b57a898
Author: José Aliste <jaliste src gnome org>
Date:   Wed Feb 6 00:15:59 2013 +0100

    djvu: add support for file identifiers
    
    https://bugzilla.gnome.org/show_bug.cgi?id=619410

 backend/djvu/djvu-document-private.h |    1 +
 backend/djvu/djvu-document.c         |    8 ++++++-
 backend/djvu/djvu-links.c            |   40 ++++++++++++++++++++++++---------
 3 files changed, 37 insertions(+), 12 deletions(-)
---
diff --git a/backend/djvu/djvu-document-private.h b/backend/djvu/djvu-document-private.h
index dfc75f4..07b27d9 100644
--- a/backend/djvu/djvu-document-private.h
+++ b/backend/djvu/djvu-document-private.h
@@ -40,6 +40,7 @@ struct _DjvuDocument {
         GString         *opts;
        ddjvu_fileinfo_t *fileinfo_pages;
        gint              n_pages;
+       GHashTable       *file_ids;
 };
 
 int  djvu_document_get_n_pages (EvDocument   *document);
diff --git a/backend/djvu/djvu-document.c b/backend/djvu/djvu-document.c
index b8243c3..57af7dd 100644
--- a/backend/djvu/djvu-document.c
+++ b/backend/djvu/djvu-document.c
@@ -215,8 +215,8 @@ djvu_document_load (EvDocument  *document,
 
        if (djvu_document->n_pages > 0) {
                djvu_document->fileinfo_pages = g_new0 (ddjvu_fileinfo_t, djvu_document->n_pages);
+               djvu_document->file_ids = g_hash_table_new (g_str_hash, g_str_equal);
        }
-
        if (ddjvu_document_get_type (djvu_document->d_document) == DDJVU_DOCTYPE_INDIRECT)
                check_for_missing_files = TRUE;
 
@@ -237,6 +237,9 @@ djvu_document_load (EvDocument  *document,
                        djvu_document->fileinfo_pages[fileinfo.pageno] = fileinfo;
                }
 
+               g_hash_table_insert (djvu_document->file_ids,
+                                    (gpointer) djvu_document->fileinfo_pages[fileinfo.pageno].id,
+                                    GINT_TO_POINTER(fileinfo.pageno));
 
                if (check_for_missing_files && !missing_files) {
                        file = g_build_filename (base, fileinfo.id, NULL);
@@ -482,6 +485,9 @@ djvu_document_finalize (GObject *object)
        if (djvu_document->fileinfo_pages) 
            g_free (djvu_document->fileinfo_pages);
        
+       if (djvu_document->file_ids)
+           g_hash_table_destroy (djvu_document->file_ids);
+
        ddjvu_context_release (djvu_document->d_context);
        ddjvu_format_release (djvu_document->d_format);
        ddjvu_format_release (djvu_document->thumbs_format);
diff --git a/backend/djvu/djvu-links.c b/backend/djvu/djvu-links.c
index ebcc6a4..33fa142 100644
--- a/backend/djvu/djvu-links.c
+++ b/backend/djvu/djvu-links.c
@@ -67,11 +67,18 @@ get_djvu_link_page (const DjvuDocument *djvu_document, const gchar *link_name, i
 
        /* #pagenum, #+pageoffset, #-pageoffset */
        if (g_str_has_prefix (link_name, "#")) {
-               if (base_page > 0 && g_str_has_prefix (link_name+1, "+")) {
+               if (g_str_has_suffix (link_name,".djvu")) {
+                       /* File identifiers */
+                       gpointer page = NULL;
+
+                       if (g_hash_table_lookup_extended (djvu_document->file_ids, link_name + 1, NULL, 
&page)) {
+                               return GPOINTER_TO_INT (page);
+                       }
+               } else if (base_page > 0 && g_str_has_prefix (link_name + 1, "+")) {
                        if (number_from_string_10 (link_name + 2, &page_num)) {
                                return base_page + page_num;
                        }
-               } else if (base_page > 0 && g_str_has_prefix (link_name+1, "-")) {
+               } else if (base_page > 0 && g_str_has_prefix (link_name + 1, "-")) {
                        if (number_from_string_10 (link_name + 2, &page_num)) {
                                return base_page - page_num;
                        }
@@ -81,7 +88,7 @@ get_djvu_link_page (const DjvuDocument *djvu_document, const gchar *link_name, i
                        }
                }
        } else {
-               /* FIXME: component file identifiers */
+               /* FIXME: should we handle this case */
        }
 
        return page_num;
@@ -90,7 +97,21 @@ get_djvu_link_page (const DjvuDocument *djvu_document, const gchar *link_name, i
 static EvLinkDest *
 get_djvu_link_dest (const DjvuDocument *djvu_document, const gchar *link_name, int base_page)
 {
-       return ev_link_dest_new_page (get_djvu_link_page (djvu_document, link_name, base_page));
+       /* #+pagenum #-pagenum #file_id.djvu */
+       if (g_str_has_prefix (link_name, "#")) {
+               if (g_str_has_suffix (link_name, ".djvu") ||
+                   (base_page > 0 && g_str_has_prefix (link_name + 1, "+")) ||
+                   (base_page > 0 && g_str_has_prefix (link_name + 1, "-"))) {
+                       return ev_link_dest_new_page (get_djvu_link_page (djvu_document, link_name, 
base_page));
+               } else {
+                       /* #pagenum #page_label: the djvu spec is not clear on whether #pagenum represents
+                        * a link to a page number or to a page label. Here we mimick djview,
+                        * and always treat #pagenum as a link to a page label */
+                       return ev_link_dest_new_page_label (link_name + 1);
+               }
+       }
+
+       return NULL;
 }
 
 static EvLinkAction *
@@ -99,16 +120,15 @@ get_djvu_link_action (const DjvuDocument *djvu_document, const gchar *link_name,
        EvLinkDest *ev_dest = NULL;
        EvLinkAction *ev_action = NULL;
 
-       ev_dest = get_djvu_link_dest (djvu_document, link_name, base_page);
+       /* File component identifiers are handled by get_djvu_link_dest */
 
+       ev_dest = get_djvu_link_dest (djvu_document, link_name, base_page);
        if (ev_dest) {
                ev_action = ev_link_action_new_dest (ev_dest);
                g_object_unref (ev_dest);
        } else if (strstr(link_name, "://") != NULL) {
                /* It's probably an URI */
                ev_action = ev_link_action_new_external_uri (link_name);
-       } else {
-               /* FIXME: component file identifiers */
        }
 
        return ev_action;
@@ -191,10 +211,8 @@ build_tree (const DjvuDocument *djvu_document,
                }
 
                ev_action = get_djvu_link_action (djvu_document, link_dest, -1);
-               
-               if (g_str_has_suffix (link_dest, ".djvu")) {
-                       /* FIXME: component file identifiers */
-               } else if (ev_action) {
+
+               if (ev_action) {
                        ev_link = ev_link_new (utf8_title ? utf8_title : title, ev_action);
                        gtk_tree_store_append (GTK_TREE_STORE (model), &tree_iter, parent);
                        gtk_tree_store_set (GTK_TREE_STORE (model), &tree_iter,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]