[cairo] cairo_draw_with_xlib API

Robert O'Callahan rocallahan at novell.com
Wed Feb 22 19:39:14 PST 2006


We (Mozilla) need a way to take existing code that draws to an X
drawable and redirect the drawing to an arbitrary cairo context, so that
the drawing respects all cairo state (clipping, transforms, operator,
etc). The main reason we need this is to get existing GTK2 themes to
render in our cairo builds, even when the themed widget is rotated or
scaled. Two additional requirements:
-- For the common case where the cairo state has nothing interesting and
the target surface is an X drawable, the implementation needs to hand
the X drawable directly to the X-drawing code. Otherwise we will eat a
significant performance hit compared to our non-cairo builds.
-- Many themes paint with transparency or possibly even translucency
(e.g., by just not painting the entire widget area). This must be
supported.

Despite appearances, this API is not specific to xlib surfaces. In
Mozilla we will be applying it to PDF, PS and possibly glitz surfaces.
One could even imagine using it with Windows and Quartz surfaces if one
was thoroughly demented.

We've designed an API to do this, which I call cairo_draw_with_xlib. The
implementation basically chooses one of three strategies:
-- If the target surface is an xlib surface, the current matrix is just
a translation, the area to be drawn is clipped in a sufficiently simple
way, the operator is OVER, and certain other conditions hold, then we
pass the underlying X drawable through to the X-drawing code.
-- Otherwise if the X drawing is guaranteed to paint every pixel
opaquely, then we can create a temporary xlib surface, direct the
X-drawing to that surface, then copy the temporary surface to the
output.
-- Otherwise we apply the X drawing to two temporary surfaces, one with
a white background and one with a black background, and assuming that
the X-drawing code is equivalent to applying some ARGB image with
operator OVER, reconstruct the ARGB data by comparing the surface
pixels.

The latter two strategies can be quite slow --- especially the last one
--- so the API supports capturing the drawing results in a temporary
surface returned to the caller, which can be cached for later reuse.

I hope this functionality could be useful to other developers. For that
reason, and because it depends on nothing but cairo and X, and because
it requires access to cairo state that is currently internal, I think it
would be useful to have it part of cairo. However, because Carl seemed
reluctant to take it, we've implemented it outside of cairo for now:
http://lxr.mozilla.org/seamonkey/source/gfx/thebes/src/cairo-xlib-utils.h
http://lxr.mozilla.org/seamonkey/source/gfx/thebes/src/cairo-xlib-utils.c

To support this implementation, we have extended cairo in two ways:
-- Added a number of getter functions to extract properties of a cairo
xlib surface
-- Added cairo_extract_clip_rectangles to obtain the current clip in
device coordinates. If the clip cannot be expressed as rectangles, the
function simply gives up ... for our purposes, a non-rectangular clip is
useless anyway.
Patches for these extensions are attached --- please evaluate.

We will probably need broadly similar draw_with_hdc and draw_with_quartz
APIs in the future. On Windows we need to call HDC-drawing code to not
only render native themes, but also windowless plugins.

Rob
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cairo-xlib-getters.patch
Type: text/x-patch
Size: 4600 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20060223/700ee534/cairo-xlib-getters-0001.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cairo-clip-extract-rectangles.patch
Type: text/x-patch
Size: 11326 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20060223/700ee534/cairo-clip-extract-rectangles-0001.bin


More information about the cairo mailing list