From 67197e562dbdfdbd518d1e8ffb4746af41c3f731 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 17 May 2013 15:58:15 +0200 Subject: [PATCH 64/68] gdk: Lookup double scaled variants on pixbufs if the pixbuf contains its @2x variant as gobject data and the display has a doubled scale factor, use such pixbuf for rendering --- gdk/gdkcairo.c | 36 ++++++++++++++++++++++++++++++++++-- gdk/gdkdraw.c | 18 ++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/gdk/gdkcairo.c b/gdk/gdkcairo.c index c423871..9aab5e1 100644 --- a/gdk/gdkcairo.c +++ b/gdk/gdkcairo.c @@ -23,6 +23,8 @@ #include "gdkregion-generic.h" #include "gdkalias.h" +static const cairo_user_data_key_t gdk_cairo_drawable_pointer; + static void gdk_ensure_surface_flush (gpointer surface) { @@ -58,6 +60,7 @@ gdk_cairo_create (GdkDrawable *drawable) surface = _gdk_drawable_ref_cairo_surface (drawable); cr = cairo_create (surface); + cairo_set_user_data (cr, &gdk_cairo_drawable_pointer, drawable, NULL); if (GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_clip) GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_clip (drawable, cr); @@ -202,7 +205,32 @@ gdk_cairo_set_source_pixbuf (cairo_t *cr, cairo_format_t format; cairo_surface_t *surface; static const cairo_user_data_key_t key; - int j; + GdkWindow *window; + cairo_pattern_t *pattern; + cairo_matrix_t matrix; + int j, scale = 1; + + window = cairo_get_user_data (cr, &gdk_cairo_drawable_pointer); + + if (window && + (int) gdk_window_get_scale_factor (window) == 2) + { + GdkPixbuf *scaled_pixbuf; + + scaled_pixbuf = g_object_get_data (G_OBJECT (pixbuf), + "gdk-pixbuf-2x-variant"); + if (scaled_pixbuf) + { + scale = 2; + pixbuf = scaled_pixbuf; + } + } + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + gdk_pixels = gdk_pixbuf_get_pixels (pixbuf); + gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf); + n_channels = gdk_pixbuf_get_n_channels (pixbuf); if (n_channels == 3) format = CAIRO_FORMAT_RGB24; @@ -274,7 +302,11 @@ gdk_cairo_set_source_pixbuf (cairo_t *cr, cairo_pixels += cairo_stride; } - cairo_set_source_surface (cr, surface, pixbuf_x, pixbuf_y); + cairo_set_source_surface (cr, surface, 0, 0); + pattern = cairo_get_source (cr); + cairo_matrix_init_scale (&matrix, scale, scale); + cairo_matrix_translate (&matrix, -pixbuf_x, -pixbuf_y); + cairo_pattern_set_matrix (pattern, &matrix); cairo_surface_destroy (surface); } diff --git a/gdk/gdkdraw.c b/gdk/gdkdraw.c index 932de97..6ebd8c7 100644 --- a/gdk/gdkdraw.c +++ b/gdk/gdkdraw.c @@ -819,6 +819,8 @@ gdk_draw_pixbuf (GdkDrawable *drawable, gint x_dither, gint y_dither) { + GdkPixbuf *scaled_pixbuf; + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); g_return_if_fail (gc == NULL || GDK_IS_GC (gc)); g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); @@ -826,6 +828,22 @@ gdk_draw_pixbuf (GdkDrawable *drawable, if (width == 0 || height == 0) return; + scaled_pixbuf = g_object_get_data (G_OBJECT (pixbuf), + "gdk-pixbuf-2x-variant"); + + if (scaled_pixbuf && GDK_IS_WINDOW (drawable) && + (int) gdk_window_get_scale_factor (GDK_WINDOW (drawable)) == 2) + { + cairo_t *cr; + + cr = gdk_cairo_create (GDK_WINDOW (drawable)); + gdk_cairo_set_source_pixbuf (cr, pixbuf, dest_x, dest_y); + cairo_paint (cr); + + cairo_destroy (cr); + return; + } + if (width == -1) width = gdk_pixbuf_get_width (pixbuf); if (height == -1) -- 1.7.10.2 (Apple Git-33)