From 4af5ca8c3480b4d19ec3d54386721cbf46ab0472 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Fri, 15 Oct 2010 21:27:22 +0200 Subject: [PATCH] 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 --- draw.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/draw.c b/draw.c index 6d0eef69..f48c4cd0 100644 --- a/draw.c +++ b/draw.c @@ -107,9 +107,23 @@ int luaA_surface_from_data(lua_State *L, int width, int height, uint32_t *data) { unsigned long int len = width * height; - unsigned char *buffer = p_dup(data, len); - cairo_surface_t *surface = - cairo_image_surface_create_for_data(buffer, + unsigned long int i; + uint32_t *buffer = p_new(uint32_t, len); + 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, width, height,