+static gdouble
+compute_scroll_increment (EvView *view,
+ GtkScrollType scroll)
+{
+ GtkWidget *widget = GTK_WIDGET (view);
+ GtkAdjustment *adjustment = view->vadjustment;
+ cairo_region_t *text_region, *region;
+ GtkAllocation allocation;
+ gint page;
+ GdkRectangle rect;
+ EvRectangle doc_rect;
+ GdkRectangle page_area;
+ GtkBorder border;
+ gdouble fraction = 1.0;
+
+ if (scroll != GTK_SCROLL_PAGE_BACKWARD && scroll != GTK_SCROLL_PAGE_FORWARD)
+ return gtk_adjustment_get_page_size (adjustment);
+
+ page = scroll == GTK_SCROLL_PAGE_BACKWARD ? view->start_page : view->end_page;
+
+ text_region = ev_page_cache_get_text_mapping (view->page_cache, page);
+ if (!text_region || cairo_region_is_empty (text_region))
+ return gtk_adjustment_get_page_size (adjustment);
+
+ gtk_widget_get_allocation (widget, &allocation);
+ ev_view_get_page_extents (view, page, &page_area, &border);
+ rect.x = page_area.x + view->scroll_x;
+ rect.y = view->scroll_y + (scroll == GTK_SCROLL_PAGE_BACKWARD ? 5 : allocation.height - 5);
+ rect.width = page_area.width;
+ rect.height = 1;
+ view_rect_to_doc_rect (view, &rect, &page_area, &doc_rect);
+
+ /* Convert the doc rectangle into a GdkRectangle */
+ rect.x = doc_rect.x1;
+ rect.y = doc_rect.y1;
+ rect.width = doc_rect.x2 - doc_rect.x1;
+ rect.height = MAX (1, doc_rect.y2 - doc_rect.y1);
+ region = cairo_region_create_rectangle (&rect);
+
+ cairo_region_intersect (region, text_region);
+ if (cairo_region_num_rectangles (region)) {
+ EvRenderContext *rc;
+ EvPage *ev_page;
+ cairo_region_t *sel_region;
+
+ cairo_region_get_rectangle (region, 0, &rect);
+ ev_page = ev_document_get_page (view->document, page);
+ rc = ev_render_context_new (ev_page, view->rotation, view->scale);
+ g_object_unref (ev_page);
+ /* Get the selection region to know the height of the line */
+ doc_rect.x1 = doc_rect.x2 = rect.x + 0.5;
+ doc_rect.y1 = doc_rect.y2 = rect.y + 0.5;
+
+ ev_document_doc_mutex_lock ();
+ sel_region = ev_selection_get_selection_region (EV_SELECTION (view->document),
+ rc, EV_SELECTION_STYLE_LINE,
+ &doc_rect);
+ ev_document_doc_mutex_unlock ();
+
+ g_object_unref (rc);
+
+ if (cairo_region_num_rectangles (sel_region) > 0) {
+ cairo_region_get_rectangle (sel_region, 0, &rect);
+ fraction = 1 - (rect.height / gtk_adjustment_get_page_size (adjustment));
+ }
+ cairo_region_destroy (sel_region);
+ }
+ cairo_region_destroy (region);
+
+ return gtk_adjustment_get_page_size (adjustment) * fraction;
+
+}
+