[cairo] cairo_stroke_extents() with transformation matrix

Andreas Falkenhahn andreas at airsoftsoftwair.de
Tue Feb 2 06:49:20 PST 2010


On 02.02.2010 at 09:38 Behdad Esfahbod wrote:

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

Hmm, so is there no way of finding out the exact output dimensions of
a stroked/filled path before drawing it?

Greets,

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




More information about the cairo mailing list