[cairo] cairo_stroke_extents() with transformation matrix
andreas at airsoftsoftwair.de
Mon Feb 1 12:07:41 PST 2010
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:
>> how can I get cairo_stroke_extents() to take the current transformation
>> 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_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
>> of roughly 640 for x2 and roughly 480 for y2. Instead, it simply returns
>> 320 for x2 and about 240 for y2-- just as if there was no transformation
>> Is there a way to get cairo_stroke_extents() take the current
>> 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_scale(cr, 2, 2);
>cairo_rectangle(cr, 0, 0, 320, 240);
>cairo_stroke_extents(cr, &x1, &y1, &x2, &y2);
>Hope this helps, and you have fun using Cairo!
Yes, thanks, it's working now.
I'm still a little confused with transformations and user vs. device space,
though. What I want to do is fit the current path *exactly* to a surface,
ie. without any blank spaces on the sides. Optionally, scaling or rotation
shall be used. I'm doing this the following way:
1) Calculate current path dimensions using cairo_stroke_extents() with a
dummy surface of size 1x1 pixel.
2) Once I have the dimensions of the path, allocate a surface that is exactly
the same size as the current path.
3) Cut off any gaps on the left and top sides of the path. I do this by translating
the path to the top left corner like this:
cairo_stroke_extents(cr, &x1, &y1, &x2, &y2);
cairo_translate(cr, -x1, -y1);
4) Now draw the path using cairo_stroke().
If no scale or rotation matrix is present, this code works fine. The path is
positioned exactly at the top-left corner of the surface and fits pixel-perfect
to the bottom-right corner. However, as soon as I add scaling or rotation, the
translation does not work correctly. Presumably because of some problem
between user and device space that I'm unaware of. So how do I have to translate
the current path so that cairo_stroke() starts stroking exactly at the top-left corner
of my surface?
As I said, the surface is large enough to hold the current path but it seems I'm
currently passing the wrong translation coordinates...
"Remember: It's nice to be important but it's more important to be nice!"
More information about the cairo