[cairo] Pattern rewrite

Kristian Høgsberg krh at bitplanet.net
Tue Jan 25 14:20:29 PST 2005


Hi,

The overall idea of this rewrite is that we want to pass the source
pattern all the way down into the backends.  The motivation for this
is that not all backends want a surface for the source operand, and by
passing the pattern down, backends can choose to convert it to a
surface if they need that.  For the RENDER-like backend (xlib and
image) a new surface must be created, whereas other backends (PDF,
glitz and win32 I think) implement or accelerate this differently.

I have removed the create_surface function pointer from the surface
vtable and moved much of that code into a couple of helper functions
that can be called from a surface backend if necessary:

	_cairo_pattern_get_image (): returns an image surface for the given 
bouding box for the given surface.

	_cairo_pattern_get_surface() returns a surface of the same type as the 
dst argument, except for gradient patterns where it returns an image 
surface.  This could probably be moved into the xlib backend and 
combined with _cairo_xlib_surface_clone_similar().

In order for a backend to be able to create a source surface for a 
painting operation, the backend needs the bounding box for the part of 
the source pattern that will be accessed by the operation.  Also, to
calculate the right offsets into the source pattern, the backend needs
to know the bounding box of the affected area in the destination
surface.  In the case of clipping, this differs from the source
pattern bounding box since we are drawing into an intermediate
surface--the size is the same though.  Even if the destination surface
bounding box is implicit in the trapezoids or glyps given, it's not
cheap to compute, and the upper layer (in cairo_gstate.c) always
computes it before calling into the backend so it makes sense to pass
it down.

The upshot of this is that I have changed the source surface argument
to composite, composite_trapezoids and show_glyphs to be a pattern.  I
added dst_x and dst_y arguments to composite_trapezoids and changed
the meaning and names of the x_src and y_src arguments.  These used to
be source surface coordinates relative to the upper left corner of the
first trapezoid, now they are just the coordinate of the upper left
corner of the source pattern bounding box.  Thus, all the drawing 
functions now take src_x, src_y, dst_x, dst_y, widht, and height, with 
the same meaning in all cases.

One little nit that's left is _cairo_gstate_create_pattern().  First it 
does some checking of the pattern and converts single stop gradients to 
solid colors.  Then it copies strate from gstate into the pattern.  I'd 
like to get rid of it entirely and not change the pattern, but I 
couldn't find an nice way to do that.

Future ideas:

The composite vtable entry takes mask_x and mask_y, which could be added 
to composite_trapezoids and show_glyphs to adjust the placement of the 
trapezoids and glyphs respectively.  The adjustment could instead take 
place in the backend, which for image could be combined with converting 
from cairo_trapezoid_t to pixman_trapezoid_t properly.  For the PDF 
backend the offset could be added while outputting the PDF drawing 
operators.  This way we don't have to change the trapezoids.

There's currently an issue with surface pattern offsets for show_glyphs 
that I'm looking into, but I thought I'd send this out for review as 
soon as possible so we can avoid blocking on this too long.  Also, this 
breaks the XCB, glitz and Quartz backends.

cheers,
Kristian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pattern-rewrite-2.patch
Type: text/x-patch
Size: 62083 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20050125/d38c987a/pattern-rewrite-2.bin


More information about the cairo mailing list