[cairo] Pattern questions

Chris Wilson chris at chris-wilson.co.uk
Thu Sep 3 11:13:40 PDT 2009

Excerpts from Ian Britten's message of Thu Sep 03 14:32:02 +0100 2009:
> Hi all,
>     [ cairo 1.8.8 ]
> I'm trying to do some basic work with patterns, and I was hoping
> someone could clarify a couple of things:

For quick questions like these you may find it easier to use IRC, #cairo
on irc.freenode.net. We lose the advantage of archiving the question and
answers, but, on the other hand, we may be able to help you better over

> My goal:
> - Make a pattern (stencil), and use it to draw multiple times at
>    multiple user positions on my output surface.  The result should
>    work for any surface type (But primarily Image and PDF).
> My concerns:
> - Correctness (and performance)
> - Positioning

Using a sprite or a stencil will be much faster than redrawing a complex
geometry each time, especially if it involves many layers and expensive
effects. (I differ between sprite and stencil in terms of application. A
sprite is a full-colour pattern that we can simply blit to the
destination, whereas I regard a stencil as a masking operation and
requires another source.) The complication is down to sub-pixel
rendering. Obviously, if you re-render each time, the geometry will be
computed with the appropriate sub-pixel accuracy. In order to achieve a
similar effect you could pre-compute a few sub-pixel positions and
choose the appropriate one when applying the stencil. On the other hand,

> Attached is a basic sample that I'm working with.  In it, I can
> create my pattern/stencil correctly, and it looks correct when
> I save it to PNG (That's a handy feature, BTW!)
> Also, I can get it to draw, but, well...
> - Is cairo_paint() the correct (and efficient) way to draw each
>    pattern?  I had initially been trying to use move_to()/stroke()
>    but obviously that didn't work.

Yes cairo_paint() is the correct (and efficient) method of applying one
surface to another. How many pixels that are written to actually depends
upon the operator, but, for example, using OVER the operation will be
bounded to the smallest affected region (presumably the visible part of
the stencil). This region can be reduced further by use of a clip region
(though for the sake of performance make sure the clip is device-space

>    - I seem to recall discussions about embedding+reusing patterns
>      in some output surfaces (PDF?), and wasn't sure if using paint()
>      would result in that being done (Assuming it actually is done).

Yes, but pattern reuse is only available in the 1.10 release (you can
test it in the 1.9.2 snapshot). Snapshotting of patterns is not limited
to paint, but applies to any use of the pattern.

> - Can someone describe (or point me to) some info about positioning
>    the patterns?  Especially about where their initial position is.

This is perhaps the most fundamental part of Cairo's design, everything
(apart from pens, grr!) is set at the time of setting onto the context.
In other words, the pattern matrix is set from the current
transformation matrix at the time of the cairo_set_source() call. All
subsequent transformations will not alter the position of the source in
device space. To do that, you will need to either manipulate the pattern
matrix yourself or reset the source.

Hope this helps, and you continue to have fun with Cairo!

More information about the cairo mailing list