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
This commit is contained in:
Lars Uebernickel 2015-12-09 17:48:26 +01:00
parent a56a8a8c02
commit 1f07625705

View File

@ -56,8 +56,9 @@
* This allows you to efficiently read individual pixels on the client side. * 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 * 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 * the size specified by the @width and @height arguments scaled by the
* will contain an alpha channel if the @window contains one. * 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 * 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 * 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) gint height)
{ {
cairo_surface_t *surface; cairo_surface_t *surface;
cairo_surface_t *copy;
cairo_t *cr;
GdkPixbuf *dest; GdkPixbuf *dest;
g_return_val_if_fail (GDK_IS_WINDOW (src), NULL); 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); cairo_surface_mark_dirty (surface);
dest = gdk_pixbuf_get_from_surface (surface, if (cairo_surface_get_content (surface) & CAIRO_CONTENT_ALPHA)
src_x, src_y, copy = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width * scale, height * scale);
width, height); 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); cairo_surface_destroy (surface);
return dest; return dest;