I have just committed a change which turns SPCanvasBuf from 24bpp to 32bpp (since cairo cannot handle 24bpp buffers) and adds a cairo_t member (buf->ct) that canvas items can use to draw themselves using cairo. So far, canvas bpaths, ctrllines, and ctrlquadrs are drawn with cairo; the rest of items still use direct bitflipping although they are updated for 32bpp (and I think they should stay that way, as they don't need antialiasing and cairo would be much slower for them).
Everything should work and behave exactly as before, except a little faster, and except the temporary regressions outlined below. Note that this only concerns canvas items; regular objects are still rendered as before. Total cairofication has become closer but we're not there yet.
Here's what you need to remember to use cairo to render a canvasitem:
- In the update method, you're given an affine matrix. Remember it.
- In the render method, transform your points by the remembered affine, and then subtract from it the point (buf->rect.x0, buf->rect.y0). Use the resulting coords to draw into buf->ct, then everything will be where it must be.
- When setting colors using cairo_set_source_rgba, give the components in the order B, G, R, A, not R G B A.
Problems and regressions:
1 For some reason, drawing the canvasbuf onto the screen using cairo is very slow. So I had to keep the old method using gdk_draw_rgb_image_dithalign, which is faster even though it involves a 32bpp->24bpp conversion because gdk can only deal with 24bpp. This is controlled by the define CANVAS_OUTPUT_VIA_CAIRO in sp-canvas.cpp; uncomment it to use the cairo output. Can any cairo guru guess what is going wrong here?
2 Cairo cannot draw over the past content of the buffer with inversion. The XOR operator does not result in inversion, or at least I couldn't figure out how. So, the text selection (Shift+arrows over) had to become semitransparent blue instead of black with inversion. Hopefully this will be possible to fix with a future version of cairo.
3 With apologies to Mac users, I had to take out the code which reverts the byte order depending on endianness, which used to fix the problem caused by our using fixed byte order (RGBA) and cairo depending on the endianness of the hardware. Now that many things draw directly into the buffer using cairo, I can no longer easily separate what is drawn with cairo and what not, so there's no endianness fix anymore and as a result the colors of canvas items on a Mac will likely be wrong. This is a temporary regression; when rendering of regular objects is also cairoified, we can restore this fix, and when the problem 1 above is fixed, this endianness fix will be no longer needed because everything will be cairo throughout.
Let me know if you find any problems.