[evince] EvSidebarThumbnails: render thumbnails correctly for hi-dpi displays



commit 2d3feb111939ea2cf15d5d749a3d0aa03693e830
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Thu Feb 27 19:15:04 2014 -0500

    EvSidebarThumbnails: render thumbnails correctly for hi-dpi displays
    
    Render thumbnails with resolution from gtk_widget_get_scale_factor() and
    recreate them when the scale change. Make the thumbnail-rendering helper
    functions create a hi-resolution surface when the widget has a scale
    factor.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=723431

 libdocument/ev-document-misc.c |   25 ++++++++++++++++++++++---
 shell/ev-sidebar-thumbnails.c  |   38 +++++++++++++++++++++++++++++++++-----
 2 files changed, 55 insertions(+), 8 deletions(-)
---
diff --git a/libdocument/ev-document-misc.c b/libdocument/ev-document-misc.c
index 4c3b54f..6d3c820 100644
--- a/libdocument/ev-document-misc.c
+++ b/libdocument/ev-document-misc.c
@@ -136,25 +136,39 @@ ev_document_misc_render_thumbnail_frame (GtkWidget       *widget,
 {
         GtkStyleContext *context = gtk_widget_get_style_context (widget);
         GtkStateFlags    state = gtk_widget_get_state_flags (widget);
-        int              width_r, height_r;
-        int              width_f, height_f;
+        double           width_r, height_r;
+        double           width_f, height_f;
         cairo_surface_t *surface;
         cairo_t         *cr;
+        double           device_scale_x = 1;
+        double           device_scale_y = 1;
         GtkBorder        border = {0, };
 
         if (source_surface) {
                 width_r = cairo_image_surface_get_width (source_surface);
                 height_r = cairo_image_surface_get_height (source_surface);
+#ifdef HAVE_HIDPI_SUPPORT
+                cairo_surface_get_device_scale (source_surface, &device_scale_x, &device_scale_y);
+#endif
         } else if (source_pixbuf) {
                 g_return_val_if_fail (GDK_IS_PIXBUF (source_pixbuf), NULL);
 
                 width_r = gdk_pixbuf_get_width (source_pixbuf);
                 height_r = gdk_pixbuf_get_height (source_pixbuf);
+#ifdef HAVE_HIDPI_SUPPORT
+                device_scale_x = device_scale_y = gtk_widget_get_scale_factor (widget);
+#endif
         } else {
                 width_r = width;
                 height_r = height;
+#ifdef HAVE_HIDPI_SUPPORT
+                device_scale_x = device_scale_y = gtk_widget_get_scale_factor (widget);
+#endif
         }
 
+        width_r /= device_scale_x;
+        height_r /= device_scale_y;
+
         gtk_style_context_save (context);
 
         gtk_style_context_add_class (context, "page-thumbnail");
@@ -166,7 +180,12 @@ ev_document_misc_render_thumbnail_frame (GtkWidget       *widget,
         height_f = height_r + border.top + border.bottom;
 
         surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                              width_f, height_f);
+                                              device_scale_x * width_f,
+                                              device_scale_y * height_f);
+
+#ifdef HAVE_HIDPI_SUPPORT
+        cairo_surface_set_device_scale (surface, device_scale_x, device_scale_y);
+#endif
 
         cr = cairo_create (surface);
         if (source_surface) {
diff --git a/shell/ev-sidebar-thumbnails.c b/shell/ev-sidebar-thumbnails.c
index 65703e0..994a403 100644
--- a/shell/ev-sidebar-thumbnails.c
+++ b/shell/ev-sidebar-thumbnails.c
@@ -102,6 +102,7 @@ static void         ev_sidebar_thumbnails_set_current_page (EvSidebarThumbnails
                                                            gint     page);
 static void         thumbnail_job_completed_callback       (EvJobThumbnail          *job,
                                                            EvSidebarThumbnails     *sidebar_thumbnails);
+static void         ev_sidebar_thumbnails_reload           (EvSidebarThumbnails     *sidebar_thumbnails);
 static void         adjustment_changed_cb                  (EvSidebarThumbnails     *sidebar_thumbnails);
 
 G_DEFINE_TYPE_EXTENDED (EvSidebarThumbnails, 
@@ -386,10 +387,16 @@ ev_sidebar_thumbnails_get_loading_icon (EvSidebarThumbnails *sidebar_thumbnails,
        icon = g_hash_table_lookup (priv->loading_icons, key);
        if (!icon) {
                gboolean inverted_colors;
+                gint device_scale = 1;
+
+#ifdef HAVE_HIDPI_SUPPORT
+                device_scale = gtk_widget_get_scale_factor (GTK_WIDGET (sidebar_thumbnails));
+#endif
 
                inverted_colors = ev_document_model_get_inverted_colors (priv->model);
                 icon = ev_document_misc_render_loading_thumbnail_surface (GTK_WIDGET (sidebar_thumbnails),
-                                                                          width, height,
+                                                                          width * device_scale,
+                                                                          height * device_scale,
                                                                           inverted_colors);
                g_hash_table_insert (priv->loading_icons, key, icon);
        } else {
@@ -462,16 +469,20 @@ get_size_for_page (EvSidebarThumbnails *sidebar_thumbnails,
        EvSidebarThumbnailsPrivate *priv = sidebar_thumbnails->priv;
         gdouble width, height;
         gint thumbnail_height;
+        gint device_scale = 1;
 
+#ifdef HAVE_HIDPI_SUPPORT
+        device_scale = gtk_widget_get_scale_factor (GTK_WIDGET (sidebar_thumbnails));
+#endif
         ev_document_get_page_size (priv->document, page, &width, &height);
         thumbnail_height = (int)(THUMBNAIL_WIDTH * height / width + 0.5);
 
         if (priv->rotation == 90 || priv->rotation == 270) {
-                *width_return = thumbnail_height;
-                *height_return = THUMBNAIL_WIDTH;
+                *width_return = thumbnail_height * device_scale;
+                *height_return = THUMBNAIL_WIDTH * device_scale;
         } else {
-                *width_return = THUMBNAIL_WIDTH;
-                *height_return = thumbnail_height;
+                *width_return = THUMBNAIL_WIDTH * device_scale;
+                *height_return = thumbnail_height * device_scale;
         }
 }
 
@@ -774,6 +785,14 @@ ev_sidebar_thumbnails_use_icon_view (EvSidebarThumbnails *sidebar_thumbnails)
 }
 
 static void
+ev_sidebar_thumbnails_device_scale_factor_changed_cb (EvSidebarThumbnails *sidebar_thumbnails,
+                                                      GParamSpec          *pspec)
+
+{
+        ev_sidebar_thumbnails_reload (sidebar_thumbnails);
+}
+
+static void
 ev_sidebar_thumbnails_init (EvSidebarThumbnails *ev_sidebar_thumbnails)
 {
        EvSidebarThumbnailsPrivate *priv;
@@ -802,6 +821,9 @@ ev_sidebar_thumbnails_init (EvSidebarThumbnails *ev_sidebar_thumbnails)
                                  ev_sidebar_thumbnails);
        gtk_box_pack_start (GTK_BOX (ev_sidebar_thumbnails), priv->swindow, TRUE, TRUE, 0);
 
+       g_signal_connect (ev_sidebar_thumbnails, "notify::scale-factor",
+                         G_CALLBACK (ev_sidebar_thumbnails_device_scale_factor_changed_cb), NULL);
+
        /* Put it all together */
        gtk_widget_show_all (priv->swindow);
 }
@@ -907,6 +929,12 @@ thumbnail_job_completed_callback (EvJobThumbnail      *job,
        EvSidebarThumbnailsPrivate *priv = sidebar_thumbnails->priv;
        GtkTreeIter                *iter;
         cairo_surface_t            *surface;
+#ifdef HAVE_HIDPI_SUPPORT
+        gint                        device_scale;
+
+        device_scale = gtk_widget_get_scale_factor (widget);
+        cairo_surface_set_device_scale (job->thumbnail_surface, device_scale, device_scale);
+#endif
 
         surface = ev_document_misc_render_thumbnail_surface_with_frame (widget,
                                                                         job->thumbnail_surface,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]