[cairo] How to flatten several data surfaces with transparency

Steve Moreau moreau.steve at free.fr
Mon Nov 5 23:37:16 PST 2012


Hi all,

Thanks for all inputs.
I remember I tested the byte ordering manually so in this case that was not
the problem (even it was not platform independent code I agree).
Here the issue seems to be the problem raised by behdad in Carlos' thread :
http://lists.freedesktop.org/archives/cairo/2012-July/023298.html

 * @CAIRO_FORMAT_ARGB32: each pixel is a 32-bit quantity, with
 *   alpha in the upper 8 bits, then red, then green, then blue.
 *   The 32-bit quantities are stored native-endian. *Pre-multiplied
 *   alpha is used. (That is, 50% transparent red is 0x80800000,
 *   not 0x80ff0000.) (Since 1.0)*


So I had to level the r, g, and b values to "alpha" maximum.
In other words, I understood that r or g or b should never be greater than
the matching opacity value.

For anyone interested, please find below how I interpreted it (for now).
Thanks,

Steve

void setColor(unsigned char* pixel, unsigned int color, unsigned char
opacity = 0xFF)
{
  unsigned char r = (color >> 16) & 0xFF;
  unsigned char g = (color >> 8) & 0xFF;
  unsigned char b = (color) & 0xFF;

  r = r*opacity/255;
  g = g*opacity/255;
  b = b*opacity/255;

  *((unsigned int*) pixel) = opacity << 24 | r << 16 | g << 8 | b;
}


2012/11/6 Steve Moreau <moreau.steve at free.fr>

> Thank you guys,
>
> I will try and let you know when it works.
> Regards,
>
> Steve
>
>
> 2012/11/5 Bill Spitzak <spitzak at gmail.com>
>
>> Cairo wants pre-multiplied data for the OVER composite. This likely means
>> that the green value should depend on y just like the alpha value does. Ie
>> set the green to (y < 50 ? 0 : 50 * (y - 50)/height)
>>
>> Also I recommend filling in the buffer as 32-bit words, rather than
>> bytes. This is faster and will make the it work on a big-endian machine.
>>
>> unsigned char* buf = (unsigned char*)malloc(4*width*height);
>>   cairo_surface_t* dataSurface = cairo_image_surface_create_**for_data
>> (buf, CAIRO_FORMAT_ARGB32, width, height, rowLen);
>>   for (y=0; y<height; y++)
>>   {
>>     for (x=0; x<width; x++)
>>     {
>>       //setColor(&buf[y*rowLen+x*4], 0x00FF00, y*255.0/3/height);
>>       buf[y*rowLen+x*4+0] = 0;
>>       buf[y*rowLen+x*4+1] = 50;
>>       buf[y*rowLen+x*4+2] = 0;
>>       buf[y*rowLen+x*4+3] = (y < 50 ? 0 : (y-50)*255.0/height);
>>     }
>>   }
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cairographics.org/archives/cairo/attachments/20121106/38733343/attachment-0001.html>


More information about the cairo mailing list