From 6c9ba464fdfc4b92f5d472705a53eb3f476431fb Mon Sep 17 00:00:00 2001 From: "Nickolay V. Shmyrev" Date: Sun, 5 Jun 2005 08:35:38 +0000 Subject: [PATCH] More compact EvView layout in documents with different page sizes --- ChangeLog | 15 +++ backend/ev-page-cache.c | 106 ++++++++++++++------ backend/ev-page-cache.h | 13 ++- shell/ev-view.c | 214 +++++++++++++++++----------------------- 4 files changed, 192 insertions(+), 156 deletions(-) diff --git a/ChangeLog b/ChangeLog index f3b8fb5f..bccef737 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2005-06-05 Nickolay V. Shmyrev + + * backend/ev-page-cache.c: (ev_page_cache_finalize), + (_ev_page_cache_new), (ev_page_cache_get_max_width), + (ev_page_cache_get_max_height), (ev_page_cache_get_height_to_page): + * backend/ev-page-cache.h: + * shell/ev-view.c: (scroll_to_current_page), + (view_update_range_and_current_page), (get_page_y_offset), + (get_page_extents), (ev_view_size_request_continuous_dual_page), + (ev_view_size_request_continuous), + (ev_view_zoom_for_size_continuous_and_dual_page), + (ev_view_zoom_for_size_continuous): + + More compact EvView layout in document with pages of different size. + Sat Jun 4 19:20:57 2005 Jonathan Blandford * shell/ev-window.c (ev_window_cmd_file_properties): fix diff --git a/backend/ev-page-cache.c b/backend/ev-page-cache.c index ad0a1fa2..17cd6414 100644 --- a/backend/ev-page-cache.c +++ b/backend/ev-page-cache.c @@ -27,10 +27,10 @@ struct _EvPageCache 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; + double max_width; + double max_height; + double* height_to_page; + double* dual_height_to_page; EvPageCacheInfo *size_cache; EvDocumentInfo *page_info; @@ -94,6 +94,9 @@ ev_page_cache_finalize (GObject *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); + ev_document_info_free (page_cache->page_info); } @@ -104,6 +107,7 @@ _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); @@ -116,10 +120,8 @@ _ev_page_cache_new (EvDocument *document) page_cache->has_labels = FALSE; page_cache->n_pages = ev_document_get_n_pages (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; + page_cache->max_width = 0; + page_cache->max_height = 0; doc_info = ev_document_get_info (document); if (doc_info->fields_mask & EV_DOCUMENT_INFO_TITLE) { @@ -151,16 +153,14 @@ _ev_page_cache_new (EvDocument *document) } } - 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_width > page_cache->max_width) { + page_cache->max_width = page_width; } - 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 (page_height > page_cache->max_height) { + page_cache->max_height = page_height; } - + if (i == 0) { page_cache->uniform_width = page_width; page_cache->uniform_height = page_height; @@ -189,6 +189,39 @@ _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]; + } + } + } + page_cache->page_info = ev_document_get_info (document); /* make some sanity check assertions */ @@ -326,34 +359,51 @@ ev_page_cache_get_size (EvPageCache *page_cache, } -/* Note that these aren't necessarily from the same page. - */ void -ev_page_cache_get_max_width_size (EvPageCache *page_cache, +ev_page_cache_get_max_width (EvPageCache *page_cache, gfloat scale, - gint *width, - gint *height) + gint *width) { 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; + *width = page_cache->max_width * scale; } void -ev_page_cache_get_max_height_size (EvPageCache *page_cache, +ev_page_cache_get_max_height (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; + *height = page_cache->max_height * scale; +} + +void +ev_page_cache_get_height_to_page (EvPageCache *page_cache, + gint page, + 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 (height) + *height = result * scale; + + if (page > 1) + dual_result = page_cache->dual_height_to_page [page / 2 - 1]; + + if (dual_height) + *dual_height = dual_result * scale; } gint diff --git a/backend/ev-page-cache.h b/backend/ev-page-cache.h index 22557f14..053fd366 100644 --- a/backend/ev-page-cache.h +++ b/backend/ev-page-cache.h @@ -39,14 +39,17 @@ void ev_page_cache_get_size (EvPageCache *page_cache, gfloat scale, gint *width, gint *height); -void ev_page_cache_get_max_width_size (EvPageCache *page_cache, +void ev_page_cache_get_max_width (EvPageCache *page_cache, gfloat scale, - gint *width, - gint *height); -void ev_page_cache_get_max_height_size (EvPageCache *page_cache, + gint *width); +void ev_page_cache_get_max_height (EvPageCache *page_cache, gfloat scale, - gint *width, gint *height); +void ev_page_cache_get_height_to_page (EvPageCache *page_cache, + gint page, + gfloat scale, + gint *height, + gint *dual_height); gint ev_page_cache_get_max_label_chars (EvPageCache *page_cache); char *ev_page_cache_get_page_label (EvPageCache *page_cache, gint page); diff --git a/shell/ev-view.c b/shell/ev-view.c index 4ea0fce2..a4032e9e 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -141,7 +141,6 @@ struct _EvView { int spacing; double scale; - GtkBorder border; gboolean continuous; gboolean dual_page; @@ -166,6 +165,8 @@ struct _EvViewClass { }; /*** Scrolling ***/ +static void scroll_to_current_page (EvView *view, + GtkOrientation orientation); static void ev_view_set_scroll_adjustments (EvView *view, GtkAdjustment *hadjustment, GtkAdjustment *vadjustment); @@ -191,6 +192,10 @@ static void compute_border (EvView int width, int height, GtkBorder *border); +static void get_page_y_offset (EvView *view, + int page, + double zoom, + int *y_offset); static gboolean get_page_extents (EvView *view, gint page, GdkRectangle *page_area, @@ -203,9 +208,6 @@ static void doc_rect_to_view_rect (EvView int page, EvRectangle *doc_rect, GdkRectangle *view_rect); -static void get_bounding_box_size (EvView *view, - int *max_width, - int *max_height); static void find_page_at_location (EvView *view, gdouble x, gdouble y, @@ -357,35 +359,25 @@ G_DEFINE_TYPE (EvView, ev_view, GTK_TYPE_WIDGET) static void scroll_to_current_page (EvView *view, GtkOrientation orientation) { - int max_width, max_height, n_rows; - - get_bounding_box_size (view, &max_width, &max_height); - + GdkRectangle page_area; + GtkBorder border; + + get_page_extents (view, view->current_page, &page_area, &border); + if (orientation == GTK_ORIENTATION_VERTICAL) { if (view->continuous) { - n_rows = view->dual_page ? view->current_page / 2 : view->current_page; - gtk_adjustment_clamp_page (view->vadjustment, - (max_height + view->spacing) * n_rows, - (max_height + view->spacing) * n_rows + - view->vadjustment->page_size); + page_area.y - view->spacing, + page_area.y + view->vadjustment->page_size); } else { gtk_adjustment_set_value (view->vadjustment, view->vadjustment->lower); } } else { if (view->dual_page) { - if (view->current_page % 2 == 0) { - gtk_adjustment_set_value (view->hadjustment, - view->hadjustment->lower); - } else { - gtk_adjustment_clamp_page (view->hadjustment, - view->hadjustment->lower + - max_width + view->spacing, - view->hadjustment->lower + - max_width + view->spacing + - view->hadjustment->page_size); - } + gtk_adjustment_clamp_page (view->hadjustment, + page_area.x, + page_area.x + view->hadjustment->page_size); } else { gtk_adjustment_set_value (view->hadjustment, CLAMP (view->hadjustment->value, @@ -469,31 +461,23 @@ view_update_range_and_current_page (EvView *view) view->end_page = view->current_page; } else if (view->continuous) { GdkRectangle current_area, unused, page_area; + GtkBorder border; gint current_page; gboolean found = FALSE; int i; - get_bounding_box_size (view, &(page_area.width), &(page_area.height)); - page_area.x = view->spacing; - page_area.y = view->spacing; - - if (view->hadjustment) { - current_area.x = view->hadjustment->value; - current_area.width = view->hadjustment->page_size; - } else { - current_area.x = page_area.x; - current_area.width = page_area.width; - } - - if (view->vadjustment) { - current_area.y = view->vadjustment->value; - current_area.height = view->vadjustment->page_size; - } else { - current_area.y = page_area.y; - current_area.height = page_area.height; - } + if (!(view->vadjustment && view->hadjustment)) + return; + + current_area.x = view->hadjustment->value; + current_area.width = view->hadjustment->upper; + current_area.y = view->vadjustment->value; + current_area.height = view->vadjustment->page_size; for (i = 0; i < ev_page_cache_get_n_pages (view->page_cache); i++) { + + get_page_extents (view, i, &page_area, &border); + if (gdk_rectangle_intersect (¤t_area, &page_area, &unused)) { if (! found) { view->start_page = i; @@ -504,18 +488,8 @@ view_update_range_and_current_page (EvView *view) } else if (found) { break; } - if (view->dual_page) { - if (i % 2 == 0) { - page_area.x += page_area.width + view->spacing; - } else { - page_area.x = view->spacing; - page_area.y += page_area.height + view->spacing; - } - } else { - page_area.y += page_area.height + view->spacing; - } } - + current_page = ev_page_cache_get_current_page (view->page_cache); if (current_page < view->start_page || current_page > view->end_page) { @@ -740,6 +714,32 @@ compute_border (EvView *view, int width, int height, GtkBorder *border) } } +static void get_page_y_offset (EvView *view, + int page, + double zoom, + int *y_offset) +{ + int max_width, offset; + GtkBorder border; + + g_return_if_fail (y_offset != NULL); + + ev_page_cache_get_max_width (view->page_cache, zoom, &max_width); + + compute_border (view, max_width, max_width, &border); + + if (view->dual_page) { + ev_page_cache_get_height_to_page (view->page_cache, page, zoom, NULL, &offset); + offset += (page / 2 + 1) * view->spacing + (page / 2) * (border.top + border.bottom); + } else { + ev_page_cache_get_height_to_page (view->page_cache, page, zoom, &offset, NULL); + offset += (page + 1) * view->spacing + page * (border.top + border.bottom); + } + + *y_offset = offset; + return; +} + static gboolean get_page_extents (EvView *view, gint page, @@ -751,22 +751,6 @@ get_page_extents (EvView *view, widget = GTK_WIDGET (view); - /* Quick sanity check */ - if (view->presentation) { - if (view->current_page != page) - return FALSE; - } else if (view->continuous) { - if (page < view->start_page || - page > view->end_page) - return FALSE; - } else if (view->dual_page) { - if (ABS (page - view->current_page) > 1) - return FALSE; - } else { - if (view->current_page != page) - return FALSE; - } - /* Get the size of the page */ ev_page_cache_get_size (view->page_cache, page, view->scale, @@ -779,20 +763,24 @@ get_page_extents (EvView *view, page_area->x = (MAX (0, widget->allocation.width - width))/2; page_area->y = (MAX (0, widget->allocation.height - height))/2; } else if (view->continuous) { - gint max_width, max_height; + gint max_width; gint x, y; - get_bounding_box_size (view, &max_width, &max_height); + ev_page_cache_get_max_width (view->page_cache, view->scale, &max_width); + max_width = max_width + border->left + border->right; /* Get the location of the bounding box */ if (view->dual_page) { x = view->spacing + (page % 2) * (max_width + view->spacing); - y = view->spacing + (page / 2) * (max_height + view->spacing); - x = x + MAX (0, widget->allocation.width - (max_width * 2 + view->spacing * 3))/2; + x = x + MAX (0, widget->allocation.width - (max_width * 2 + view->spacing * 3)) / 2; + if (page % 2 == 0) + x = x + (max_width - width - border->left - border->right); } else { x = view->spacing; - y = view->spacing + page * (max_height + view->spacing); - x = x + MAX (0, widget->allocation.width - (max_width + view->spacing * 2))/2; + x = x + MAX (0, widget->allocation.width - (width + view->spacing * 2)) / 2; } + + get_page_y_offset (view, page, view->scale, &y); + page_area->x = x; page_area->y = y; } else { @@ -883,30 +871,6 @@ doc_rect_to_view_rect (EvView *view, view_rect->height = ceil (height * view->scale); } -static void -get_bounding_box_size (EvView *view, int *max_width, int *max_height) -{ - GtkBorder border; - int width, height; - - if (max_width) { - ev_page_cache_get_max_width_size (view->page_cache, - view->scale, - &width, &height); - compute_border (view, width, height, &border); - *max_width = width + border.left + border.right; - } - - - if (max_height) { - ev_page_cache_get_max_height_size (view->page_cache, - view->scale, - &width, &height); - compute_border (view, width, height, &border); - *max_height = height + border.top + border.bottom; - } -} - static void find_page_at_location (EvView *view, gdouble x, @@ -1026,17 +990,19 @@ status_message_from_link (EvView *view, EvLink *link) static void ev_view_size_request_continuous_dual_page (EvView *view, - GtkRequisition *requisition) + GtkRequisition *requisition) { - int max_width, max_height; - int n_rows; + int max_width; + gint n_pages; + GtkBorder border; - get_bounding_box_size (view, &max_width, &max_height); + ev_page_cache_get_max_width (view->page_cache, view->scale, &max_width); + compute_border (view, max_width, max_width, &border); - n_rows = (1 + ev_page_cache_get_n_pages (view->page_cache)) / 2; + n_pages = ev_page_cache_get_n_pages (view->page_cache) + 1; - requisition->width = (max_width * 2) + (view->spacing * 3); - requisition->height = max_height * n_rows + (view->spacing * (n_rows + 1)); + requisition->width = (max_width + border.left + border.right) * 2 + (view->spacing * 3); + get_page_y_offset (view, n_pages, view->scale, &requisition->height); if (view->sizing_mode == EV_SIZING_FIT_WIDTH) { requisition->width = 1; @@ -1052,15 +1018,17 @@ static void ev_view_size_request_continuous (EvView *view, GtkRequisition *requisition) { - int max_width, max_height; + int max_width; int n_pages; + GtkBorder border; - get_bounding_box_size (view, &max_width, &max_height); + ev_page_cache_get_max_width (view->page_cache, view->scale, &max_width); n_pages = ev_page_cache_get_n_pages (view->page_cache); + compute_border (view, max_width, max_width, &border); - requisition->width = max_width + (view->spacing * 2); - requisition->height = max_height * n_pages + (view->spacing * (n_pages + 1)); + requisition->width = max_width + (view->spacing * 2) + border.left + border.right; + get_page_y_offset (view, n_pages, view->scale, &requisition->height); if (view->sizing_mode == EV_SIZING_FIT_WIDTH) { requisition->width = 1; @@ -2225,12 +2193,12 @@ ev_view_zoom_for_size_continuous_and_dual_page (EvView *view, GtkBorder border; gdouble scale; - ev_page_cache_get_max_width_size (view->page_cache, - 1.0, - &doc_width, NULL); - ev_page_cache_get_max_height_size (view->page_cache, - 1.0, - NULL, &doc_height); + ev_page_cache_get_max_width (view->page_cache, + 1.0, + &doc_width); + ev_page_cache_get_max_height (view->page_cache, + 1.0, + &doc_height); compute_border (view, doc_width, doc_height, &border); doc_width = doc_width * 2; @@ -2261,12 +2229,12 @@ ev_view_zoom_for_size_continuous (EvView *view, GtkBorder border; gdouble scale; - ev_page_cache_get_max_width_size (view->page_cache, - 1.0, - &doc_width, NULL); - ev_page_cache_get_max_height_size (view->page_cache, - 1.0, - NULL, &doc_height); + ev_page_cache_get_max_width (view->page_cache, + 1.0, + &doc_width); + ev_page_cache_get_max_height (view->page_cache, + 1.0, + &doc_height); compute_border (view, doc_width, doc_height, &border); width -= (border.left + border.right + 2 * view->spacing); -- 2.43.5