[evince] EvPresentationView: Render correctly on hi-dpi displays
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince] EvPresentationView: Render correctly on hi-dpi displays
- Date: Wed, 23 Jul 2014 14:55:58 +0000 (UTC)
commit 37c13b386a89156e616dc24db2cf6a3b64c4c6a7
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Thu Feb 27 19:22:55 2014 -0500
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
libview/ev-view-presentation.c | 70 ++++++++++++++++++++++++++++++++++------
1 files changed, 60 insertions(+), 10 deletions(-)
---
diff --git a/libview/ev-view-presentation.c b/libview/ev-view-presentation.c
index 678b456..ea9aee0 100644
--- a/libview/ev-view-presentation.c
+++ b/libview/ev-view-presentation.c
@@ -274,11 +274,35 @@ 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;
+
+#ifdef HAVE_HIDPI_SUPPORT
+ {
+ int scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (pview));
+ cairo_surface_set_device_scale (surface, scale_factor, scale_factor);
+ }
+#endif
+
+ 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;
@@ -302,11 +326,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);
@@ -333,7 +358,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));
@@ -352,6 +377,13 @@ ev_view_presentation_schedule_new_job (EvViewPresentation *pview,
return NULL;
ev_view_presentation_get_view_size (pview, page, &view_width, &view_height);
+#ifdef HAVE_HIDPI_SUPPORT
+ {
+ gint device_scale = gtk_widget_get_scale_factor (GTK_WIDGET (pview));
+ view_width *= device_scale;
+ view_height *= device_scale;
+ }
+#endif
job = ev_job_render_new (pview->document, page, pview->rotation, 0.,
view_width, view_height);
g_signal_connect (job, "finished",
@@ -1069,7 +1101,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) {
@@ -1224,18 +1256,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);
- GdkScreen *screen = gtk_widget_get_screen (widget);
+ GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (pview));
GdkRectangle monitor;
gint monitor_num;
- monitor_num = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (widget));
+ 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);
@@ -1391,6 +1430,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,
@@ -1410,6 +1457,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;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]