X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=backend%2Fev-page-cache.c;h=ad0a1fa2d123ac1e28978befa34cba3791cbaa40;hb=3a5debb394dd45d4b802ab83e1249d9749fc4d84;hp=204239476f87c8b74da7f24ffc8f4eed8a3da5f0;hpb=03ad9a29cbe1a89dfc5e8b94a74f6f86c4cba076;p=evince.git diff --git a/backend/ev-page-cache.c b/backend/ev-page-cache.c index 20423947..ad0a1fa2 100644 --- a/backend/ev-page-cache.c +++ b/backend/ev-page-cache.c @@ -1,10 +1,12 @@ #include "ev-page-cache.h" #include "ev-job-queue.h" +#include +#include typedef struct _EvPageCacheInfo { - gint width; - gint height; + double width; + double height; } EvPageCacheInfo; @@ -17,12 +19,21 @@ struct _EvPageCache int n_pages; char *title; char **page_labels; - + + gint max_label_chars; + gboolean has_labels; gboolean uniform; - gint uniform_width; - gint uniform_height; + + double uniform_width; + double uniform_height; + + double max_width_page_width; + double max_width_page_height; + double max_height_page_width; + double max_height_page_height; EvPageCacheInfo *size_cache; + EvDocumentInfo *page_info; }; struct _EvPageCacheClass @@ -49,7 +60,8 @@ G_DEFINE_TYPE (EvPageCache, ev_page_cache, G_TYPE_OBJECT) static void ev_page_cache_init (EvPageCache *page_cache) { - page_cache->current_page = 0; + page_cache->current_page = -1; + page_cache->max_label_chars = 0; } static void @@ -82,34 +94,72 @@ ev_page_cache_finalize (GObject *object) g_free (page_cache->title); g_free (page_cache->size_cache); + ev_document_info_free (page_cache->page_info); } EvPageCache * _ev_page_cache_new (EvDocument *document) { + EvDocumentInfo *doc_info; EvPageCache *page_cache; EvPageCacheInfo *info; gint i; page_cache = (EvPageCache *) g_object_new (EV_TYPE_PAGE_CACHE, NULL); - g_mutex_lock (EV_DOC_MUTEX); + ev_document_doc_mutex_lock (); /* We read page information out of the document */ /* Assume all pages are the same size until proven otherwise */ page_cache->uniform = TRUE; + page_cache->has_labels = FALSE; page_cache->n_pages = ev_document_get_n_pages (document); - page_cache->title = ev_document_get_title (document); page_cache->page_labels = g_new0 (char *, page_cache->n_pages); + page_cache->max_width_page_width = 0; + page_cache->max_width_page_height = 0; + page_cache->max_height_page_width = 0; + page_cache->max_height_page_height = 0; + + doc_info = ev_document_get_info (document); + if (doc_info->fields_mask & EV_DOCUMENT_INFO_TITLE) { + page_cache->title = g_strdup (doc_info->title); + } else { + page_cache->title = NULL; + } + g_free (doc_info); - ev_document_set_scale (document, 1.0); for (i = 0; i < page_cache->n_pages; i++) { - gint page_width = 0; - gint page_height = 0; - + double page_width = 0; + double page_height = 0; + ev_document_get_page_size (document, i, &page_width, &page_height); - page_cache->page_labels[i] = ev_document_get_page_label (document, i); + + page_cache->page_labels[i] = ev_document_get_page_label (document, i); + + if (page_cache->page_labels[i] != NULL) { + + page_cache->max_label_chars = MAX(page_cache->max_label_chars, + g_utf8_strlen (page_cache->page_labels[i], 256)); + if (!page_cache->has_labels) { + gchar *expected_label; + + expected_label = g_strdup_printf ("%d", i + 1); + if (strcmp (expected_label, page_cache->page_labels[i])) + page_cache->has_labels = TRUE; + g_free (expected_label); + } + } + + if (page_width > page_cache->max_width_page_width) { + page_cache->max_width_page_width = page_width; + page_cache->max_width_page_height = page_height; + } + + if (page_height > page_cache->max_height_page_height) { + page_cache->max_height_page_width = page_width; + page_cache->max_height_page_height = page_height; + } if (i == 0) { page_cache->uniform_width = page_width; @@ -122,31 +172,35 @@ _ev_page_cache_new (EvDocument *document) page_cache->size_cache = g_new0 (EvPageCacheInfo, page_cache->n_pages); - for (j = 1; j < i; j++) { - info = &(page_cache->size_cache [j - 1]); - info->width = page_width; - info->height = page_height; + for (j = 0; j < i; j++) { + info = &(page_cache->size_cache [j]); + info->width = page_cache->uniform_width; + info->height = page_cache->uniform_height; } page_cache->uniform = FALSE; } if (! page_cache->uniform) { - info = &(page_cache->size_cache [i - 1]); + info = &(page_cache->size_cache [i]); info->width = page_width; info->height = page_height; } } + page_cache->page_info = ev_document_get_info (document); + /* make some sanity check assertions */ - g_assert (page_cache->n_pages > 0); if (! page_cache->uniform) g_assert (page_cache->size_cache != NULL); if (page_cache->uniform) g_assert (page_cache->uniform_width > 0 && page_cache->uniform_height > 0); - g_mutex_unlock (EV_DOC_MUTEX); + ev_document_doc_mutex_unlock (); + + if (page_cache->n_pages > 0) + ev_page_cache_set_current_page (page_cache, 0); return page_cache; } @@ -181,6 +235,45 @@ ev_page_cache_set_current_page (EvPageCache *page_cache, g_signal_emit (page_cache, signals[PAGE_CHANGED], 0, page); } +gboolean +ev_page_cache_set_page_label (EvPageCache *page_cache, + const char *page_label) +{ + gint i, page; + long value; + char *endptr = NULL; + + g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), FALSE); + g_return_val_if_fail (page_label != NULL, FALSE); + + /* First, look for a literal label match */ + for (i = 0; i < page_cache->n_pages; i ++) { + if (page_cache->page_labels[i] != NULL && + ! strcmp (page_label, page_cache->page_labels[i])) { + ev_page_cache_set_current_page (page_cache, i); + return TRUE; + } + } + + /* Next, parse the label, and see if the number fits */ + value = strtol (page_label, &endptr, 10); + if (endptr[0] == '\0') { + /* Page number is an integer */ + page = MIN (G_MAXINT, value); + + /* convert from a page label to a page offset */ + page --; + if (page >= 0 && + page < page_cache->n_pages && + page_cache->page_labels[page] == NULL) { + ev_page_cache_set_current_page (page_cache, page); + return TRUE; + } + } + + return FALSE; +} + void ev_page_cache_set_link (EvPageCache *page_cache, EvLink *link) @@ -226,11 +319,51 @@ ev_page_cache_get_size (EvPageCache *page_cache, } if (width) - *width = (*width) * scale; + *width = (int) ((*width) * scale + 0.5); if (width) - *height = (*height) * scale; + *height = (int) ((*height) * scale + 0.5); } + + +/* Note that these aren't necessarily from the same page. + */ +void +ev_page_cache_get_max_width_size (EvPageCache *page_cache, + gfloat scale, + gint *width, + gint *height) +{ + g_return_if_fail (EV_IS_PAGE_CACHE (page_cache)); + + if (width) + *width = page_cache->max_width_page_width * scale; + if (height) + *height = page_cache->max_width_page_height * scale; +} + +void +ev_page_cache_get_max_height_size (EvPageCache *page_cache, + gfloat scale, + gint *width, + gint *height) +{ + g_return_if_fail (EV_IS_PAGE_CACHE (page_cache)); + + if (width) + *width = page_cache->max_height_page_width * scale; + if (height) + *height = page_cache->max_height_page_height * scale; +} + +gint +ev_page_cache_get_max_label_chars (EvPageCache *page_cache) +{ + g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), 0); + + return page_cache->max_label_chars; +} + gchar * ev_page_cache_get_page_label (EvPageCache *page_cache, gint page) @@ -244,13 +377,28 @@ ev_page_cache_get_page_label (EvPageCache *page_cache, return g_strdup (page_cache->page_labels[page]); } +gboolean +ev_page_cache_has_nonnumeric_page_labels (EvPageCache *page_cache) +{ + g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), FALSE); + return page_cache->has_labels; +} + +const EvDocumentInfo * +ev_page_cache_get_info (EvPageCache *page_cache) +{ + g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), NULL); + + return page_cache->page_info; +} + gboolean ev_page_cache_next_page (EvPageCache *page_cache) { g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), FALSE); - if (page_cache->current_page > page_cache->n_pages) + if (page_cache->current_page >= page_cache->n_pages - 1) return FALSE; ev_page_cache_set_current_page (page_cache, page_cache->current_page + 1);