st: Drop usage of gdk_cairo_set_source_pixbuf()
Avoid using it by... guess it... yes! Copying the function into an utility. This helper function to convert between pixel formats is quite self-contained and unrelated to the rest of GTK, so may be copied in place. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2655>
This commit is contained in:
parent
32eff6bbde
commit
d3545a3b53
@ -21,6 +21,8 @@
|
||||
#include "st-image-content.h"
|
||||
#include "st-private.h"
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
struct _StImageContent
|
||||
{
|
||||
/*< private >*/
|
||||
|
@ -541,6 +541,121 @@ pixbuf_to_st_content_image (GdkPixbuf *pixbuf,
|
||||
return image;
|
||||
}
|
||||
|
||||
static void
|
||||
util_cairo_surface_paint_pixbuf (cairo_surface_t *surface,
|
||||
const GdkPixbuf *pixbuf)
|
||||
{
|
||||
int width, height;
|
||||
guchar *gdk_pixels, *cairo_pixels;
|
||||
int gdk_rowstride, cairo_stride;
|
||||
int n_channels;
|
||||
int j;
|
||||
|
||||
if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
|
||||
return;
|
||||
|
||||
/* This function can't just copy any pixbuf to any surface, be
|
||||
* sure to read the invariants here before calling it */
|
||||
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);
|
||||
|
||||
for (j = height; j; j--)
|
||||
{
|
||||
guchar *p = gdk_pixels;
|
||||
guchar *q = cairo_pixels;
|
||||
|
||||
if (n_channels == 3)
|
||||
{
|
||||
guchar *end = p + 3 * width;
|
||||
|
||||
while (p < end)
|
||||
{
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
q[0] = p[2];
|
||||
q[1] = p[1];
|
||||
q[2] = p[0];
|
||||
#else
|
||||
q[1] = p[0];
|
||||
q[2] = p[1];
|
||||
q[3] = p[2];
|
||||
#endif
|
||||
p += 3;
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
guchar *end = p + 4 * width;
|
||||
guint t1,t2,t3;
|
||||
|
||||
#define MULT(d,c,a,t) G_STMT_START { t = c * a + 0x80; d = ((t >> 8) + t) >> 8; } G_STMT_END
|
||||
|
||||
while (p < end)
|
||||
{
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
MULT(q[0], p[2], p[3], t1);
|
||||
MULT(q[1], p[1], p[3], t2);
|
||||
MULT(q[2], p[0], p[3], t3);
|
||||
q[3] = p[3];
|
||||
#else
|
||||
q[0] = p[3];
|
||||
MULT(q[1], p[0], p[3], t1);
|
||||
MULT(q[2], p[1], p[3], t2);
|
||||
MULT(q[3], p[2], p[3], t3);
|
||||
#endif
|
||||
|
||||
p += 4;
|
||||
q += 4;
|
||||
}
|
||||
|
||||
#undef MULT
|
||||
}
|
||||
|
||||
gdk_pixels += gdk_rowstride;
|
||||
cairo_pixels += cairo_stride;
|
||||
}
|
||||
|
||||
cairo_surface_mark_dirty (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
util_cairo_set_source_pixbuf (cairo_t *cr,
|
||||
const GdkPixbuf *pixbuf,
|
||||
gdouble pixbuf_x,
|
||||
gdouble pixbuf_y)
|
||||
{
|
||||
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 = cairo_surface_create_similar_image (cairo_get_target (cr),
|
||||
format,
|
||||
gdk_pixbuf_get_width (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf));
|
||||
|
||||
util_cairo_surface_paint_pixbuf (surface, pixbuf);
|
||||
|
||||
cairo_set_source_surface (cr, surface, pixbuf_x, pixbuf_y);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
|
||||
{
|
||||
@ -552,7 +667,7 @@ pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
|
||||
dummy_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
|
||||
|
||||
cr = cairo_create (dummy_surface);
|
||||
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
||||
util_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
|
||||
pattern = cairo_get_source (cr);
|
||||
cairo_pattern_get_surface (pattern, &surface);
|
||||
cairo_surface_reference (surface);
|
||||
|
Loading…
Reference in New Issue
Block a user