diff --git a/gdk/gdkcairo.c b/gdk/gdkcairo.c index 5dba69a8f7..d16a619ebd 100644 --- a/gdk/gdkcairo.c +++ b/gdk/gdkcairo.c @@ -175,45 +175,32 @@ gdk_cairo_region (cairo_t *cr, } } -/** - * gdk_cairo_surface_create_from_pixbuf: - * @pixbuf: a #GdkPixbuf - * @scale: the scale of the new surface, or 0 to use same as @window - * @for_window: The window this will be drawn to, on %NULL. - * - * Creates an image surface with the same contents as - * the pixbuf. - * - * Returns: a new cairo surface, must be freed with cairo_surface_destroy() - * - * Since: 3.10 - */ -cairo_surface_t * -gdk_cairo_surface_create_from_pixbuf (const GdkPixbuf *pixbuf, - int scale, - GdkWindow *for_window) +static void +gdk_cairo_surface_paint_pixbuf (cairo_surface_t *surface, + const GdkPixbuf *pixbuf) { - gint width = gdk_pixbuf_get_width (pixbuf); - gint height = gdk_pixbuf_get_height (pixbuf); - guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf); - int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf); - int n_channels = gdk_pixbuf_get_n_channels (pixbuf); - int cairo_stride; - guchar *cairo_pixels; - cairo_format_t format; - cairo_surface_t *surface; + gint width, height; + guchar *gdk_pixels, *cairo_pixels; + int gdk_rowstride, cairo_stride; + int n_channels; int j; - if (n_channels == 3) - format = CAIRO_FORMAT_RGB24; - else - format = CAIRO_FORMAT_ARGB32; + /* This function can't just copy any pixbuf to any surface, be + * sure to read the invariants here before calling it */ - surface = - gdk_window_create_similar_image_surface (for_window, - format, - width, height, - scale); + g_assert (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE); + g_assert (cairo_image_surface_get_format (surface) == CAIRO_FORMAT_RGB24 || + cairo_image_surface_get_format (surface) == CAIRO_FORMAT_ARGB32); + g_assert (cairo_image_surface_get_width (surface) == gdk_pixbuf_get_width (pixbuf)); + g_assert (cairo_image_surface_get_height (surface) == gdk_pixbuf_get_height (pixbuf)); + + cairo_surface_flush (surface); + + 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); cairo_stride = cairo_image_surface_get_stride (surface); cairo_pixels = cairo_image_surface_get_data (surface); @@ -274,6 +261,43 @@ gdk_cairo_surface_create_from_pixbuf (const GdkPixbuf *pixbuf, } cairo_surface_mark_dirty (surface); +} + +/** + * gdk_cairo_surface_create_from_pixbuf: + * @pixbuf: a #GdkPixbuf + * @scale: the scale of the new surface, or 0 to use same as @window + * @for_window: The window this will be drawn to, on %NULL. + * + * Creates an image surface with the same contents as + * the pixbuf. + * + * Returns: a new cairo surface, must be freed with cairo_surface_destroy() + * + * Since: 3.10 + */ +cairo_surface_t * +gdk_cairo_surface_create_from_pixbuf (const GdkPixbuf *pixbuf, + int scale, + GdkWindow *for_window) +{ + cairo_format_t format; + cairo_surface_t *surface; + + if (gdk_pixbuf_get_n_channels (pixbuf) == 3) + format = CAIRO_FORMAT_RGB24; + else + format = CAIRO_FORMAT_ARGB32; + + surface = + gdk_window_create_similar_image_surface (for_window, + format, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + scale); + + gdk_cairo_surface_paint_pixbuf (surface, pixbuf); + return surface; }