+2005-02-14 Martin Kretzschmar <martink@gnome.org>
+
+ * 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.
+
2005-02-14 Crispin Flowerday <gnome@flowerday.cx>
* shell/ev-sidebar-thumbnails.c: Ensure that after we have
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;
}
}
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);
}
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);
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