Fwd: [cairo] Re: NEW: cairo rendering in outline mode
Forward of a message by Jeff Muizelaar who is probably someone at Cairo and could not post this to the list because he is not subscribed.
Begin forwarded message:
From: Jeff Muizelaar <jeff@...1669...> Date: 2007 February 25 22:15:09 CEST To: bulia byak <buliabyak@...400...> Cc: jiho <jo.irisson@...400...>, cairo@...278..., inkscape List Devel inkscape-devel@lists.sourceforge.net Subject: Re: [cairo] Re: [Inkscape-devel] NEW: cairo rendering in outline mode
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.
JiHO --- http://jo.irisson.free.fr/
participants (1)
-
jiho