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-image-content.h"
|
||||||
#include "st-private.h"
|
#include "st-private.h"
|
||||||
|
|
||||||
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
|
|
||||||
struct _StImageContent
|
struct _StImageContent
|
||||||
{
|
{
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
@ -541,6 +541,121 @@ pixbuf_to_st_content_image (GdkPixbuf *pixbuf,
|
|||||||
return image;
|
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 *
|
static cairo_surface_t *
|
||||||
pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
|
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);
|
dummy_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
|
||||||
|
|
||||||
cr = cairo_create (dummy_surface);
|
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);
|
pattern = cairo_get_source (cr);
|
||||||
cairo_pattern_get_surface (pattern, &surface);
|
cairo_pattern_get_surface (pattern, &surface);
|
||||||
cairo_surface_reference (surface);
|
cairo_surface_reference (surface);
|
||||||
|
Loading…
Reference in New Issue
Block a user