Clipping in Cairo

While doing some hacking on Zowie, I noticed I was getting drastic slowdown when drawing large, clipped objects — typically when something is almost in the zooming-center and skids off to the side while very 'close' to the lens.

It turns out that clipping can be quite expensive in Cairo, under certain circumstances. When the clipping is complex or not aligned on pixel boundaries, Cairo resorts to using an intermediate buffer and compositing back to the surface in the context.

I have a couple of solutions on my plate:

  1. Make sure clipping paths are rectangular and pixel-aligned
  2. Don't bother even trying to draw things that would be fully clipped

I've implemented the latter just by testing if bounding boxes overlap the clipping region. Just this makes a huge difference! Cairo seems to keep up with painting plenty of shapes (rectangles, admittedly), so long as the large ones end up mostly off-screen. It is possible that there could be large, partially clipped shapes that don't comply and stay in view (it doesn't tend to happen in my example code at the minute); for that reason, I might need to experiment with the latter solution. It's a bit tricky because clipping regions can be at the bottom of a stack of transforms, so to get pixel co-ordinates I need to transform all the way up to world co-ordinates, apply the clip rectangle, then go back to where I was.

(BTW I do plan to make some of this hacking available eventually — my first target is to have zooming with the mouse and an editable text widget, and they are both in reach ..)