X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=libview%2Fev-view-presentation.c;h=05f879923748b74165505647a21f2ec0f747f304;hb=83ee6052d7eeb4cfa100f4533d6259573d65efe9;hp=8f91869745facbb9f16f69c7834670cac176bec3;hpb=6d690c345c434c074333fa0971af0406eeb2719e;p=evince.git diff --git a/libview/ev-view-presentation.c b/libview/ev-view-presentation.c index 8f918697..05f87992 100644 --- a/libview/ev-view-presentation.c +++ b/libview/ev-view-presentation.c @@ -41,6 +41,7 @@ enum { enum { CHANGE_PAGE, + FINISHED, N_SIGNALS }; @@ -56,6 +57,7 @@ struct _EvViewPresentation GtkWidget base; guint current_page; + cairo_surface_t *current_surface; EvDocument *document; guint rotation; EvPresentationState state; @@ -91,6 +93,7 @@ struct _EvViewPresentationClass /* signals */ void (* change_page) (EvViewPresentation *pview, GtkScrollType scroll); + void (* finished) (EvViewPresentation *pview); }; static guint signals[N_SIGNALS] = { 0 }; @@ -184,27 +187,25 @@ ev_view_presentation_get_page_area (EvViewPresentation *pview, GdkRectangle *area) { GtkWidget *widget = GTK_WIDGET (pview); - gdouble width, height; + gdouble doc_width, doc_height; + gint view_width, view_height; ev_document_get_page_size (pview->document, pview->current_page, - &width, &height); + &doc_width, &doc_height); if (pview->rotation == 90 || pview->rotation == 270) { - gdouble tmp; - - tmp = width; - width = height; - height = tmp; + view_width = (gint)((doc_height * pview->scale) + 0.5); + view_height = (gint)((doc_width * pview->scale) + 0.5); + } else { + view_width = (gint)((doc_width * pview->scale) + 0.5); + view_height = (gint)((doc_height * pview->scale) + 0.5); } - width *= pview->scale; - height *= pview->scale; - - area->x = (MAX (0, widget->allocation.width - width)) / 2; - area->y = (MAX (0, widget->allocation.height - height)) / 2; - area->width = width; - area->height = height; + area->x = (MAX (0, widget->allocation.width - view_width)) / 2; + area->y = (MAX (0, widget->allocation.height - view_height)) / 2; + area->width = view_width; + area->height = view_height; } /* Page Transition */ @@ -236,7 +237,7 @@ ev_view_presentation_transition_start (EvViewPresentation *pview) duration = ev_document_transition_get_page_duration (EV_DOCUMENT_TRANSITION (pview->document), pview->current_page); - if (duration > 0) { + if (duration >= 0) { pview->trans_timeout_id = g_timeout_add_seconds (duration, (GSourceFunc) transition_next_page, @@ -291,7 +292,9 @@ ev_view_presentation_animation_start (EvViewPresentation *pview, pview->animation = ev_transition_animation_new (effect); surface = EV_JOB_RENDER (pview->curr_job)->surface; - ev_transition_animation_set_origin_surface (pview->animation, surface); + ev_transition_animation_set_origin_surface (pview->animation, + surface != NULL ? + surface : pview->current_surface); jump = new_page - pview->current_page; if (jump == -1) @@ -877,6 +880,19 @@ ev_view_presentation_hide_cursor_timeout_start (EvViewPresentation *pview) pview); } +static void +ev_view_presentation_update_current_surface (EvViewPresentation *pview, + cairo_surface_t *surface) +{ + if (!surface || pview->current_surface == surface) + return; + + cairo_surface_reference (surface); + if (pview->current_surface) + cairo_surface_destroy (pview->current_surface); + pview->current_surface = surface; +} + static void ev_view_presentation_destroy (GtkObject *object) { @@ -906,6 +922,11 @@ ev_view_presentation_destroy (GtkObject *object) pview->next_job = NULL; } + if (pview->current_surface) { + cairo_surface_destroy (pview->current_surface); + pview->current_surface = NULL; + } + if (pview->page_cache) { g_object_unref (pview->page_cache); pview->page_cache = NULL; @@ -955,7 +976,7 @@ ev_view_presentation_draw_end_page (EvViewPresentation *pview) PangoFontDescription *font_desc; gchar *markup; GdkRectangle area = {0}; - const gchar *text = _("End of presentation. Press Escape to exit."); + const gchar *text = _("End of presentation. Click to exit."); if (pview->state != EV_PRESENTATION_END) return; @@ -1018,6 +1039,9 @@ ev_view_presentation_expose_event (GtkWidget *widget, cairo_translate (cr, page_area.x, page_area.y); page_area.x = page_area.y = 0; + /* Try to fix rounding errors */ + page_area.width--; + ev_transition_animation_paint (pview->animation, cr, page_area); cairo_destroy (cr); } @@ -1026,19 +1050,25 @@ ev_view_presentation_expose_event (GtkWidget *widget, } surface = pview->curr_job ? EV_JOB_RENDER (pview->curr_job)->surface : NULL; - if (!surface) + if (surface) { + ev_view_presentation_update_current_surface (pview, surface); + } else if (pview->current_surface) { + surface = pview->current_surface; + } else { return FALSE; + } ev_view_presentation_get_page_area (pview, &page_area); if (gdk_rectangle_intersect (&page_area, &(event->area), &overlap)) { cr = gdk_cairo_create (widget->window); - cairo_translate (cr, overlap.x, overlap.y); - cairo_surface_set_device_offset (surface, - overlap.x - page_area.x, - overlap.y - page_area.y); - cairo_set_source_surface (cr, surface, 0, 0); - cairo_paint (cr); + /* Try to fix rounding errors. See bug #438760 */ + if (overlap.width == page_area.width) + overlap.width--; + + cairo_rectangle (cr, overlap.x, overlap.y, overlap.width, overlap.height); + cairo_set_source_surface (cr, surface, page_area.x, page_area.y); + cairo_fill (cr); cairo_destroy (cr); } @@ -1073,6 +1103,22 @@ ev_view_presentation_key_press_event (GtkWidget *widget, ev_view_presentation_set_white (pview); return TRUE; + case GDK_Home: + if (pview->state == EV_PRESENTATION_NORMAL) { + ev_view_presentation_update_current_page (pview, 0); + return TRUE; + } + break; + case GDK_End: + if (pview->state == EV_PRESENTATION_NORMAL) { + gint page; + + page = ev_document_get_n_pages (pview->document) - 1; + ev_view_presentation_update_current_page (pview, page); + + return TRUE; + } + break; default: break; } @@ -1105,6 +1151,12 @@ ev_view_presentation_button_release_event (GtkWidget *widget, case 1: { EvLink *link; + if (pview->state == EV_PRESENTATION_END) { + g_signal_emit (pview, signals[FINISHED], 0, NULL); + + return FALSE; + } + link = ev_view_presentation_get_link_at_location (pview, event->x, event->y); @@ -1355,6 +1407,15 @@ ev_view_presentation_class_init (EvViewPresentationClass *klass) g_cclosure_marshal_VOID__ENUM, G_TYPE_NONE, 1, GTK_TYPE_SCROLL_TYPE); + signals[FINISHED] = + g_signal_new ("finished", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EvViewPresentationClass, finished), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, + G_TYPE_NONE); binding_set = gtk_binding_set_by_class (klass); add_change_page_binding_keypad (binding_set, GDK_Left, 0, GTK_SCROLL_PAGE_BACKWARD);