X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=libview%2Fev-view.c;h=6417a43c6f949032c9c3e0bc64f4adc812a843e4;hb=43f607bda8eef3648f018e433647172603ea1a7f;hp=ea26824ac1b179bb59823e9995f9d3673410f3b7;hpb=899acae2d641802bb46d7aaf850a224614866f08;p=evince.git diff --git a/libview/ev-view.c b/libview/ev-view.c index ea26824a..6417a43c 100644 --- a/libview/ev-view.c +++ b/libview/ev-view.c @@ -609,8 +609,6 @@ view_set_adjustment_values (EvView *view, static void view_update_range_and_current_page (EvView *view) { - gint current_page; - gint best_current_page = -1; gint start = view->start_page; gint end = view->end_page; @@ -623,6 +621,7 @@ view_update_range_and_current_page (EvView *view) GtkBorder border; gboolean found = FALSE; gint area_max = -1, area; + gint best_current_page = -1; int i; if (!(view->vadjustment && view->hadjustment)) @@ -657,12 +656,20 @@ view_update_range_and_current_page (EvView *view) } } + if (view->pending_scroll == SCROLL_TO_KEEP_POSITION) { + best_current_page = MAX (best_current_page, view->start_page); + + if (view->current_page != best_current_page) { + view->current_page = best_current_page; + ev_document_model_set_page (view->model, best_current_page); + } + } } else if (view->dual_page) { if (view->current_page % 2 == get_dual_even_left (view)) { view->start_page = view->current_page; if (view->current_page + 1 < ev_document_get_n_pages (view->document)) view->end_page = view->start_page + 1; - else + else view->end_page = view->start_page; } else { if (view->current_page < 1) @@ -676,14 +683,6 @@ view_update_range_and_current_page (EvView *view) view->end_page = view->current_page; } - best_current_page = MAX (best_current_page, view->start_page); - current_page = ev_document_model_get_page (view->model); - - if ((current_page != best_current_page) && (view->pending_scroll == SCROLL_TO_KEEP_POSITION)) { - view->current_page = best_current_page; - ev_document_model_set_page (view->model, best_current_page); - } - if (start != view->start_page || end != view->end_page) { gint i; @@ -702,6 +701,9 @@ view_update_range_and_current_page (EvView *view) view->rotation, view->scale, view->selection_info.selections); + + if (ev_pixbuf_cache_get_surface (view->pixbuf_cache, view->current_page)) + gtk_widget_queue_draw (GTK_WIDGET (view)); } static void @@ -767,6 +769,79 @@ add_scroll_binding_keypad (GtkBindingSet *binding_set, G_TYPE_BOOLEAN, horizontal); } +static gdouble +compute_scroll_increment (EvView *view, + GtkScrollType scroll) +{ + GtkWidget *widget = GTK_WIDGET (view); + GtkAdjustment *adjustment = view->vadjustment; + GdkRegion *text_region, *region; + gint page; + GdkRectangle rect; + EvRectangle doc_rect; + GdkRectangle page_area; + GtkBorder border; + GdkRectangle *recs; + gint n_recs; + gdouble fraction = 1.0; + + if (scroll != GTK_SCROLL_PAGE_BACKWARD && scroll != GTK_SCROLL_PAGE_FORWARD) + return adjustment->page_size; + + page = scroll == GTK_SCROLL_PAGE_BACKWARD ? view->start_page : view->end_page; + + text_region = ev_pixbuf_cache_get_text_mapping (view->pixbuf_cache, page); + if (!text_region || gdk_region_empty (text_region)) + return adjustment->page_size; + + 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 : widget->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 = gdk_region_rectangle (&rect); + + gdk_region_intersect (region, text_region); + gdk_region_get_rectangles (region, &recs, &n_recs); + gdk_region_destroy (region); + if (n_recs > 0) { + EvRenderContext *rc; + EvPage *ev_page; + + 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 = recs[0].x + 0.5; + doc_rect.y1 = doc_rect.y2 = recs[0].y + 0.5; + + ev_document_doc_mutex_lock (); + 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); + g_free (recs); + gdk_region_get_rectangles (region, &recs, &n_recs); + gdk_region_destroy (region); + if (n_recs > 0) { + fraction = 1 - (recs[0].height / adjustment->page_size); + } + g_free (recs); + } + + return adjustment->page_size * fraction; + +} + void ev_view_scroll (EvView *view, GtkScrollType scroll, @@ -797,7 +872,6 @@ ev_view_scroll (EvView *view, /* Assign values for increment and vertical adjustment */ adjustment = horizontal ? view->hadjustment : view->vadjustment; - increment = adjustment->page_size * 0.75; value = adjustment->value; /* Assign boolean for first and last page */ @@ -817,6 +891,7 @@ ev_view_scroll (EvView *view, ev_view_previous_page (view); /* Jump to the top */ } else { + increment = compute_scroll_increment (view, GTK_SCROLL_PAGE_BACKWARD); value = MAX (value - increment, adjustment->lower); } break; @@ -830,6 +905,7 @@ ev_view_scroll (EvView *view, ev_view_next_page (view); /* Jump to the bottom */ } else { + increment = compute_scroll_increment (view, GTK_SCROLL_PAGE_FORWARD); value = MIN (value + increment, adjustment->upper - adjustment->page_size); } break;