draw: Fix transparent image handling

Everyone uses "normal" alpha. Cairo uses pre-multiplied alpha. That means that
0x80800000 is translucent red and 0x80ff0000 is just invalid. We were using the
invalid version previously.

This fixes all kinds of tray icons whose background was previously wrong.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2010-10-15 21:27:22 +02:00
parent 1beb274944
commit 4af5ca8c34
1 changed files with 17 additions and 3 deletions

20
draw.c
View File

@ -107,9 +107,23 @@ int
luaA_surface_from_data(lua_State *L, int width, int height, uint32_t *data) luaA_surface_from_data(lua_State *L, int width, int height, uint32_t *data)
{ {
unsigned long int len = width * height; unsigned long int len = width * height;
unsigned char *buffer = p_dup(data, len); unsigned long int i;
cairo_surface_t *surface = uint32_t *buffer = p_new(uint32_t, len);
cairo_image_surface_create_for_data(buffer, cairo_surface_t *surface;
/* Cairo wants premultiplied alpha, meh :( */
for(i = 0; i < len; i++)
{
uint8_t a = (data[i] >> 24) & 0xff;
double alpha = a / 255.0;
uint8_t r = ((data[i] >> 16) & 0xff) * alpha;
uint8_t g = ((data[i] >> 8) & 0xff) * alpha;
uint8_t b = ((data[i] >> 0) & 0xff) * alpha;
buffer[i] = (a << 24) | (r << 16) | (g << 8) | b;
}
surface =
cairo_image_surface_create_for_data((unsigned char *) buffer,
CAIRO_FORMAT_ARGB32, CAIRO_FORMAT_ARGB32,
width, width,
height, height,