From 80a9ffebfe5125584341d4fb005ee1a29219c970 Mon Sep 17 00:00:00 2001 From: Jonathan Blandford Date: Fri, 20 May 2005 05:08:11 +0000 Subject: Use gdk_window_scroll instead of gtk_widget_queue_draw. Massive speedups Fri May 20 01:07:15 2005 Jonathan Blandford * shell/ev-view.c (view_update_adjustments): Use gdk_window_scroll instead of gtk_widget_queue_draw. Massive speedups in scrolling. Fri May 20 01:05:10 2005 Jonathan Blandford * .cvsignore: * shell/ev-view.c:(ev_view_size_allocate), (ev_view_class_init), (zoom_for_size_fit_width), (zoom_for_size_best_fit), (ev_view_zoom_for_size_presentation), (ev_view_zoom_for_size_continuous_and_dual_page), (ev_view_zoom_for_size_continuous), (ev_view_zoom_for_size_dual_page), (ev_view_zoom_for_size_single_page), (ev_view_set_zoom_for_size): * shell/ev-view.h: * shell/ev-window.c: (update_view_size), (ev_window_sizing_mode_changed_cb): Patch from Nickolay Shmyrev to handle the scrollbars. It's not 100% right, but it's much closer. Kills an infinite loop, #304769 --- diff --git a/.cvsignore b/.cvsignore index 20fcfd4..bb30019 100644 --- a/.cvsignore +++ b/.cvsignore @@ -3,6 +3,7 @@ Makefile.in aclocal.m4 autom4te.cache callgrind.out.* +compile config.guess config.h config.h.in diff --git a/ChangeLog b/ChangeLog index 6c59708..ac328e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +Fri May 20 01:07:15 2005 Jonathan Blandford + + * shell/ev-view.c (view_update_adjustments): Use gdk_window_scroll + instead of gtk_widget_queue_draw. Massive speedups in scrolling. + +Fri May 20 01:05:10 2005 Jonathan Blandford + + * .cvsignore: + * shell/ev-view.c:(ev_view_size_allocate), (ev_view_class_init), + (zoom_for_size_fit_width), (zoom_for_size_best_fit), + (ev_view_zoom_for_size_presentation), + (ev_view_zoom_for_size_continuous_and_dual_page), + (ev_view_zoom_for_size_continuous), + (ev_view_zoom_for_size_dual_page), + (ev_view_zoom_for_size_single_page), (ev_view_set_zoom_for_size): + * shell/ev-view.h: + * shell/ev-window.c: (update_view_size), + (ev_window_sizing_mode_changed_cb): + + Patch from Nickolay Shmyrev to handle + the scrollbars. It's not 100% right, but it's much closer. Kills + an infinite loop, #304769 + + 2005-05-18 Marco Pesenti Gritti * data/evince-ui.xml: diff --git a/shell/ev-view.c b/shell/ev-view.c index 552b771..3da8d13 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -52,6 +52,12 @@ enum { }; enum { + SIGNAL_SCROLL_VIEW, + SIGNAL_ZOOM_INVALID, + N_SIGNALS, +}; + +enum { TARGET_STRING, TARGET_TEXT, TARGET_COMPOUND_TEXT, @@ -66,6 +72,8 @@ static const GtkTargetEntry targets[] = { { "UTF8_STRING", 0, TARGET_UTF8_STRING }, }; +static guint signals[N_SIGNALS]; + typedef enum { EV_VIEW_CURSOR_NORMAL, EV_VIEW_CURSOR_LINK, @@ -152,6 +160,7 @@ struct _EvViewClass { void (*scroll_view) (EvView *view, GtkScrollType scroll, gboolean horizontal); + void (*zoom_invalid) (EvView *view); }; /*** Scrolling ***/ @@ -281,33 +290,40 @@ static void ev_view_class_init (EvViewClass static void ev_view_init (EvView *view); /*** Zoom and sizing ***/ -static double zoom_for_size_fit_width (int doc_width, - int doc_height, - int target_width, - int target_height); -static double zoom_for_size_best_fit (int doc_width, - int doc_height, - int target_width, - int target_height); -static void ev_view_zoom_for_size_presentation (EvView *view, - int width, - int height); -static void ev_view_zoom_for_size_continuous_dual_page (EvView *view, - int width, - int height); -static void ev_view_zoom_for_size_continuous (EvView *view, - int width, - int height); -static void ev_view_zoom_for_size_dual_page (EvView *view, - int width, - int height); -static void ev_view_zoom_for_size_single_page (EvView *view, - int width, - int height); -static void ev_view_set_zoom_for_size (EvView *view, - int width, - int height); - +static double zoom_for_size_fit_width (int doc_width, + int doc_height, + int target_width, + int target_height, + int vsb_width); +static double zoom_for_size_best_fit (int doc_width, + int doc_height, + int target_width, + int target_height, + int vsb_width, + int hsb_width); +static void ev_view_zoom_for_size_presentation (EvView *view, + int width, + int height); +static void ev_view_zoom_for_size_continuous_and_dual_page (EvView *view, + int width, + int height, + int vsb_width, + int hsb_height); +static void ev_view_zoom_for_size_continuous (EvView *view, + int width, + int height, + int vsb_width, + int hsb_height); +static void ev_view_zoom_for_size_dual_page (EvView *view, + int width, + int height, + int vsb_width, + int hsb_height); +static void ev_view_zoom_for_size_single_page (EvView *view, + int width, + int height, + int vsb_width, + int hsb_height); /*** Cursors ***/ static GdkCursor* ev_view_create_invisible_cursor (void); static void ev_view_set_cursor (EvView *view, @@ -342,17 +358,28 @@ G_DEFINE_TYPE (EvView, ev_view, GTK_TYPE_WIDGET) static void view_update_adjustments (EvView *view) { - if (view->hadjustment) + int dx = 0, dy = 0; + + if (! GTK_WIDGET_REALIZED (view)) + return; + + if (view->hadjustment) { + dx = view->scroll_x - view->hadjustment->value; view->scroll_x = view->hadjustment->value; - else + } else { view->scroll_x = 0; + } - if (view->vadjustment) + if (view->vadjustment) { + dy = view->scroll_y - view->vadjustment->value; view->scroll_y = view->vadjustment->value; - else + } else { view->scroll_y = 0; + } - gtk_widget_queue_draw (GTK_WIDGET (view)); + // gtk_widget_queue_draw (GTK_WIDGET (view)); + gdk_window_scroll (GTK_WIDGET (view)->window, dx, dy); + if (view->document) view_update_range_and_current_page (view); @@ -1178,12 +1205,12 @@ ev_view_size_allocate (GtkWidget *widget, if (view->sizing_mode == EV_SIZING_FIT_WIDTH || view->sizing_mode == EV_SIZING_BEST_FIT) { - - ev_view_set_zoom_for_size (view, allocation->width, allocation->height); - ev_view_size_request (widget, &widget->requisition); - } - + g_signal_emit (view, signals[SIGNAL_ZOOM_INVALID], 0); + + ev_view_size_request (widget, &widget->requisition); + } + view_set_adjustment_values (view, GTK_ORIENTATION_HORIZONTAL); view_set_adjustment_values (view, GTK_ORIENTATION_VERTICAL); @@ -1747,7 +1774,7 @@ ev_view_class_init (EvViewClass *class) GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT); - g_signal_new ("scroll_view", + signals[SIGNAL_SCROLL_VIEW] = g_signal_new ("scroll-view", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (EvViewClass, scroll_view), @@ -1757,6 +1784,14 @@ ev_view_class_init (EvViewClass *class) GTK_TYPE_SCROLL_TYPE, G_TYPE_BOOLEAN); + signals[SIGNAL_ZOOM_INVALID] = g_signal_new ("zoom-invalid", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EvViewClass, zoom_invalid), + NULL, NULL, + ev_marshal_VOID__VOID, + G_TYPE_NONE, 0, G_TYPE_NONE); + g_object_class_install_property (object_class, PROP_STATUS, g_param_spec_string ("status", @@ -2111,20 +2146,19 @@ ev_view_zoom_out (EvView *view) ev_view_set_zoom (view, ZOOM_OUT_FACTOR, TRUE); } - - static double zoom_for_size_fit_width (int doc_width, int doc_height, int target_width, - int target_height) + int target_height, + int vsb_width) { double scale; scale = (double)target_width / doc_width; if (doc_height * scale > target_height) - scale = (double) (target_width) / doc_width; + scale = (double) (target_width - vsb_width) / doc_width; return scale; } @@ -2133,7 +2167,9 @@ static double zoom_for_size_best_fit (int doc_width, int doc_height, int target_width, - int target_height) + int target_height, + int vsb_width, + int hsb_width) { double w_scale; double h_scale; @@ -2142,9 +2178,9 @@ zoom_for_size_best_fit (int doc_width, h_scale = (double)target_height / doc_height; if (doc_height * w_scale > target_height) - w_scale = (double) target_width / doc_width; + w_scale = (double) (target_width - vsb_width) / doc_width; if (doc_width * h_scale > target_width) - h_scale = (double) target_height / doc_height; + h_scale = (double) (target_height - hsb_width) / doc_height; return MIN (w_scale, h_scale); } @@ -2163,14 +2199,16 @@ ev_view_zoom_for_size_presentation (EvView *view, 1.0, &doc_width, &doc_height); - scale = zoom_for_size_best_fit (doc_width, doc_height, width, height); + scale = zoom_for_size_best_fit (doc_width, doc_height, width, height, 0, 0); ev_view_set_zoom (view, scale, FALSE); } static void -ev_view_zoom_for_size_continuous_dual_page (EvView *view, +ev_view_zoom_for_size_continuous_and_dual_page (EvView *view, int width, - int height) + int height, + int vsb_width, + int hsb_height) { int doc_width, doc_height; GtkBorder border; @@ -2192,9 +2230,9 @@ ev_view_zoom_for_size_continuous_dual_page (EvView *view, * page height. We assume there's always a vertical scrollbar for * now. We need to fix this. */ if (view->sizing_mode == EV_SIZING_FIT_WIDTH) - scale = zoom_for_size_fit_width (doc_width, doc_height, width, height); + scale = zoom_for_size_fit_width (doc_width, doc_height, width - vsb_width, height, 0); else if (view->sizing_mode == EV_SIZING_BEST_FIT) - scale = zoom_for_size_best_fit (doc_width, doc_height, width, height); + scale = zoom_for_size_best_fit (doc_width, doc_height, width - vsb_width, height, 0, hsb_height); else g_assert_not_reached (); @@ -2204,7 +2242,9 @@ ev_view_zoom_for_size_continuous_dual_page (EvView *view, static void ev_view_zoom_for_size_continuous (EvView *view, int width, - int height) + int height, + int vsb_width, + int hsb_height) { int doc_width, doc_height; GtkBorder border; @@ -2225,9 +2265,9 @@ ev_view_zoom_for_size_continuous (EvView *view, * page height. We assume there's always a vertical scrollbar for * now. We need to fix this. */ if (view->sizing_mode == EV_SIZING_FIT_WIDTH) - scale = zoom_for_size_fit_width (doc_width, doc_height, width, height); + scale = zoom_for_size_fit_width (doc_width, doc_height, width - vsb_width, height, 0); else if (view->sizing_mode == EV_SIZING_BEST_FIT) - scale = zoom_for_size_best_fit (doc_width, doc_height, width, height); + scale = zoom_for_size_best_fit (doc_width, doc_height, width - vsb_width, height, 0, hsb_height); else g_assert_not_reached (); @@ -2237,7 +2277,9 @@ ev_view_zoom_for_size_continuous (EvView *view, static void ev_view_zoom_for_size_dual_page (EvView *view, int width, - int height) + int height, + int vsb_width, + int hsb_height) { GtkBorder border; gint doc_width, doc_height; @@ -2270,9 +2312,9 @@ ev_view_zoom_for_size_dual_page (EvView *view, height -= (border.top + border.bottom + 2 * view->spacing); if (view->sizing_mode == EV_SIZING_FIT_WIDTH) - scale = zoom_for_size_fit_width (doc_width, doc_height, width, height); + scale = zoom_for_size_fit_width (doc_width, doc_height, width, height, vsb_width); else if (view->sizing_mode == EV_SIZING_BEST_FIT) - scale = zoom_for_size_best_fit (doc_width, doc_height, width, height); + scale = zoom_for_size_best_fit (doc_width, doc_height, width, height, vsb_width, hsb_height); else g_assert_not_reached (); @@ -2282,7 +2324,9 @@ ev_view_zoom_for_size_dual_page (EvView *view, static void ev_view_zoom_for_size_single_page (EvView *view, int width, - int height) + int height, + int vsb_width, + int hsb_height) { int doc_width, doc_height; GtkBorder border; @@ -2300,9 +2344,9 @@ ev_view_zoom_for_size_single_page (EvView *view, height -= (border.top + border.bottom + 2 * view->spacing); if (view->sizing_mode == EV_SIZING_FIT_WIDTH) - scale = zoom_for_size_fit_width (doc_width, doc_height, width, height); + scale = zoom_for_size_fit_width (doc_width, doc_height, width, height, vsb_width); else if (view->sizing_mode == EV_SIZING_BEST_FIT) - scale = zoom_for_size_best_fit (doc_width, doc_height, width, height); + scale = zoom_for_size_best_fit (doc_width, doc_height, width, height, vsb_width, hsb_height); else g_assert_not_reached (); @@ -2312,8 +2356,10 @@ ev_view_zoom_for_size_single_page (EvView *view, void ev_view_set_zoom_for_size (EvView *view, int width, - int height) -{ + int height, + int vsb_width, + int hsb_height) +{ g_return_if_fail (view->sizing_mode == EV_SIZING_FIT_WIDTH || view->sizing_mode == EV_SIZING_BEST_FIT); g_return_if_fail (width >= 0); @@ -2325,13 +2371,13 @@ ev_view_set_zoom_for_size (EvView *view, if (view->presentation) ev_view_zoom_for_size_presentation (view, width, height); else if (view->continuous && view->dual_page) - ev_view_zoom_for_size_continuous_dual_page (view, width, height); + ev_view_zoom_for_size_continuous_and_dual_page (view, width, height, vsb_width, hsb_height); else if (view->continuous) - ev_view_zoom_for_size_continuous (view, width, height); + ev_view_zoom_for_size_continuous (view, width, height, vsb_width, hsb_height); else if (view->dual_page) - ev_view_zoom_for_size_dual_page (view, width, height); + ev_view_zoom_for_size_dual_page (view, width, height, vsb_width, hsb_height); else - ev_view_zoom_for_size_single_page (view, width, height); + ev_view_zoom_for_size_single_page (view, width, height, vsb_width, hsb_height); } /*** Status text messages ***/ diff --git a/shell/ev-view.h b/shell/ev-view.h index 126eaf9..4243761 100644 --- a/shell/ev-view.h +++ b/shell/ev-view.h @@ -86,6 +86,11 @@ void ev_view_set_zoom (EvView *view, gboolean relative); double ev_view_get_zoom (EvView *view); +void ev_view_set_zoom_for_size (EvView *view, + int width, + int height, + int vsb_width, + int hsb_height); /* Find */ gboolean ev_view_can_find_next (EvView *view); void ev_view_find_next (EvView *view); diff --git a/shell/ev-window.c b/shell/ev-window.c index 6549d3f..2a37834 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -1843,6 +1843,38 @@ ev_window_cmd_escape (GtkAction *action, EvWindow *window) } } +static void +update_view_size (EvView *view, EvWindow *window) +{ + int width, height; + GtkRequisition vsb_requisition; + GtkRequisition hsb_requisition; + int scrollbar_spacing; + + /* Calculate the width available for the */ + width = window->priv->scrolled_window->allocation.width; + height = window->priv->scrolled_window->allocation.height; + + if (gtk_scrolled_window_get_shadow_type (GTK_SCROLLED_WINDOW (window->priv->scrolled_window)) == GTK_SHADOW_IN) { + width -= 2 * window->priv->view->style->xthickness; + height -= 2 * window->priv->view->style->ythickness; + } + + gtk_widget_size_request (GTK_SCROLLED_WINDOW (window->priv->scrolled_window)->vscrollbar, + &vsb_requisition); + gtk_widget_size_request (GTK_SCROLLED_WINDOW (window->priv->scrolled_window)->hscrollbar, + &hsb_requisition); + gtk_widget_style_get (window->priv->scrolled_window, + "scrollbar_spacing", &scrollbar_spacing, + NULL); + + ev_view_set_zoom_for_size (EV_VIEW (window->priv->view), + MAX (1, width), + MAX (1, height), + vsb_requisition.width + scrollbar_spacing, + hsb_requisition.height + scrollbar_spacing); +} + static void ev_window_sizing_mode_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window) @@ -1856,18 +1888,29 @@ ev_window_sizing_mode_changed_cb (EvView *view, GParamSpec *pspec, scrolled_window = ev_window->priv->scrolled_window; + g_signal_handlers_disconnect_by_func (ev_window->priv->view, update_view_size, ev_window); + + if (sizing_mode != EV_SIZING_FREE) + update_view_size (NULL, ev_window); + switch (sizing_mode) { case EV_SIZING_BEST_FIT: g_object_set (G_OBJECT (scrolled_window), "hscrollbar-policy", GTK_POLICY_NEVER, "vscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL); + g_signal_connect (ev_window->priv->view, "zoom_invalid", + G_CALLBACK (update_view_size), + ev_window); break; case EV_SIZING_FIT_WIDTH: g_object_set (G_OBJECT (scrolled_window), "hscrollbar-policy", GTK_POLICY_NEVER, "vscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL); + g_signal_connect (ev_window->priv->view, "zoom_invalid", + G_CALLBACK (update_view_size), + ev_window); break; case EV_SIZING_FREE: g_object_set (G_OBJECT (scrolled_window), -- cgit v0.9.1