[cairo] Re: [Inkscape-devel] NEW: cairo rendering in outline mode

Jeff Muizelaar jeff at infidigm.net
Sun Feb 25 13:15:09 PST 2007

On Sun, Feb 25, 2007 at 11:10:16AM -0500, bulia byak wrote:
> Last night, with the help of Carl Worth, the issue of cairo/inkscape
> not working on mac was more or less clarified. Here's how I understand
> it.
> When drawing into a memory buffer, cairo uses a fixed byte order of
> the R, G, B, A bytes regardless of the platform.

This is incorrect. Cairo's byte order depends on the platform. See, for
example, pixman/src/fbpict.c:fbOver():

static CARD32
fbOver (CARD32 x, CARD32 y)
    CARD16  a = ~x >> 24;
    CARD16  t;
    CARD32  m,n,o,p;

    m = FbOverU(x,y,0,a,t);
    n = FbOverU(x,y,8,a,t);
    o = FbOverU(x,y,16,a,t);
    p = FbOverU(x,y,24,a,t);
    return m|n|o|p;

As is shown, the alpha component is always in the most significant byte. So
byte 0 on big endian and byte 3 on little endian. 

However, Inkscape's code assumes a fixed byte order (see below). i.e R is byte
0, G is byte 1 etc.

nr_R8G8B8A8_N_EMPTY_A8_RGBA32 (unsigned char *px, int w, int h, int rs, const unsigned char *mpx, int mrs, unsigned long rgba)
	unsigned int r, g, b, a;
	unsigned int x, y;

	r = NR_RGBA32_R (rgba);
	g = NR_RGBA32_G (rgba);
	b = NR_RGBA32_B (rgba);
	a = NR_RGBA32_A (rgba);

	for (y = h; y > 0; y--) {
		if (a == 0) {
			memset(px, 0, w*4);
		} else {
			unsigned char *d = px;
			const unsigned char *m = mpx;
			for (x = w; x > 0; x--) {
				d[0] = r;
				d[1] = g;
				d[2] = b;
				d[3] = NR_PREMUL_111 (m[0], a);
				d += 4;
				m += 1;
		px += rs;
		mpx += mrs;

> Inkscape and GDK (which is used by Inkscape for drawing to screen),
> however, both use system-dependent byte order, i.e. the order of R, G,
> B, A is determined by the hardware and is different on PC and Mac
> platforms.
> And it so happens that the fixed order of cairo coincides with the
> hardware order on PC but not on Mac. Hence, painting by cairo directly
> into Inkscape/GDK buffers worked on PC but on Mac, all colors are
> wrong and (in case of outline) black color gets zero opacity, i.e.
> becomes invisible.
> Essentially, this means that Inkscape and cairo are not compatible as
> is, and that a gradual switching of parts of our display engine to
> cairo is not possible. (Unless we ditch Macs, of course.)
> Even if we switch our screen output from using GDK to cairo (which is
> relatively easy), this won't help - it will just break rendering on
> PCs too. Inkscape has a lot (and I do mean A LOT) of code that assumes
> system-dependent byte order. Composers, decomposers, premultipliers,
> unpremultipliers, blitters and blotters of all sizes and colors
> permeate the codebase. Most of them come all the way from Sodipodi.

Fortunately, cairo has a lot of equivalent code that matches cairo's byte
order. It also looks like alot of inkscape's compositing code, like cairo's,
isn't particularily fast either.

> Now, of course, it's possible to create "adapters" for cairo bits.
> That is, every time we use cairo, instead of drawing directly into
> Inkscape buffer, we can draw into a temporary buffer instead,
> rearrange the bytes in that buffer, and then compose that into the
> main buffer. But that is certain to more than negate the feeble speed
> gains we're seeing from cairo's image backend rendering.
> Or, we can attempt a much more drastic rearchitecturing, by changing
> our functions so they pass around cairo contexts instead of Inkscape
> buffers. With this approach, byte reordering will be needed less
> frequently, and eventually eliminated completely. But this is not only
> much more work, it will also mean a lot more bugs and regressions and
> quite some time before Inkscape is usable again.
> So, it looks like due to this stupid byte-order issue, cairo for us is
> practically an all-or-nothing proposition - and much more hassle than
> I expected. I'm not saying it's impossible but it is quite a major
> project that cannot be done gradually.
> Unless, of course, cairo gets so in love with Inkscape as to provide
> us with a new image surface with system-dependent byte order...

This is painful as well. All of cairo's software compositing routines use the
cairo byte order, and likewise X assumes this byte order as well.


More information about the cairo mailing list