[gtk+] gdk_pixbuf_get_from_window: honor device scale



commit 1f076257059f15f37c2c93853c3eff2ec2be2aa1
Author: Lars Uebernickel <lars uebernickel canonical com>
Date:   Wed Dec 9 17:48:26 2015 +0100

    gdk_pixbuf_get_from_window: honor device scale
    
    gdk_pixbuf_get_from_window() paints the given window onto a new cairo
    surface. Create that new surface with the same device scale as the
    window so that the result is not scaled down on hidpi screens.
    
    This is similar to 657a43e (which was reverted), but doesn't modify the
    behavior of gdk_pixbuf_get_from_surface().
    
    https://bugzilla.gnome.org/show_bug.cgi?id=757147

 gdk/gdkpixbuf-drawable.c |   26 +++++++++++++++++++++-----
 1 files changed, 21 insertions(+), 5 deletions(-)
---
diff --git a/gdk/gdkpixbuf-drawable.c b/gdk/gdkpixbuf-drawable.c
index ae6e7da..2f780a5 100644
--- a/gdk/gdkpixbuf-drawable.c
+++ b/gdk/gdkpixbuf-drawable.c
@@ -56,8 +56,9 @@
  * This allows you to efficiently read individual pixels on the client side.
  *
  * This function will create an RGB pixbuf with 8 bits per channel with
- * the same size specified by the @width and @height arguments. The pixbuf
- * will contain an alpha channel if the @window contains one.
+ * the size specified by the @width and @height arguments scaled by the
+ * scale factor of @window. The pixbuf will contain an alpha channel if
+ * the @window contains one.
  *
  * If the window is off the screen, then there is no image data in the
  * obscured/offscreen regions to be placed in the pixbuf. The contents of
@@ -87,6 +88,8 @@ gdk_pixbuf_get_from_window (GdkWindow *src,
                             gint       height)
 {
   cairo_surface_t *surface;
+  cairo_surface_t *copy;
+  cairo_t *cr;
   GdkPixbuf *dest;
 
   g_return_val_if_fail (GDK_IS_WINDOW (src), NULL);
@@ -101,9 +104,22 @@ gdk_pixbuf_get_from_window (GdkWindow *src,
    */
   cairo_surface_mark_dirty (surface);
 
-  dest = gdk_pixbuf_get_from_surface (surface,
-                                      src_x, src_y,
-                                      width, height);
+  if (cairo_surface_get_content (surface) & CAIRO_CONTENT_ALPHA)
+    copy = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width * scale, height * scale);
+  else
+    copy = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width * scale, height * scale);
+
+  cairo_surface_set_device_scale (copy, scale, scale);
+
+  cr = cairo_create (copy);
+  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+  cairo_set_source_surface (cr, surface, -src_x, -src_y);
+  cairo_paint (cr);
+  cairo_destroy (cr);
+
+  dest = gdk_pixbuf_get_from_surface (copy, 0, 0, width * scale, height * scale);
+
+  cairo_surface_destroy (copy);
   cairo_surface_destroy (surface);
 
   return dest;


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