From 557d371972b4410765afb303ab6ec82720e0e86b Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Thu, 27 Feb 2014 19:22:55 -0500 Subject: EvPresentationView: Render correctly on hi-dpi displays Create rendering jobs with a scale that incorporate the scale factor of the widget, and then use cairo_surface_set_device_scale() to make the resulting surfaces render at the correct size. Handle changes to the scale factor both for the cached surfaces, and also for the monitor dimensions, which are reported in scaled coordinates. https://bugzilla.gnome.org/show_bug.cgi?id=723431 origin commit: https://git.gnome.org/browse/evince/commit/?id=37c13b --- libview/ev-view-presentation.c | 61 +++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 13 deletions(-) (limited to 'libview') diff --git a/libview/ev-view-presentation.c b/libview/ev-view-presentation.c index 997a11b1..31a473ae 100644 --- a/libview/ev-view-presentation.c +++ b/libview/ev-view-presentation.c @@ -283,11 +283,28 @@ ev_view_presentation_transition_animation_frame (EvViewPresentation *pview, gtk_widget_queue_draw (GTK_WIDGET (pview)); } +static cairo_surface_t * +get_surface_from_job (EvViewPresentation *pview, + EvJob *job) +{ + cairo_surface_t *surface; + + if (!job) + return NULL; + + surface = EV_JOB_RENDER(job)->surface; + if (!surface) + return NULL; + + return surface; +} + static void ev_view_presentation_animation_start (EvViewPresentation *pview, gint new_page) { EvTransitionEffect *effect = NULL; + EvJob *job; cairo_surface_t *surface; gint jump; @@ -311,11 +328,12 @@ ev_view_presentation_animation_start (EvViewPresentation *pview, jump = new_page - pview->current_page; if (jump == -1) - surface = pview->prev_job ? EV_JOB_RENDER (pview->prev_job)->surface : NULL; + job = pview->prev_job; else if (jump == 1) - surface = pview->next_job ? EV_JOB_RENDER (pview->next_job)->surface : NULL; + job = pview->next_job; else - surface = NULL; + job = NULL; + surface = get_surface_from_job (pview, job); if (surface) ev_transition_animation_set_dest_surface (pview->animation, surface); @@ -342,7 +360,7 @@ job_finished_cb (EvJob *job, if (pview->animation) { ev_transition_animation_set_dest_surface (pview->animation, - job_render->surface); + get_surface_from_job (pview, job)); } else { ev_view_presentation_transition_start (pview); gtk_widget_queue_draw (GTK_WIDGET (pview)); @@ -1064,7 +1082,7 @@ ev_view_presentation_draw (GtkWidget *widget, return TRUE; } - surface = pview->curr_job ? EV_JOB_RENDER (pview->curr_job)->surface : NULL; + surface = get_surface_from_job (pview, pview->curr_job); if (surface) { ev_view_presentation_update_current_surface (pview, surface); } else if (pview->current_surface) { @@ -1212,19 +1230,25 @@ ev_view_presentation_motion_notify_event (GtkWidget *widget, return FALSE; } -static gboolean -init_presentation (GtkWidget *widget) +static void +ev_view_presentation_update_monitor_geometry (EvViewPresentation *pview) { - EvViewPresentation *pview = EV_VIEW_PRESENTATION (widget); - GdkDisplay *display = gtk_widget_get_display (widget); + GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (pview)); GdkRectangle monitor; - GdkMonitor *monitor_num; - - monitor_num = gdk_display_get_monitor_at_window (display, gtk_widget_get_window (widget)); - gdk_monitor_get_geometry (monitor_num, &monitor); + gint monitor_num; + monitor_num = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (GTK_WIDGET (pview))); + gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor); pview->monitor_width = monitor.width; pview->monitor_height = monitor.height; +} + +static gboolean +init_presentation (GtkWidget *widget) +{ + EvViewPresentation *pview = EV_VIEW_PRESENTATION (widget); + + ev_view_presentation_update_monitor_geometry (pview); ev_view_presentation_update_current_page (pview, pview->current_page); ev_view_presentation_hide_cursor_timeout_start (pview); @@ -1378,6 +1402,14 @@ ev_view_presentation_get_property (GObject *object, } } + static void +ev_view_presentation_notify_scale_factor (EvViewPresentation *pview) +{ + ev_view_presentation_update_monitor_geometry (pview); + ev_view_presentation_reset_jobs (pview); + ev_view_presentation_update_current_page (pview, pview->current_page); +} + static GObject * ev_view_presentation_constructor (GType type, guint n_construct_properties, @@ -1397,6 +1429,9 @@ ev_view_presentation_constructor (GType type, ev_page_cache_set_flags (pview->page_cache, EV_PAGE_DATA_INCLUDE_LINKS); } + g_signal_connect (object, "notify::scale-factor", + G_CALLBACK (ev_view_presentation_notify_scale_factor), NULL); + return object; } -- cgit v1.2.1