[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.
void
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.
-Jeff
More information about the cairo
mailing list