[cairo] cairo_stroke_extents() with transformation matrix

Behdad Esfahbod behdad at behdad.org
Tue Feb 2 06:38:17 PST 2010


On 02/02/2010 09:20 AM, Andreas Falkenhahn wrote:
> On 01.02.2010 at 16:56 Chris Wilson wrote:
> 
>> On Mon, 01 Feb 2010 17:35:25 +0100, "Andreas Falkenhahn"
>> <andreas at airsoftsoftwair.de> wrote:
>>>
>>> Hi,
>>>
>>> how can I get cairo_stroke_extents() to take the current transformation
>> matrix
>>> into account? I.e. please consider the following code:
>>>
>>> // scale * 2 on both axes
>>> cairo_matrix_init(&m, 2, 0, 0, 2, 0, 0);
>>>
>>> cairo_set_matrix(cr, &m);
>>> cairo_new_path(cr);
>>> cairo_rectangle(cr, 0, 0, 320, 240);	
>>> cairo_stroke_extents(cr, &x1, &y1, &x2, &y2);
>>>
>>> I'd expect that cairo_stroke_extents() would return something in the
>> range
>>> of roughly 640 for x2 and roughly 480 for y2. Instead, it simply returns
>> about
>>> 320 for x2 and about 240 for y2-- just as if there was no transformation
>> at all.
>>>
>>> Is there a way to get cairo_stroke_extents() take the current
>> transformation
>>> matrix into account?
>>
>> Ab, but it is. It is transforming the extents of the path from device to
>> user space using the current transformation matrix. For your purposes, you
>> actually want to know the device extents, and so should set an identity
>> transformation when querying the extents.
>>
>> cairo_save(cr);
>> cairo_scale(cr, 2, 2);
>> cairo_new_path(cr);
>> cairo_rectangle(cr, 0, 0, 320, 240);	
>> cairo_restore(cr);
>> cairo_stroke_extents(cr, &x1, &y1, &x2, &y2);
>>
>> Hope this helps, and you have fun using Cairo!
> 
> Hmm, now I'm confused. Please consider the following code:
> 
> cairo_new_path(cr);
> cairo_set_line_width(cr, 10);
> cairo_rectangle(cr, 0, 0, 320, 240);
> cairo_stroke_extents(cr, &x1, &y1, &x2, &y2);
> 	
> printf("NORMAL: %.14g %.14g %.14g %.14g\n", x1, y1, x2, y2);
> 	
> cairo_save(cr);
> cairo_scale(cr, 2, 2);
> cairo_new_path(cr);
> cairo_set_line_width(cr, 10);
> cairo_rectangle(cr, 0, 0, 320, 240);	
> cairo_restore(cr);
> cairo_stroke_extents(cr, &x1, &y1, &x2, &y2);
> 
> printf("TRANSFORMED: %.14g %.14g %.14g %.14g\n", x1, y1, x2, y2);
> 
> The first one prints:
> 
> NORMAL: -5 -5 325 245
> 
> And the second one prints:
> 
> TRANSFORMED: -5 -5 645 485
> 
> But shouldn't the second one print 
> 
> -5 -5 655 495
> 
> ?? ... I mean, because I'm scaling by two on both axes. It seems as
> if cairo_stroke_extents() doesn't scale the line width but when I draw it using
> cairo_stroke() the line width has been scaled and is 20px wide/high. Any
> ideas?

Unfortunately right now the stroke width is interpreted at the time of (and in
the space of) the cairo_stroke() command.  You can replace your
cairo_stroke_extents() with cairo_stroke() to see what I mean.

There has been a proposal to lock the pen space at the time of
set_line_width(), but that has not been accepted/implemented yet.

behdad


> Thanks,
> 
> Andreas
> --
> "Remember: It's nice to be important but it's more important to be nice!"
> 
> 


More information about the cairo mailing list