X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=shell%2Fev-page-cache.c;h=a1b4d609019e1a1abe17b4fda3b71797eef1ce9a;hb=f51872613abaaa42c716e2fe6a2e4695c529dc4b;hp=7409ded1c03401c6868ad362628e417629c6828f;hpb=00a3581bfaaf0d5f825820c68b515415fe510b66;p=evince.git diff --git a/shell/ev-page-cache.c b/shell/ev-page-cache.c index 7409ded1..a1b4d609 100644 --- a/shell/ev-page-cache.c +++ b/shell/ev-page-cache.c @@ -1,15 +1,23 @@ +#include #include "ev-page-cache.h" #include "ev-job-queue.h" +#include "ev-document-thumbnails.h" #include #include +#define THUMBNAIL_WIDTH 100 + typedef struct _EvPageCacheInfo { double width; double height; -} -EvPageCacheInfo; +} EvPageCacheInfo; +typedef struct _EvPageThumbsInfo +{ + gint width; + gint height; +} EvPageThumbsInfo; struct _EvPageCache { @@ -23,6 +31,7 @@ struct _EvPageCache gint max_label_chars; gboolean has_labels; gboolean uniform; + gboolean dual_even_left; double uniform_width; double uniform_height; @@ -37,6 +46,14 @@ struct _EvPageCache EvPageCacheInfo *size_cache; EvDocumentInfo *page_info; + + /* Thumbnail dimensions */ + gboolean thumbs_uniform; + gint thumbs_uniform_width; + gint thumbs_uniform_height; + gint thumbs_max_width; + gint thumbs_max_height; + EvPageThumbsInfo *thumbs_size_cache; }; struct _EvPageCacheClass @@ -44,11 +61,13 @@ struct _EvPageCacheClass GObjectClass parent_class; void (* page_changed) (EvPageCache *page_cache, gint page); + void (* history_changed) (EvPageCache *page_cache, gint page); }; enum { PAGE_CHANGED, + HISTORY_CHANGED, N_SIGNALS, }; @@ -86,6 +105,16 @@ ev_page_cache_class_init (EvPageCacheClass *class) G_TYPE_NONE, 1, G_TYPE_INT); + signals [HISTORY_CHANGED] = + g_signal_new ("history-changed", + EV_TYPE_PAGE_CACHE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EvPageCacheClass, history_changed), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, + G_TYPE_INT); + } static void @@ -95,12 +124,43 @@ ev_page_cache_finalize (GObject *object) page_cache = EV_PAGE_CACHE (object); - g_free (page_cache->title); - g_free (page_cache->size_cache); - g_free (page_cache->height_to_page); - g_free (page_cache->dual_height_to_page); + if (page_cache->title) { + g_free (page_cache->title); + page_cache->title = NULL; + } + + if (page_cache->size_cache) { + g_free (page_cache->size_cache); + page_cache->size_cache = NULL; + } + + if (page_cache->height_to_page) { + g_free (page_cache->height_to_page); + page_cache->height_to_page = NULL; + } + + if (page_cache->dual_height_to_page) { + g_free (page_cache->dual_height_to_page); + page_cache->dual_height_to_page = NULL; + } + + if (page_cache->page_labels) { + gint i; + + for (i = 0; i < page_cache->n_pages; i++) { + if (page_cache->page_labels[i]) + g_free (page_cache->page_labels[i]); + } + g_free (page_cache->page_labels); + page_cache->page_labels = NULL; + } + + if (page_cache->page_info) { + ev_document_info_free (page_cache->page_info); + page_cache->page_info = NULL; + } - ev_document_info_free (page_cache->page_info); + G_OBJECT_CLASS (ev_page_cache_parent_class)->finalize (object); } static void @@ -117,54 +177,77 @@ build_height_to_page (EvPageCache *page_cache) g_free (page_cache->height_to_page); g_free (page_cache->dual_height_to_page); - page_cache->height_to_page = g_new0(double, page_cache->n_pages); - page_cache->dual_height_to_page = g_new0(double, page_cache->n_pages / 2 + 1); + page_cache->height_to_page = g_new0(double, page_cache->n_pages + 1); + page_cache->dual_height_to_page = g_new0(double, page_cache->n_pages + 2); saved_height = 0; - for (i = 0; i < page_cache->n_pages; i++) { + for (i = 0; i <= page_cache->n_pages; i++) { if (page_cache->uniform) { if (!swap) { uniform_height = page_cache->uniform_height; } else { uniform_height = page_cache->uniform_width; } - page_cache->height_to_page [i] = (i + 1) * uniform_height; + page_cache->height_to_page [i] = i * uniform_height; } else { - if (!swap) { - page_height = page_cache->size_cache [i].height; + if (i < page_cache->n_pages) { + if (!swap) { + page_height = page_cache->size_cache [i].height; + } else { + page_height = page_cache->size_cache [i].width; + } } else { - page_height = page_cache->size_cache [i].width; + page_height = 0; } - page_cache->height_to_page [i] = saved_height + page_height; - saved_height = page_cache->height_to_page [i]; + page_cache->height_to_page [i] = saved_height; + saved_height += page_height; } } - - saved_height = 0; - for (i = 0; i < page_cache->n_pages; i += 2) { + + if (page_cache->dual_even_left && !page_cache->uniform) { + if (!swap) { + saved_height = page_cache->size_cache [0].height; + } else { + saved_height = page_cache->size_cache [0].width; + } + } else { + saved_height = 0; + } + for (i = page_cache->dual_even_left; i < page_cache->n_pages + 2; i += 2) { if (page_cache->uniform) { if (!swap) { uniform_height = page_cache->uniform_height; } else { uniform_height = page_cache->uniform_width; } - page_cache->dual_height_to_page [i / 2] = (i / 2 + 1) * uniform_height; + page_cache->dual_height_to_page [i] = ((i + page_cache->dual_even_left) / 2) * uniform_height; + if (i + 1 < page_cache->n_pages + 2) + page_cache->dual_height_to_page [i + 1] = ((i + page_cache->dual_even_left) / 2) * uniform_height; } else { - if (!swap) { - page_height = page_cache->size_cache [i].height; - next_page_height = page_cache->size_cache [i + 1].height; + if (i + 1 < page_cache->n_pages) { + if (!swap) { + next_page_height = page_cache->size_cache [i + 1].height; + } else { + next_page_height = page_cache->size_cache [i + 1].width; + } } else { - page_height = page_cache->size_cache [i].width; - next_page_height = page_cache->size_cache [i + 1].width; + next_page_height = 0; } - if (i == page_cache->n_pages - 1) { - page_cache->dual_height_to_page [i / 2] = - saved_height + page_height; + if (i < page_cache->n_pages) { + if (!swap) { + page_height = page_cache->size_cache [i].height; + } else { + page_height = page_cache->size_cache [i].width; + } + } else { + page_height = 0; } - else { - page_cache->dual_height_to_page [i / 2] = saved_height + - MAX(page_height, next_page_height); - saved_height = page_cache->dual_height_to_page [i / 2]; + if (i + 1 < page_cache->n_pages + 2) { + page_cache->dual_height_to_page [i] = saved_height; + page_cache->dual_height_to_page [i + 1] = saved_height; + saved_height += MAX(page_height, next_page_height); + } else { + page_cache->dual_height_to_page [i] = saved_height; } } } @@ -175,6 +258,9 @@ ev_page_cache_new (EvDocument *document) { EvPageCache *page_cache; EvPageCacheInfo *info; + EvPageThumbsInfo *thumb_info; + EvRenderContext *rc = NULL; + gboolean has_thumbs; gint i; page_cache = (EvPageCache *) g_object_new (EV_TYPE_PAGE_CACHE, NULL); @@ -187,10 +273,12 @@ ev_page_cache_new (EvDocument *document) page_cache->uniform = TRUE; page_cache->has_labels = FALSE; page_cache->n_pages = ev_document_get_n_pages (document); + page_cache->dual_even_left = (page_cache->n_pages > 2); page_cache->page_labels = g_new0 (char *, page_cache->n_pages); page_cache->max_width = 0; page_cache->max_height = 0; page_cache->page_info = ev_document_get_info (document); + page_cache->thumbs_uniform = TRUE; if (page_cache->page_info->fields_mask & EV_DOCUMENT_INFO_TITLE) { page_cache->title = g_strdup (page_cache->page_info->title); @@ -198,10 +286,14 @@ ev_page_cache_new (EvDocument *document) page_cache->title = NULL; } + has_thumbs = EV_IS_DOCUMENT_THUMBNAILS (document); + for (i = 0; i < page_cache->n_pages; i++) { double page_width = 0; double page_height = 0; - + gint thumb_width = 0; + gint thumb_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); @@ -254,6 +346,57 @@ ev_page_cache_new (EvDocument *document) info->width = page_width; info->height = page_height; } + + if (!has_thumbs) + continue; + + if (!rc) { + rc = ev_render_context_new (0, i, (gdouble)THUMBNAIL_WIDTH / page_width); + } else { + ev_render_context_set_page (rc, i); + ev_render_context_set_scale (rc, (gdouble)THUMBNAIL_WIDTH / page_width); + } + + ev_document_thumbnails_get_dimensions (EV_DOCUMENT_THUMBNAILS (document), + rc, &thumb_width, &thumb_height); + + if (thumb_width > page_cache->thumbs_max_width) { + page_cache->thumbs_max_width = thumb_width; + } + + if (thumb_height > page_cache->thumbs_max_height) { + page_cache->thumbs_max_height = thumb_height; + } + + if (i == 0) { + page_cache->thumbs_uniform_width = thumb_width; + page_cache->thumbs_uniform_height = thumb_height; + } else if (page_cache->thumbs_uniform && + (page_cache->thumbs_uniform_width != thumb_width || + page_cache->thumbs_uniform_height != thumb_height)) { + /* It's a different thumbnail size. Backfill the array. */ + int j; + + page_cache->thumbs_size_cache = g_new0 (EvPageThumbsInfo, page_cache->n_pages); + + for (j = 0; j < i; j++) { + thumb_info = &(page_cache->thumbs_size_cache [j]); + thumb_info->width = page_cache->thumbs_uniform_width; + thumb_info->height = page_cache->thumbs_uniform_height; + } + page_cache->thumbs_uniform = FALSE; + } + + if (! page_cache->thumbs_uniform) { + thumb_info = &(page_cache->thumbs_size_cache [i]); + + thumb_info->width = thumb_width; + thumb_info->height = thumb_height; + } + } + + if (rc) { + g_object_unref (rc); } build_height_to_page (page_cache); @@ -302,6 +445,16 @@ ev_page_cache_set_current_page (EvPageCache *page_cache, g_signal_emit (page_cache, signals[PAGE_CHANGED], 0, page); } +void +ev_page_cache_set_current_page_history (EvPageCache *page_cache, + int page) +{ + if (abs (page - page_cache->current_page) > 1) + g_signal_emit (page_cache, signals [HISTORY_CHANGED], 0, page); + + ev_page_cache_set_current_page (page_cache, page); +} + gboolean ev_page_cache_set_page_label (EvPageCache *page_cache, const char *page_label) @@ -331,8 +484,7 @@ ev_page_cache_set_page_label (EvPageCache *page_cache, /* convert from a page label to a page offset */ page --; if (page >= 0 && - page < page_cache->n_pages && - page_cache->page_labels[page] == NULL) { + page < page_cache->n_pages) { ev_page_cache_set_current_page (page_cache, page); return TRUE; } @@ -357,7 +509,7 @@ ev_page_cache_get_size (EvPageCache *page_cache, gint *width, gint *height) { - int w, h; + double w, h; g_return_if_fail (EV_IS_PAGE_CACHE (page_cache)); g_return_if_fail (page >= 0 && page < page_cache->n_pages); @@ -374,15 +526,15 @@ ev_page_cache_get_size (EvPageCache *page_cache, h = info->height; } - w = (int) (w * scale + 0.5); - h = (int) (h * scale + 0.5); + w = w * scale + 0.5; + h = h * scale + 0.5; if (rotation == 0 || rotation == 180) { - if (width) *width = w; - if (height) *height = h; + if (width) *width = (int)w; + if (height) *height = (int)h; } else { - if (width) *width = h; - if (height) *height = w; + if (width) *width = (int)h; + if (height) *height = (int)w; } } @@ -428,27 +580,54 @@ ev_page_cache_get_height_to_page (EvPageCache *page_cache, gint *height, gint *dual_height) { - double result = 0.0; - double dual_result = 0.0; - g_return_if_fail (EV_IS_PAGE_CACHE (page_cache)); + g_return_if_fail (page >= 0); + g_return_if_fail (!height || page <= page_cache->n_pages); + g_return_if_fail (!dual_height || page <= page_cache->n_pages + 1); if (page_cache->rotation != rotation) { page_cache->rotation = rotation; build_height_to_page (page_cache); } - - if (page > 0) - result = page_cache->height_to_page [page - 1]; if (height) - *height = result * scale; + *height = page_cache->height_to_page [page] * scale; - if (page > 1) - dual_result = page_cache->dual_height_to_page [page / 2 - 1]; - if (dual_height) - *dual_height = dual_result * scale; + *dual_height = page_cache->dual_height_to_page [page] * scale; +} + +void +ev_page_cache_get_thumbnail_size (EvPageCache *page_cache, + gint page, + gint rotation, + gint *width, + gint *height) +{ + gint w, h; + + g_return_if_fail (EV_IS_PAGE_CACHE (page_cache)); + g_return_if_fail (page >= 0 && page < page_cache->n_pages); + + if (page_cache->thumbs_uniform) { + w = page_cache->thumbs_uniform_width; + h = page_cache->thumbs_uniform_height; + } else { + EvPageThumbsInfo *info; + + info = &(page_cache->thumbs_size_cache [page]); + + w = info->width; + h = info->height; + } + + if (rotation == 0 || rotation == 180) { + if (width) *width = w; + if (height) *height = h; + } else { + if (width) *width = h; + if (height) *height = w; + } } gint @@ -459,6 +638,14 @@ ev_page_cache_get_max_label_chars (EvPageCache *page_cache) return page_cache->max_label_chars; } +gboolean +ev_page_cache_get_dual_even_left (EvPageCache *page_cache) +{ + g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), 0); + + return page_cache->dual_even_left; +} + gchar * ev_page_cache_get_page_label (EvPageCache *page_cache, gint page)