]> www.fi.muni.cz Git - evince.git/blobdiff - shell/ev-view.c
Fix minor points related to moving best fit up. Introduce
[evince.git] / shell / ev-view.c
index 3e28b0c58f690e9db8088f51f00b27c4e7d77d85..9f66d8acba3b8ff9219ff7934072a454169899f9 100644 (file)
@@ -49,6 +49,13 @@ enum {
        PROP_FULLSCREEN,
        PROP_PRESENTATION,
        PROP_SIZING_MODE,
+       PROP_ZOOM,
+};
+
+enum {
+       SIGNAL_SCROLL_VIEW,
+       SIGNAL_ZOOM_INVALID,
+       N_SIGNALS,
 };
 
 enum {
@@ -66,6 +73,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,
@@ -78,7 +87,7 @@ typedef enum {
 #define ZOOM_OUT_FACTOR (1.0/ZOOM_IN_FACTOR)
 
 #define MIN_SCALE 0.05409
-#define MAX_SCALE 6.0
+#define MAX_SCALE 4.0
 
 typedef struct {
        EvRectangle rect;
@@ -106,8 +115,8 @@ struct _EvView {
        char *status;
        char *find_status;
 
-       int scroll_x;
-       int scroll_y;
+       gint scroll_x;
+       gint scroll_y;
 
        DragInfo drag_info;
        gboolean pressed_button;
@@ -141,6 +150,7 @@ struct _EvView {
        EvSizingMode sizing_mode;
        
        PendingScroll pending_scroll;
+       gboolean pending_resize;
 };
 
 struct _EvViewClass {
@@ -152,6 +162,7 @@ struct _EvViewClass {
        void    (*scroll_view)            (EvView         *view,
                                           GtkScrollType   scroll,
                                           gboolean        horizontal);
+       void    (*zoom_invalid)           (EvView         *view);
 };
 
 /*** Scrolling ***/
@@ -281,33 +292,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 +360,31 @@ G_DEFINE_TYPE (EvView, ev_view, GTK_TYPE_WIDGET)
 static void
 view_update_adjustments (EvView *view)
 {
-       if (view->hadjustment)
-               view->scroll_x = view->hadjustment->value;
-       else
+       int dx = 0, dy = 0;
+
+       if (! GTK_WIDGET_REALIZED (view))
+               return;
+
+       if (view->hadjustment) {
+               dx = view->scroll_x - (int) view->hadjustment->value;
+               view->scroll_x = (int) view->hadjustment->value;
+       } else {
                view->scroll_x = 0;
+       }
 
-       if (view->vadjustment)
-               view->scroll_y = view->vadjustment->value;
-       else
+       if (view->vadjustment) {
+               dy = view->scroll_y - (int) view->vadjustment->value;
+               view->scroll_y = (int) view->vadjustment->value;
+       } else {
                view->scroll_y = 0;
-               
-       gtk_widget_queue_draw (GTK_WIDGET (view));
+       }
+       
+       
+       if (view->pending_resize)       
+               gtk_widget_queue_draw (GTK_WIDGET (view));
+       else
+               gdk_window_scroll (GTK_WIDGET (view)->window, dx, dy);
+
 
        if (view->document)
                view_update_range_and_current_page (view);
@@ -404,7 +436,7 @@ view_set_adjustment_values (EvView         *view,
        switch (view->pending_scroll) {
                case SCROLL_TO_KEEP_POSITION: 
                        new_value = CLAMP (adjustment->upper * factor, 0, adjustment->upper - adjustment->page_size);
-                       gtk_adjustment_set_value (adjustment, new_value);
+                       gtk_adjustment_set_value (adjustment, (int)new_value);
                        break;
                case SCROLL_TO_CURRENT_PAGE: 
                        if (orientation == GTK_ORIENTATION_VERTICAL) {
@@ -413,7 +445,7 @@ view_set_adjustment_values (EvView         *view,
                        break;
                case SCROLL_TO_CENTER: 
                        new_value = CLAMP (adjustment->upper * factor - adjustment->page_size * 0.5, 0, adjustment->upper - adjustment->page_size);
-                       gtk_adjustment_set_value (adjustment, new_value);
+                       gtk_adjustment_set_value (adjustment, (int)new_value);
                        break;
        }
 
@@ -510,7 +542,7 @@ view_scroll_to_page (EvView *view, gint new_page)
        EvPageCache *page_cache = view->page_cache;
        int old_width, old_height;
        int new_width, new_height;
-       int max_height, n_rows;
+       int max_height, max_width, n_rows;
 
        ev_page_cache_get_size (page_cache,
                                view->current_page,
@@ -529,19 +561,43 @@ view_scroll_to_page (EvView *view, gint new_page)
        else
                gtk_widget_queue_draw (GTK_WIDGET (view));
        
-       if (view->continuous) {
-               
-               n_rows = view->dual_page ? new_page / 2 : new_page;
+       get_bounding_box_size (view, &max_width, &max_height);
+       
+       if (view->vadjustment) {
+               if (view->continuous) {
                
-               get_bounding_box_size (view, NULL, &max_height);
+                       n_rows = view->dual_page ? new_page / 2 : new_page;
 
-               gtk_adjustment_clamp_page(view->vadjustment,
-                                         (max_height + view->spacing) * n_rows, 
-                                         (max_height + view->spacing) * n_rows +
-                                          view->vadjustment->page_size);
-       } else {
-               gtk_adjustment_set_value (view->vadjustment,
-                                         view->vadjustment->lower);
+                       gtk_adjustment_clamp_page(view->vadjustment,
+                                                 (max_height + view->spacing) * n_rows, 
+                                                 (max_height + view->spacing) * n_rows +
+                                                  view->vadjustment->page_size);
+               } else {
+                       gtk_adjustment_set_value (view->vadjustment,
+                                                 view->vadjustment->lower);
+               }
+       }
+       
+       if (view->hadjustment) {
+               if (view->dual_page) {
+                       if (new_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);
+                       }
+               } else {
+                               gtk_adjustment_set_value (view->hadjustment,
+                                                         CLAMP (view->hadjustment->value, 
+                                                         view->hadjustment->lower,
+                                                         view->hadjustment->upper - 
+                                                         view->hadjustment->page_size));
+               }
        }
 
        view->current_page = new_page;
@@ -667,38 +723,32 @@ ev_view_scroll_view (EvView *view,
                     GtkScrollType scroll,
                     gboolean horizontal)
 {
-       if (scroll == GTK_SCROLL_PAGE_BACKWARD) {
-               ev_page_cache_prev_page (view->page_cache);
-       } else if (scroll == GTK_SCROLL_PAGE_FORWARD) {
-               ev_page_cache_next_page (view->page_cache);
-       } else {
-               GtkAdjustment *adjustment;
-               double value;
+       GtkAdjustment *adjustment;
+       double value;
 
-               if (horizontal) {
-                       adjustment = view->hadjustment;
-               } else {
-                       adjustment = view->vadjustment;
-               }
+       if (horizontal) {
+               adjustment = view->hadjustment;
+       } else {
+               adjustment = view->vadjustment;
+       }
 
-               value = adjustment->value;
+       value = adjustment->value;
 
-               switch (scroll) {
-                       case GTK_SCROLL_STEP_BACKWARD:
-                               value -= adjustment->step_increment;
-                               break;
-                       case GTK_SCROLL_STEP_FORWARD:
-                               value += adjustment->step_increment;
-                               break;
-                       default:
-                               break;
-               }
+       switch (scroll) {
+               case GTK_SCROLL_STEP_BACKWARD:
+                       value -= adjustment->step_increment;
+                       break;
+               case GTK_SCROLL_STEP_FORWARD:
+                       value += adjustment->step_increment;
+                       break;
+               default:
+                       break;
+       }
 
-               value = CLAMP (value, adjustment->lower,
-                              adjustment->upper - adjustment->page_size);
+       value = CLAMP (value, adjustment->lower,
+                      adjustment->upper - adjustment->page_size);
 
-               gtk_adjustment_set_value (adjustment, value);
-       }
+       gtk_adjustment_set_value (adjustment, value);
 }
 
 #define MARGIN 5
@@ -1151,9 +1201,6 @@ ev_view_size_request (GtkWidget      *widget,
 {
        EvView *view = EV_VIEW (widget);
 
-       if (!GTK_WIDGET_REALIZED (widget))
-               return;
-
        if (view->document == NULL) {
                requisition->width = 1;
                requisition->height = 1;
@@ -1184,16 +1231,17 @@ 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);
 
        view->pending_scroll = SCROLL_TO_KEEP_POSITION;
+       view->pending_resize = FALSE;
 
        if (view->document)
                view_update_range_and_current_page (view);              
@@ -1239,15 +1287,6 @@ ev_view_realize (GtkWidget *widget)
                gdk_window_set_background (widget->window, &widget->style->black);
        else
                gdk_window_set_background (widget->window, &widget->style->mid [GTK_STATE_NORMAL]);
-
-       if (view->document) {
-               /* We can't get page size without a target, so we have to
-                * queue a size request at realization. Could be fixed
-                * with EvDocument changes to allow setting a GdkScreen
-                * without setting a target.
-                */
-               gtk_widget_queue_resize (widget);
-       }
 }
 
 static void
@@ -1265,14 +1304,16 @@ ev_view_scroll_event (GtkWidget *widget, GdkEventScroll *event)
 
                 ev_view_set_sizing_mode (view, EV_SIZING_FREE);         
 
-                if ((event->direction == GDK_SCROLL_UP || 
-                       event->direction == GDK_SCROLL_LEFT) &&
-                       ev_view_can_zoom_in (view)) {
-                               ev_view_zoom_in (view);
-                } else if (ev_view_can_zoom_out (view)) {
-                               ev_view_zoom_out (view);
-                }               
-
+                if (event->direction == GDK_SCROLL_UP || 
+                       event->direction == GDK_SCROLL_LEFT) {
+                           if (ev_view_can_zoom_in (view)) {
+                                   ev_view_zoom_in (view);
+                           }
+                } else {
+                           if (ev_view_can_zoom_out (view)) {
+                                   ev_view_zoom_out (view);
+                           }   
+                }
                 return TRUE;
        }
        
@@ -1567,9 +1608,6 @@ draw_one_page (EvView       *view,
 
        g_assert (view->document);
 
-       if (!gdk_rectangle_intersect (page_area, expose_area, &overlap))
-               return;
-
        ev_page_cache_get_size (view->page_cache,
                                page, view->scale,
                                &width, &height);
@@ -1597,6 +1635,8 @@ draw_one_page (EvView       *view,
                 height == gdk_pixbuf_get_height (current_pixbuf))
                scaled_image = g_object_ref (current_pixbuf);
        else
+               /* FIXME: We don't want to scale the whole area, just the right
+                * area of it */
                scaled_image = gdk_pixbuf_scale_simple (current_pixbuf,
                                                        width, height,
                                                        GDK_INTERP_NEAREST);
@@ -1675,6 +1715,9 @@ ev_view_set_property (GObject      *object,
        case PROP_SIZING_MODE:
                ev_view_set_sizing_mode (view, g_value_get_enum (value));
                break;
+       case PROP_ZOOM:
+               ev_view_set_zoom (view, g_value_get_double (value), FALSE);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
        }
@@ -1711,6 +1754,9 @@ ev_view_get_property (GObject *object,
        case PROP_SIZING_MODE:
                g_value_set_enum (value, view->sizing_mode);
                break;
+       case PROP_ZOOM:
+               g_value_set_double (value, view->scale);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
        }
@@ -1753,7 +1799,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),
@@ -1763,6 +1809,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",
@@ -1818,15 +1872,22 @@ ev_view_class_init (EvViewClass *class)
                                                            EV_SIZING_FIT_WIDTH,
                                                            G_PARAM_READWRITE));
 
+       g_object_class_install_property (object_class,
+                                        PROP_ZOOM,
+                                        g_param_spec_double ("zoom",
+                                                             "Zoom factor",
+                                                              "Zoom factor",
+                                                              MIN_SCALE, 
+                                                              MAX_SCALE,
+                                                              1.0,
+                                                              G_PARAM_READWRITE));
+
        binding_set = gtk_binding_set_by_class (class);
 
        add_scroll_binding_keypad (binding_set, GDK_Left,  GTK_SCROLL_STEP_BACKWARD, TRUE);
        add_scroll_binding_keypad (binding_set, GDK_Right, GTK_SCROLL_STEP_FORWARD,  TRUE);
        add_scroll_binding_keypad (binding_set, GDK_Up,    GTK_SCROLL_STEP_BACKWARD, FALSE);
        add_scroll_binding_keypad (binding_set, GDK_Down,  GTK_SCROLL_STEP_FORWARD,  FALSE);
-
-       add_scroll_binding_keypad (binding_set, GDK_Page_Up,   GTK_SCROLL_PAGE_BACKWARD, FALSE);
-       add_scroll_binding_keypad (binding_set, GDK_Page_Down, GTK_SCROLL_PAGE_FORWARD,  FALSE);
 }
 
 static void
@@ -1876,7 +1937,13 @@ page_changed_cb (EvPageCache *page_cache,
 {
        if (view->current_page != new_page) {
 
-               view_scroll_to_page (view, new_page);
+               if (view->pending_scroll != SCROLL_TO_CURRENT_PAGE) {
+                       /* Should scroll right now */
+                       view_scroll_to_page (view, new_page);
+               } else {        
+                       /* We'll scroll to new page on allocate */
+                       view->current_page = new_page;
+               }
 
                if (EV_IS_DOCUMENT_FIND (view->document)) {
                        view->find_page = new_page;
@@ -1960,9 +2027,13 @@ ev_view_set_zoom (EvView   *view,
 
        if (ABS (view->scale - scale) < EPSILON)
                return;
-       view->scale = scale;
 
+       view->scale = scale;
+       view->pending_resize = TRUE;
+       
        gtk_widget_queue_resize (GTK_WIDGET (view));
+
+       g_object_notify (G_OBJECT (view), "zoom");
 }
 
 double
@@ -2120,20 +2191,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;
 }
@@ -2142,7 +2212,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;
@@ -2151,9 +2223,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);
 }
@@ -2172,14 +2244,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;
@@ -2201,9 +2275,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, widthheight);
+               scale = zoom_for_size_best_fit (doc_width, doc_height, width - vsb_width, height, 0, hsb_height);
        else
                g_assert_not_reached ();
 
@@ -2213,7 +2287,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;
@@ -2234,9 +2310,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, widthheight);
+               scale = zoom_for_size_best_fit (doc_width, doc_height, width - vsb_width, height, 0, hsb_height);
        else
                g_assert_not_reached ();
 
@@ -2246,7 +2322,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;
@@ -2279,9 +2357,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 ();
 
@@ -2291,7 +2369,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;
@@ -2309,9 +2389,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 ();
 
@@ -2321,8 +2401,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);
@@ -2334,13 +2416,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 ***/
@@ -2386,10 +2468,8 @@ update_find_status_message (EvView *view)
        } else {
                double percent;
 
-               ev_document_doc_mutex_lock ();
                percent = ev_document_find_get_progress
                                (EV_DOCUMENT_FIND (view->document));
-               ev_document_doc_mutex_unlock ();
                if (percent >= (1.0 - 1e-10)) {
                        message = g_strdup (_("Not found"));
                } else {
@@ -2430,15 +2510,11 @@ jump_to_find_result (EvView *view)
        int n_results;
        int page = view->find_page;
 
-       ev_document_doc_mutex_lock ();
        n_results = ev_document_find_get_n_results (find, page);
-       ev_document_doc_mutex_unlock ();
 
        if (n_results > view->find_result) {
-               ev_document_doc_mutex_lock ();
                ev_document_find_get_result
                        (find, page, view->find_result, &rect);
-               ev_document_doc_mutex_unlock ();
 
                doc_rect_to_view_rect (view, page, &rect, &view_rect);
                ensure_rectangle_is_visible (view, &view_rect);
@@ -2482,9 +2558,7 @@ ev_view_can_find_next (EvView *view)
        if (EV_IS_DOCUMENT_FIND (view->document)) {
                EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
 
-               ev_document_doc_mutex_lock ();
                n_results = ev_document_find_get_n_results (find, view->current_page);
-               ev_document_doc_mutex_unlock ();
        }
 
        return n_results > 0;
@@ -2498,9 +2572,7 @@ ev_view_find_next (EvView *view)
        EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
 
        page_cache = ev_document_get_page_cache (view->document);
-       ev_document_doc_mutex_lock ();
        n_results = ev_document_find_get_n_results (find, view->current_page);
-       ev_document_doc_mutex_unlock ();
 
        n_pages = ev_page_cache_get_n_pages (page_cache);
 
@@ -2530,9 +2602,7 @@ ev_view_find_previous (EvView *view)
 
        page_cache = ev_document_get_page_cache (view->document);
 
-       ev_document_doc_mutex_lock ();
        n_results = ev_document_find_get_n_results (find, view->current_page);
-       ev_document_doc_mutex_unlock ();
 
        n_pages = ev_page_cache_get_n_pages (page_cache);