X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=shell%2Fev-view.c;h=5cc6f57d549ec305d375d6cffa1c23ca18196793;hb=d93ec57b2282ee22ade99eba434e1b13de80bcf3;hp=e9cbee5e180f68895b3c389619bf78901eb6d4c7;hpb=681b0a3166a61b96b9a0ee35ca1b0aaa487809b3;p=evince.git diff --git a/shell/ev-view.c b/shell/ev-view.c index e9cbee5e..5cc6f57d 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -49,6 +49,7 @@ enum { PROP_FULLSCREEN, PROP_PRESENTATION, PROP_SIZING_MODE, + PROP_ZOOM, }; enum { @@ -86,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; @@ -114,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; @@ -140,7 +141,6 @@ struct _EvView { int spacing; double scale; - GtkBorder border; gboolean continuous; gboolean dual_page; @@ -149,6 +149,7 @@ struct _EvView { EvSizingMode sizing_mode; PendingScroll pending_scroll; + gboolean pending_resize; }; struct _EvViewClass { @@ -164,13 +165,12 @@ struct _EvViewClass { }; /*** Scrolling ***/ -static void view_update_adjustments (EvView *view); +static void scroll_to_current_page (EvView *view, + GtkOrientation orientation); static void ev_view_set_scroll_adjustments (EvView *view, GtkAdjustment *hadjustment, GtkAdjustment *vadjustment); static void view_update_range_and_current_page (EvView *view); -static void view_scroll_to_page (EvView *view, - gint new_page); static void set_scroll_adjustment (EvView *view, GtkOrientation orientation, GtkAdjustment *adjustment); @@ -192,6 +192,10 @@ static void compute_border (EvView int width, int height, GtkBorder *border); +static void get_page_y_offset (EvView *view, + int page, + double zoom, + int *y_offset); static gboolean get_page_extents (EvView *view, gint page, GdkRectangle *page_area, @@ -204,9 +208,6 @@ static void doc_rect_to_view_rect (EvView int page, EvRectangle *doc_rect, GdkRectangle *view_rect); -static void get_bounding_box_size (EvView *view, - int *max_width, - int *max_height); static void find_page_at_location (EvView *view, gdouble x, gdouble y, @@ -356,33 +357,35 @@ static void ev_view_update_primary_selection (EvView G_DEFINE_TYPE (EvView, ev_view, GTK_TYPE_WIDGET) static void -view_update_adjustments (EvView *view) +scroll_to_current_page (EvView *view, GtkOrientation orientation) { - int dx = 0, dy = 0; + GdkRectangle page_area; + GtkBorder border; - if (! GTK_WIDGET_REALIZED (view)) - return; + get_page_extents (view, view->current_page, &page_area, &border); - if (view->hadjustment) { - dx = view->scroll_x - view->hadjustment->value; - view->scroll_x = view->hadjustment->value; - } else { - view->scroll_x = 0; - } - - if (view->vadjustment) { - dy = view->scroll_y - view->vadjustment->value; - view->scroll_y = view->vadjustment->value; + if (orientation == GTK_ORIENTATION_VERTICAL) { + if (view->continuous) { + gtk_adjustment_clamp_page (view->vadjustment, + page_area.y - view->spacing, + page_area.y + view->vadjustment->page_size); + } else { + gtk_adjustment_set_value (view->vadjustment, + view->vadjustment->lower); + } } else { - view->scroll_y = 0; + if (view->dual_page) { + gtk_adjustment_clamp_page (view->hadjustment, + page_area.x, + page_area.x + 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)); + } } - - // 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); } static void @@ -413,7 +416,7 @@ view_set_adjustment_values (EvView *view, factor = 1.0; switch (view->pending_scroll) { case SCROLL_TO_KEEP_POSITION: - factor = adjustment->value / adjustment->upper; + factor = (adjustment->value) / adjustment->upper; break; case SCROLL_TO_CURRENT_PAGE: break; @@ -428,19 +431,21 @@ view_set_adjustment_values (EvView *view, adjustment->lower = 0; adjustment->upper = MAX (allocation, requisition); + /* + * We add 0.5 to the values before to average out our rounding errors. + */ 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); + new_value = CLAMP (adjustment->upper * factor + 0.5, 0, adjustment->upper - adjustment->page_size); + gtk_adjustment_set_value (adjustment, (int)new_value); break; case SCROLL_TO_CURRENT_PAGE: - if (orientation == GTK_ORIENTATION_VERTICAL) { - view_scroll_to_page (view, view->current_page); - } + scroll_to_current_page (view, orientation); 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); + new_value = CLAMP (adjustment->upper * factor - adjustment->page_size * 0.5 + 0.5, + 0, adjustment->upper - adjustment->page_size); + gtk_adjustment_set_value (adjustment, (int)new_value); break; } @@ -456,31 +461,23 @@ view_update_range_and_current_page (EvView *view) view->end_page = view->current_page; } else if (view->continuous) { GdkRectangle current_area, unused, page_area; + GtkBorder border; gint current_page; gboolean found = FALSE; int i; - get_bounding_box_size (view, &(page_area.width), &(page_area.height)); - page_area.x = view->spacing; - page_area.y = view->spacing; - - if (view->hadjustment) { - current_area.x = view->hadjustment->value; - current_area.width = view->hadjustment->page_size; - } else { - current_area.x = page_area.x; - current_area.width = page_area.width; - } - - if (view->vadjustment) { - current_area.y = view->vadjustment->value; - current_area.height = view->vadjustment->page_size; - } else { - current_area.y = page_area.y; - current_area.height = page_area.height; - } + if (!(view->vadjustment && view->hadjustment)) + return; + + current_area.x = view->hadjustment->value; + current_area.width = view->hadjustment->upper; + current_area.y = view->vadjustment->value; + current_area.height = view->vadjustment->page_size; for (i = 0; i < ev_page_cache_get_n_pages (view->page_cache); i++) { + + get_page_extents (view, i, &page_area, &border); + if (gdk_rectangle_intersect (¤t_area, &page_area, &unused)) { if (! found) { view->start_page = i; @@ -491,18 +488,8 @@ view_update_range_and_current_page (EvView *view) } else if (found) { break; } - if (view->dual_page) { - if (i % 2 == 0) { - page_area.x += page_area.width + view->spacing; - } else { - page_area.x = view->spacing; - page_area.y += page_area.height + view->spacing; - } - } else { - page_area.y += page_area.height + view->spacing; - } } - + current_page = ev_page_cache_get_current_page (view->page_cache); if (current_page < view->start_page || current_page > view->end_page) { @@ -531,64 +518,6 @@ view_update_range_and_current_page (EvView *view) view->scale); } -static void -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, max_width, n_rows; - - ev_page_cache_get_size (page_cache, - view->current_page, - view->scale, - &old_width, &old_height); - - ev_page_cache_get_size (page_cache, - new_page, - view->scale, - &new_width, &new_height); - - compute_border (view, new_width, new_height, &(view->border)); - - if (new_width != old_width || new_height != old_height) - gtk_widget_queue_resize (GTK_WIDGET (view)); - else - gtk_widget_queue_draw (GTK_WIDGET (view)); - - get_bounding_box_size (view, &max_width, &max_height); - - if (view->continuous && view->vadjustment) { - - 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); - } - - if (view->dual_page && view->hadjustment) { - 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); - } - } - - view->current_page = new_page; - view_update_range_and_current_page (view); -} - static void set_scroll_adjustment (EvView *view, GtkOrientation orientation, @@ -628,7 +557,7 @@ ev_view_set_scroll_adjustments (EvView *view, set_scroll_adjustment (view, GTK_ORIENTATION_HORIZONTAL, hadjustment); set_scroll_adjustment (view, GTK_ORIENTATION_VERTICAL, vadjustment); - view_update_adjustments (view); + on_adjustment_value_changed (NULL, view); } static void @@ -785,6 +714,32 @@ compute_border (EvView *view, int width, int height, GtkBorder *border) } } +static void get_page_y_offset (EvView *view, + int page, + double zoom, + int *y_offset) +{ + int max_width, offset; + GtkBorder border; + + g_return_if_fail (y_offset != NULL); + + ev_page_cache_get_max_width (view->page_cache, zoom, &max_width); + + compute_border (view, max_width, max_width, &border); + + if (view->dual_page) { + ev_page_cache_get_height_to_page (view->page_cache, page, zoom, NULL, &offset); + offset += (page / 2 + 1) * view->spacing + (page / 2) * (border.top + border.bottom); + } else { + ev_page_cache_get_height_to_page (view->page_cache, page, zoom, &offset, NULL); + offset += (page + 1) * view->spacing + page * (border.top + border.bottom); + } + + *y_offset = offset; + return; +} + static gboolean get_page_extents (EvView *view, gint page, @@ -796,22 +751,6 @@ get_page_extents (EvView *view, widget = GTK_WIDGET (view); - /* Quick sanity check */ - if (view->presentation) { - if (view->current_page != page) - return FALSE; - } else if (view->continuous) { - if (page < view->start_page || - page > view->end_page) - return FALSE; - } else if (view->dual_page) { - if (ABS (page - view->current_page) > 1) - return FALSE; - } else { - if (view->current_page != page) - return FALSE; - } - /* Get the size of the page */ ev_page_cache_get_size (view->page_cache, page, view->scale, @@ -824,20 +763,24 @@ get_page_extents (EvView *view, page_area->x = (MAX (0, widget->allocation.width - width))/2; page_area->y = (MAX (0, widget->allocation.height - height))/2; } else if (view->continuous) { - gint max_width, max_height; + gint max_width; gint x, y; - get_bounding_box_size (view, &max_width, &max_height); + ev_page_cache_get_max_width (view->page_cache, view->scale, &max_width); + max_width = max_width + border->left + border->right; /* Get the location of the bounding box */ if (view->dual_page) { x = view->spacing + (page % 2) * (max_width + view->spacing); - y = view->spacing + (page / 2) * (max_height + view->spacing); - x = x + MAX (0, widget->allocation.width - (max_width * 2 + view->spacing * 3))/2; + x = x + MAX (0, widget->allocation.width - (max_width * 2 + view->spacing * 3)) / 2; + if (page % 2 == 0) + x = x + (max_width - width - border->left - border->right); } else { x = view->spacing; - y = view->spacing + page * (max_height + view->spacing); - x = x + MAX (0, widget->allocation.width - (max_width + view->spacing * 2))/2; + x = x + MAX (0, widget->allocation.width - (width + view->spacing * 2)) / 2; } + + get_page_y_offset (view, page, view->scale, &y); + page_area->x = x; page_area->y = y; } else { @@ -854,7 +797,7 @@ get_page_extents (EvView *view, /* First, we get the bounding box of the two pages */ if (other_page < ev_page_cache_get_n_pages (view->page_cache)) { ev_page_cache_get_size (view->page_cache, - page + 1, + other_page, view->scale, &width_2, &height_2); if (width_2 > width) @@ -885,8 +828,8 @@ get_page_extents (EvView *view, y = view->spacing; /* Adjust for extra allocation */ - x = x + MAX (0, widget->allocation.width - (width + view->spacing * 2))/2; - y = y + MAX (0, widget->allocation.height - (height + view->spacing * 2))/2; + x = x + MAX (0, widget->allocation.width - (width + border->left + border->right + view->spacing * 2))/2; + y = y + MAX (0, widget->allocation.height - (height + border->top + border->bottom + view->spacing * 2))/2; } page_area->x = x; @@ -928,30 +871,6 @@ doc_rect_to_view_rect (EvView *view, view_rect->height = ceil (height * view->scale); } -static void -get_bounding_box_size (EvView *view, int *max_width, int *max_height) -{ - GtkBorder border; - int width, height; - - if (max_width) { - ev_page_cache_get_max_width_size (view->page_cache, - view->scale, - &width, &height); - compute_border (view, width, height, &border); - *max_width = width + border.left + border.right; - } - - - if (max_height) { - ev_page_cache_get_max_height_size (view->page_cache, - view->scale, - &width, &height); - compute_border (view, width, height, &border); - *max_height = height + border.top + border.bottom; - } -} - static void find_page_at_location (EvView *view, gdouble x, @@ -1071,17 +990,19 @@ status_message_from_link (EvView *view, EvLink *link) static void ev_view_size_request_continuous_dual_page (EvView *view, - GtkRequisition *requisition) + GtkRequisition *requisition) { - int max_width, max_height; - int n_rows; + int max_width; + gint n_pages; + GtkBorder border; - get_bounding_box_size (view, &max_width, &max_height); + ev_page_cache_get_max_width (view->page_cache, view->scale, &max_width); + compute_border (view, max_width, max_width, &border); - n_rows = (1 + ev_page_cache_get_n_pages (view->page_cache)) / 2; + n_pages = ev_page_cache_get_n_pages (view->page_cache) + 1; - requisition->width = (max_width * 2) + (view->spacing * 3); - requisition->height = max_height * n_rows + (view->spacing * (n_rows + 1)); + requisition->width = (max_width + border.left + border.right) * 2 + (view->spacing * 3); + get_page_y_offset (view, n_pages, view->scale, &requisition->height); if (view->sizing_mode == EV_SIZING_FIT_WIDTH) { requisition->width = 1; @@ -1097,15 +1018,17 @@ static void ev_view_size_request_continuous (EvView *view, GtkRequisition *requisition) { - int max_width, max_height; + int max_width; int n_pages; + GtkBorder border; - get_bounding_box_size (view, &max_width, &max_height); + ev_page_cache_get_max_width (view->page_cache, view->scale, &max_width); n_pages = ev_page_cache_get_n_pages (view->page_cache); + compute_border (view, max_width, max_width, &border); - requisition->width = max_width + (view->spacing * 2); - requisition->height = max_height * n_pages + (view->spacing * (n_pages + 1)); + requisition->width = max_width + (view->spacing * 2) + border.left + border.right; + get_page_y_offset (view, n_pages, view->scale, &requisition->height); if (view->sizing_mode == EV_SIZING_FIT_WIDTH) { requisition->width = 1; @@ -1226,6 +1149,7 @@ ev_view_size_allocate (GtkWidget *widget, 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); @@ -1288,14 +1212,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; } @@ -1396,6 +1322,9 @@ ev_view_motion_notify_event (GtkWidget *widget, { EvView *view = EV_VIEW (widget); + if (!view->document) + return FALSE; + if (view->pressed_button == 1) { GdkRectangle selection; @@ -1445,7 +1374,7 @@ ev_view_motion_notify_event (GtkWidget *widget, return TRUE; } - } else if (view->pressed_button <= 0 && view->document) { + } else if (view->pressed_button <= 0) { EvLink *link; link = get_link_at_location (view, event->x + view->scroll_x, event->y + view->scroll_y); @@ -1589,14 +1518,12 @@ draw_one_page (EvView *view, GdkRectangle real_page_area; g_assert (view->document); - - if (!gdk_rectangle_intersect (page_area, expose_area, &overlap)) + if (! gdk_rectangle_intersect (page_area, expose_area, &overlap)) return; ev_page_cache_get_size (view->page_cache, page, view->scale, &width, &height); - /* Render the document itself */ real_page_area = *page_area; @@ -1605,36 +1532,37 @@ draw_one_page (EvView *view, real_page_area.width -= (border->left + border->right); real_page_area.height -= (border->top + border->bottom); - if (! gdk_rectangle_intersect (&real_page_area, expose_area, &overlap)) - return; - ev_document_misc_paint_one_page (GTK_WIDGET(view)->window, GTK_WIDGET (view), page_area, border); - current_pixbuf = ev_pixbuf_cache_get_pixbuf (view->pixbuf_cache, page); + if (gdk_rectangle_intersect (&real_page_area, expose_area, &overlap)) { + current_pixbuf = ev_pixbuf_cache_get_pixbuf (view->pixbuf_cache, page); - if (current_pixbuf == NULL) - scaled_image = NULL; - else if (width == gdk_pixbuf_get_width (current_pixbuf) && - height == gdk_pixbuf_get_height (current_pixbuf)) - scaled_image = g_object_ref (current_pixbuf); - else - scaled_image = gdk_pixbuf_scale_simple (current_pixbuf, - width, height, - GDK_INTERP_NEAREST); - - if (scaled_image) { - gdk_draw_pixbuf (GTK_WIDGET(view)->window, - GTK_WIDGET (view)->style->fg_gc[GTK_STATE_NORMAL], - scaled_image, - overlap.x - real_page_area.x, - overlap.y - real_page_area.y, - overlap.x, overlap.y, - overlap.width, overlap.height, - GDK_RGB_DITHER_NORMAL, - 0, 0); - g_object_unref (scaled_image); + if (current_pixbuf == NULL) + scaled_image = NULL; + else if (width == gdk_pixbuf_get_width (current_pixbuf) && + 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); + + if (scaled_image) { + gdk_draw_pixbuf (GTK_WIDGET(view)->window, + GTK_WIDGET (view)->style->fg_gc[GTK_STATE_NORMAL], + scaled_image, + overlap.x - real_page_area.x, + overlap.y - real_page_area.y, + overlap.x, overlap.y, + overlap.width, overlap.height, + GDK_RGB_DITHER_NORMAL, + 0, 0); + g_object_unref (scaled_image); + } } } @@ -1698,6 +1626,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); } @@ -1734,6 +1665,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); } @@ -1849,6 +1783,16 @@ 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); @@ -1862,7 +1806,7 @@ ev_view_init (EvView *view) { GTK_WIDGET_SET_FLAGS (view, GTK_CAN_FOCUS); - view->spacing = 10; + view->spacing = 5; view->scale = 1.0; view->current_page = 0; view->pressed_button = -1; @@ -1903,14 +1847,10 @@ page_changed_cb (EvPageCache *page_cache, EvView *view) { if (view->current_page != 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; - } + + view->current_page = new_page; + view->pending_scroll = SCROLL_TO_CURRENT_PAGE; + gtk_widget_queue_resize (GTK_WIDGET (view)); if (EV_IS_DOCUMENT_FIND (view->document)) { view->find_page = new_page; @@ -1923,8 +1863,34 @@ page_changed_cb (EvPageCache *page_cache, static void on_adjustment_value_changed (GtkAdjustment *adjustment, EvView *view) { - view_update_adjustments (view); -} + 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) { + dy = view->scroll_y - (int) view->vadjustment->value; + view->scroll_y = (int) view->vadjustment->value; + } else { + view->scroll_y = 0; + } + + + 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);} GtkWidget* ev_view_new (void) @@ -1936,6 +1902,28 @@ ev_view_new (void) return view; } +static void +setup_caches (EvView *view) +{ + view->page_cache = ev_page_cache_get (view->document); + g_signal_connect (view->page_cache, "page-changed", G_CALLBACK (page_changed_cb), view); + view->pixbuf_cache = ev_pixbuf_cache_new (view->document); + g_signal_connect (view->pixbuf_cache, "job-finished", G_CALLBACK (job_finished_cb), view); +} + +static void +clear_caches (EvView *view) +{ + if (view->pixbuf_cache) { + g_object_unref (view->pixbuf_cache); + view->pixbuf_cache = NULL; + } + + if (view->document) { + ev_page_cache_clear (view->document); + } +} + void ev_view_set_document (EvView *view, EvDocument *document) @@ -1943,6 +1931,8 @@ ev_view_set_document (EvView *view, g_return_if_fail (EV_IS_VIEW (view)); if (document != view->document) { + clear_caches (view); + if (view->document) { g_signal_handlers_disconnect_by_func (view->document, find_changed_cb, @@ -1964,11 +1954,8 @@ ev_view_set_document (EvView *view, G_CALLBACK (find_changed_cb), view); } - view->page_cache = ev_document_get_page_cache (view->document); - view->pending_scroll = SCROLL_TO_CURRENT_PAGE; - g_signal_connect (view->page_cache, "page-changed", G_CALLBACK (page_changed_cb), view); - view->pixbuf_cache = ev_pixbuf_cache_new (view->document); - g_signal_connect (view->pixbuf_cache, "job-finished", G_CALLBACK (job_finished_cb), view); + + setup_caches (view); } gtk_widget_queue_resize (GTK_WIDGET (view)); @@ -1994,9 +1981,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 @@ -2154,6 +2145,54 @@ ev_view_zoom_out (EvView *view) ev_view_set_zoom (view, ZOOM_OUT_FACTOR, TRUE); } +static void +ev_view_set_orientation (EvView *view, + EvOrientation orientation) +{ + ev_document_set_orientation (view->document, orientation); + + clear_caches (view); + setup_caches (view); + + gtk_widget_queue_resize (GTK_WIDGET (view)); +} + +void +ev_view_rotate_right (EvView *view) +{ + EvOrientation orientation, new_orientation; + + orientation = ev_document_get_orientation (view->document); + if (orientation == EV_ORIENTATION_PORTRAIT) { + new_orientation = EV_ORIENTATION_LANDSCAPE; + } else if (orientation == EV_ORIENTATION_LANDSCAPE) { + new_orientation = EV_ORIENTATION_UPSIDEDOWN; + } else if (orientation == EV_ORIENTATION_UPSIDEDOWN) { + new_orientation = EV_ORIENTATION_SEASCAPE; + } else { + new_orientation = EV_ORIENTATION_PORTRAIT; + } + ev_view_set_orientation (view, new_orientation); +} + +void +ev_view_rotate_left (EvView *view) +{ + EvOrientation orientation, new_orientation; + + orientation = ev_document_get_orientation (view->document); + if (orientation == EV_ORIENTATION_PORTRAIT) { + new_orientation = EV_ORIENTATION_SEASCAPE; + } else if (orientation == EV_ORIENTATION_SEASCAPE) { + new_orientation = EV_ORIENTATION_UPSIDEDOWN; + } else if (orientation == EV_ORIENTATION_UPSIDEDOWN) { + new_orientation = EV_ORIENTATION_LANDSCAPE; + } else { + new_orientation = EV_ORIENTATION_PORTRAIT; + } + ev_view_set_orientation (view, new_orientation); +} + static double zoom_for_size_fit_width (int doc_width, int doc_height, @@ -2222,12 +2261,12 @@ ev_view_zoom_for_size_continuous_and_dual_page (EvView *view, GtkBorder border; gdouble scale; - ev_page_cache_get_max_width_size (view->page_cache, - 1.0, - &doc_width, NULL); - ev_page_cache_get_max_height_size (view->page_cache, - 1.0, - NULL, &doc_height); + ev_page_cache_get_max_width (view->page_cache, + 1.0, + &doc_width); + ev_page_cache_get_max_height (view->page_cache, + 1.0, + &doc_height); compute_border (view, doc_width, doc_height, &border); doc_width = doc_width * 2; @@ -2258,12 +2297,12 @@ ev_view_zoom_for_size_continuous (EvView *view, GtkBorder border; gdouble scale; - ev_page_cache_get_max_width_size (view->page_cache, - 1.0, - &doc_width, NULL); - ev_page_cache_get_max_height_size (view->page_cache, - 1.0, - NULL, &doc_height); + ev_page_cache_get_max_width (view->page_cache, + 1.0, + &doc_width); + ev_page_cache_get_max_height (view->page_cache, + 1.0, + &doc_height); compute_border (view, doc_width, doc_height, &border); width -= (border.left + border.right + 2 * view->spacing); @@ -2431,10 +2470,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 { @@ -2475,15 +2512,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); @@ -2527,9 +2560,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; @@ -2542,10 +2573,8 @@ ev_view_find_next (EvView *view) int n_results, n_pages; EvDocumentFind *find = EV_DOCUMENT_FIND (view->document); - page_cache = ev_document_get_page_cache (view->document); - ev_document_doc_mutex_lock (); + page_cache = ev_page_cache_get (view->document); 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); @@ -2573,11 +2602,9 @@ ev_view_find_previous (EvView *view) EvDocumentFind *find = EV_DOCUMENT_FIND (view->document); EvPageCache *page_cache; - page_cache = ev_document_get_page_cache (view->document); + page_cache = ev_page_cache_get (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);