[cairo] cairo internal design ideas

Bill Spitzak spitzak at d2.com
Tue Sep 21 11:44:59 PDT 2004

On Tuesday 21 September 2004 03:56 am, David Reveman wrote:

> Surface backends would also be able to retrieve different
> representations of path objects. E.g. XCB, Xlib, glitz and pixman
> backends would probably like to get a list of trapezoids representing a
> path object but a PDF or a SVG backend would probably just interpret the
> path object as it is. A backend that can't do trapezoids would be able
> to ask for an image mask.

It would probably work best if the path object could contain all the types of 
data at once, and Cairo provides converter functions that can take a path and 
make a new one constructed out of a limited number of objects.

An example type of path (not necessarily the best idea) is that it is array 
of id,x,y tuples. The id is an enumeration:

	0 = reserved as end marker
	indicator for two more numbers for previous command
	moveto (also does closepath since we are only filling)
	curveto (followed by 2 more xy)
	closed rectangle (followed by 1 more xy)
	triangle strip (followed by n+1 more xy for n triangles)
	triangle fan (followed by n+1 more xy for n triangles)
	trapazoid (followed by 2 more: x1,x2,x3,y3)

Then there would be Cairo calls that a backend can use to take an arbitrary 
path and return a new one that limits the commands to a certain subset. 
Likely subsets are moveto+lineto, triangles+rectangles, trapazoids. Each 
subset can be a different call, subsets are written when and if a backend 
needs one. There should also be a call that turns a path into an 8-bit 
in-memory image mask.

The reason for this is so that the public Cairo API could take paths defined 
by things other than moveto/lineto and efficiently pass them to the backend. 
I feel it is going to be vital for Cairo's acceptance that making the path 
(especially the clip path) out of rectangles be efficient.

Other thoughts:

This is for filling only. Stroking should be done by Cairo by converting the 
path into a new one. Only caveat is that perhaps a "thin stroke" interface be 
provided for thicknesses less or equal to 1 pixel. It would draw a 1-pixel 
antialiased line (or thinner by making it more transparent). I really doubt 
that the backends will do anything with thicker lines other than convert them 
to filled paths?

The Cairo front end could cheat by using the glyph cache. One thing would be 
to make glyphs of single dots of various line thicknesses, and convert stroke 
of zero-length paths into these, rather than into circular paths. It may also 
help to recognize attempts to make circles and turn them into glyphs as well. 
However for this to work as well as possible it may mean the backend must 
accept a single call with *both* glyphs and paths. Maybe the "id" in the 
above scheme (since it is probably sizeof(double) for alignment) could 
contain a hash of the font+glyph?

You must resist the temptation to make the back-end interface visible in the 
public Cairo API. A normal program should not be able to examine or convert 
these path objects. If they absolutely must, you could write a special 
backend that does it.

More information about the cairo mailing list