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=ebf0de7f9b69f8d2409e51d69f75dabb0438d4aa;hb=217797d63b2d3b1c9a7a0511af1bbf3d99f0d482;hp=936328ffc9e90ab4be42ac53062ea4a4e960da6e;hpb=79986dda7231d1ef1c530909bde8e18a507a2a2a;p=evince.git diff --git a/shell/ev-page-cache.c b/shell/ev-page-cache.c index 936328ff..ebf0de7f 100644 --- a/shell/ev-page-cache.c +++ b/shell/ev-page-cache.c @@ -23,15 +23,19 @@ struct _EvPageCache gint max_label_chars; gboolean has_labels; gboolean uniform; + gboolean dual_even_left; double uniform_width; double uniform_height; double max_width; double max_height; + double* height_to_page; double* dual_height_to_page; + int rotation; + EvPageCacheInfo *size_cache; EvDocumentInfo *page_info; }; @@ -41,11 +45,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, }; @@ -83,6 +89,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 @@ -92,12 +108,129 @@ ev_page_cache_finalize (GObject *object) page_cache = EV_PAGE_CACHE (object); - g_free (page_cache->title); - g_free (page_cache->size_cache); + 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; + } + + G_OBJECT_CLASS (ev_page_cache_parent_class)->finalize (object); +} + +static void +build_height_to_page (EvPageCache *page_cache) +{ + gboolean swap; + int i; + double uniform_height, page_height, next_page_height; + double saved_height; + + swap = (page_cache->rotation == 90 || + page_cache->rotation == 270); + g_free (page_cache->height_to_page); g_free (page_cache->dual_height_to_page); - ev_document_info_free (page_cache->page_info); + 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++) { + 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 * uniform_height; + } else { + if (!swap) { + page_height = page_cache->size_cache [i].height; + } else { + page_height = page_cache->size_cache [i].width; + } + page_cache->height_to_page [i] = saved_height; + saved_height += page_height; + } + } + + 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] = ((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 (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 { + next_page_height = 0; + } + 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; + } + 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; + } + } + } } EvPageCache * @@ -106,7 +239,6 @@ ev_page_cache_new (EvDocument *document) EvPageCache *page_cache; EvPageCacheInfo *info; gint i; - double saved_height; page_cache = (EvPageCache *) g_object_new (EV_TYPE_PAGE_CACHE, NULL); @@ -118,6 +250,7 @@ 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; @@ -187,43 +320,12 @@ ev_page_cache_new (EvDocument *document) } } - 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); - - saved_height = 0; - for (i = 0; i < page_cache->n_pages; i++) { - - if (page_cache->uniform) { - page_cache->height_to_page [i] = (i + 1) * page_cache->uniform_height; - } else { - page_cache->height_to_page [i] = saved_height + page_cache->size_cache [i].height; - saved_height = page_cache->height_to_page [i]; - } - } - - saved_height = 0; - for (i = 0; i < page_cache->n_pages; i += 2) { - - if (page_cache->uniform) { - page_cache->dual_height_to_page [i / 2] = (i / 2 + 1) * page_cache->uniform_height; - } else { - if (i == page_cache->n_pages - 1) { - page_cache->dual_height_to_page [i / 2] = - saved_height + page_cache->size_cache [i].height; - } - else { - page_cache->dual_height_to_page [i / 2] = saved_height + - MAX(page_cache->size_cache [i].height, - page_cache->size_cache [i + 1].height); - saved_height = page_cache->dual_height_to_page [i / 2]; - } - } - } + build_height_to_page (page_cache); /* make some sanity check assertions */ if (! page_cache->uniform) g_assert (page_cache->size_cache != NULL); - if (page_cache->uniform) + if (page_cache->uniform && page_cache->n_pages > 0) g_assert (page_cache->uniform_width > 0 && page_cache->uniform_height > 0); ev_document_doc_mutex_unlock (); @@ -264,6 +366,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) @@ -293,8 +405,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; } @@ -303,16 +414,6 @@ ev_page_cache_set_page_label (EvPageCache *page_cache, return FALSE; } -void -ev_page_cache_set_link (EvPageCache *page_cache, - EvLink *link) -{ - g_return_if_fail (EV_IS_PAGE_CACHE (page_cache)); - g_return_if_fail (EV_IS_LINK (link)); - - ev_page_cache_set_current_page (page_cache, ev_link_get_page (link)); -} - const char * ev_page_cache_get_title (EvPageCache *page_cache) { @@ -322,84 +423,96 @@ ev_page_cache_get_title (EvPageCache *page_cache) } void -ev_page_cache_get_size (EvPageCache *page_cache, - gint page, - gfloat scale, - gint *width, - gint *height) +ev_page_cache_get_size (EvPageCache *page_cache, + gint page, + gint rotation, + gfloat scale, + gint *width, + gint *height) { + double 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->uniform) { - if (width) - *width = page_cache->uniform_width; - if (height) - *height = page_cache->uniform_height; + w = page_cache->uniform_width; + h = page_cache->uniform_height; } else { EvPageCacheInfo *info; info = &(page_cache->size_cache [page]); - if (width) - *width = info->width; - if (height) - *height = info->height; + w = info->width; + h = info->height; } - if (width) - *width = (int) ((*width) * scale + 0.5); - if (width) - *height = (int) ((*height) * scale + 0.5); + w = w * scale + 0.5; + h = h * scale + 0.5; + if (rotation == 0 || rotation == 180) { + if (width) *width = (int)w; + if (height) *height = (int)h; + } else { + if (width) *width = (int)h; + if (height) *height = (int)w; + } } - void -ev_page_cache_get_max_width (EvPageCache *page_cache, - gfloat scale, - gint *width) +ev_page_cache_get_max_width (EvPageCache *page_cache, + gint rotation, + gfloat scale, + gint *width) { g_return_if_fail (EV_IS_PAGE_CACHE (page_cache)); - if (width) - *width = page_cache->max_width * scale; + if (width) { + if (rotation == 0 || rotation == 180) { + *width = page_cache->max_width * scale; + } else { + *width = page_cache->max_height * scale; + } + } } void -ev_page_cache_get_max_height (EvPageCache *page_cache, - gfloat scale, - gint *height) +ev_page_cache_get_max_height (EvPageCache *page_cache, + gint rotation, + gfloat scale, + gint *height) { g_return_if_fail (EV_IS_PAGE_CACHE (page_cache)); - if (height) - *height = page_cache->max_height * scale; + if (height) { + if (rotation == 0 || rotation == 180) { + *height = page_cache->max_height * scale; + } else { + *height = page_cache->max_width * scale; + } + } } void -ev_page_cache_get_height_to_page (EvPageCache *page_cache, - gint page, - gfloat scale, - gint *height, - gint *dual_height) +ev_page_cache_get_height_to_page (EvPageCache *page_cache, + gint page, + gint rotation, + gfloat scale, + gint *height, + gint *dual_height) { - double result = 0.0; - double dual_result = 0.0; - g_return_if_fail (EV_IS_PAGE_CACHE (page_cache)); - if (page > 0) - result = page_cache->height_to_page [page - 1]; + if (page_cache->rotation != rotation) { + page_cache->rotation = rotation; + build_height_to_page (page_cache); + } 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; } gint @@ -410,6 +523,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) @@ -438,32 +559,6 @@ ev_page_cache_get_info (EvPageCache *page_cache) 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 - 1) - return FALSE; - - ev_page_cache_set_current_page (page_cache, page_cache->current_page + 1); - return TRUE; - -} - -gboolean -ev_page_cache_prev_page (EvPageCache *page_cache) -{ - g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), FALSE); - - if (page_cache->current_page <= 0) - return FALSE; - - ev_page_cache_set_current_page (page_cache, page_cache->current_page - 1); - return TRUE; -} - #define PAGE_CACHE_STRING "ev-page-cache" EvPageCache * @@ -481,11 +576,3 @@ ev_page_cache_get (EvDocument *document) return page_cache; } - -void -ev_page_cache_clear (EvDocument *document) -{ - g_return_if_fail (EV_IS_DOCUMENT (document)); - - g_object_set_data (G_OBJECT (document), PAGE_CACHE_STRING, NULL); -}