From 42ddc3073ecb88271a0ffc74326878627d71b34e Mon Sep 17 00:00:00 2001 From: Martin Kretzschmar Date: Tue, 15 Feb 2005 08:26:23 +0000 Subject: add parameters providing allocation width and height without scrollbars * shell/ev-view.c (ev_view_best_fit, ev_view_fit_width): add parameters providing allocation width and height without scrollbars and width of a possible vertical scrollbar. With this additional information the functions can work as intended. Unfortunately they're not idempotent. We should transform these commands to toggles. Fixes Bug #164976 Initial patch by Stephane Loeuillet, then heavily modified. * shell/ev-view.h: update prototypes. * shell/ev-window.c (ev_window_cmd_view_best_fit) (ev_window_cmd_view_page_width): provide EvView fit functions with all the information they need. Formulas to calculate this information taken from GtkScrolledWindow. --- (limited to 'shell') diff --git a/shell/ev-view.c b/shell/ev-view.c index 8fd8723..e3c81a0 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -1233,21 +1233,34 @@ ev_view_normal_size (EvView *view) ev_view_zoom (view, 1.0, FALSE); } +/* Unfortunately this is not idempotent (!) (numerical stability + * issues because width and height are rounded) + * + * One more reason to make this a toggle and not a command */ void -ev_view_best_fit (EvView *view) +ev_view_best_fit (EvView *view, int allocation_width, int allocation_height) { double scale; + int available_width, available_height; int width, height; width = height = 0; + /* This is the bad part. You could make it stable by doing + * ev_document_set_scale 1.0. But at least with pdf this means + * redrawing the whole page */ ev_document_get_page_size (view->document, -1, &width, &height); + LOG ("Best fit %d %d", allocation_width, allocation_height); + scale = 1.0; if (width != 0 && height != 0) { double scale_w, scale_h; - scale_w = (double)GTK_WIDGET (view)->allocation.width * view->scale / width; - scale_h = (double)GTK_WIDGET (view)->allocation.height * view->scale / height; + available_width = MAX (1, allocation_width - 2); /* 1 px border left and right */ + available_height = MAX (1, allocation_height - 2); /* 1 px border above and below */ + + scale_w = (double)available_width * view->scale / (width + 0.5); + scale_h = (double)available_height * view->scale / (height + 0.5); scale = (scale_w < scale_h) ? scale_w : scale_h; } @@ -1256,17 +1269,27 @@ ev_view_best_fit (EvView *view) } void -ev_view_fit_width (EvView *view) +ev_view_fit_width (EvView *view, int allocation_width, int allocation_height, + int vsb_width) { + int available_width, available_height; + int width, height; double scale = 1.0; - int width; - width = 0; - ev_document_get_page_size (view->document, -1, &width, NULL); + width = height = 0; + ev_document_get_page_size (view->document, -1, &width, &height); scale = 1.0; - if (width != 0) - scale = (double)GTK_WIDGET (view)->allocation.width * view->scale / width; + if (width != 0) { + available_width = MAX (1, allocation_width - 2); /* 1px border */ + available_height = MAX (1, allocation_height - 2); /* 1px border */ + + scale = (double)available_width * view->scale / (width + 0.5); + + if ((height + 0.5) * scale / view->scale > available_height) + scale = ((double)(available_width - vsb_width) * view->scale / + (width + 0.5)); + } ev_view_zoom (view, scale, FALSE); } diff --git a/shell/ev-view.h b/shell/ev-view.h index a72ed6b..f108f9f 100644 --- a/shell/ev-view.h +++ b/shell/ev-view.h @@ -58,8 +58,8 @@ int ev_view_get_page (EvView *view); void ev_view_zoom_in (EvView *view); void ev_view_zoom_out (EvView *view); void ev_view_normal_size (EvView *view); -void ev_view_best_fit (EvView *view); -void ev_view_fit_width (EvView *view); +void ev_view_best_fit (EvView *view, int width, int height); +void ev_view_fit_width (EvView *view, int width, int height, int vsb_width); /* Find */ void ev_view_find_next (EvView *view); diff --git a/shell/ev-window.c b/shell/ev-window.c index a1d74f6..547eaf0 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -1197,17 +1197,49 @@ ev_window_cmd_view_normal_size (GtkAction *action, EvWindow *ev_window) static void ev_window_cmd_view_best_fit (GtkAction *action, EvWindow *ev_window) { + EvWindowPrivate *priv = ev_window->priv; + int width, height; + g_return_if_fail (EV_IS_WINDOW (ev_window)); - ev_view_best_fit (EV_VIEW (ev_window->priv->view)); + width = priv->scrolled_window->allocation.width; + height = priv->scrolled_window->allocation.height; + + /* the scrolled window has a GTK_SHADOW_IN */ + width -= 2 * priv->view->style->xthickness; + height -= 2 * priv->view->style->ythickness; + + ev_view_best_fit (EV_VIEW (priv->view), + MAX (1, width), MAX (1, height)); } static void ev_window_cmd_view_page_width (GtkAction *action, EvWindow *ev_window) { + EvWindowPrivate *priv = ev_window->priv; + int width, height; + GtkRequisition vsb_requisition; + int scrollbar_spacing; + g_return_if_fail (EV_IS_WINDOW (ev_window)); - ev_view_fit_width (EV_VIEW (ev_window->priv->view)); + width = priv->scrolled_window->allocation.width; + height = priv->scrolled_window->allocation.height; + + /* the scrolled window has a GTK_SHADOW_IN */ + width -= 2 * priv->view->style->xthickness; + height -= 2 * priv->view->style->ythickness; + + gtk_widget_size_request ( + GTK_SCROLLED_WINDOW (priv->scrolled_window)->vscrollbar, + &vsb_requisition); + gtk_widget_style_get (priv->scrolled_window, + "scrollbar_spacing", &scrollbar_spacing, + NULL); + + ev_view_fit_width (EV_VIEW (ev_window->priv->view), + width, height, + vsb_requisition.width + scrollbar_spacing); } static void -- cgit v0.9.1