[cairo] Pattern questions

Ian Britten britten at caris.com
Thu Sep 3 12:40:45 PDT 2009


Chris Wilson wrote:

> 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
> IRC.

I agree.  Unfortunately, it's blocked here at work ...  :(
I sometimes jump on at home, but I usually don't have my work then :P

>> 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.
[ snip ]

Yep, I agree on all points.  That's why I've been trying to get this
to work, rather than simply re-rendering the sprite at each position...

>> - 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.

Ok, good to hear!

>>    - 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.

Fair enough.  As long as my code will benefit from the improvements
when they become available, without a rewrite, I'm happy!

>> - 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.

Ok, I think I get it.  Here's what I ended up with (in my sample app),
to draw my sprites at each of the specific user positions:
         int userPosX = 105;
         int userPosY = 105;
         cairo_get_matrix(outputContext, &matrix);
         cairo_matrix_translate(&matrix,
                                -(userPosX - userOriginX),
                                -(userPosY - userOriginY));
         cairo_pattern_set_matrix(stencilPattern, &matrix);
         cairo_paint(outputContext);
and it seems to work.  (Critique away...)
[ Even better - I think I've got my 'real' code working! :) ]

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

Immensely!  Many thanks!
Ian



More information about the cairo mailing list