[cairo] How to get extents of transformed graphics
Uli Schlachter
psychon at znc.in
Sun Sep 18 16:49:39 UTC 2022
Am 18.09.22 um 18:39 schrieb Michal Sudolsky:
> On Sun, Sep 18, 2022 at 10:52 AM Uli Schlachter <psychon at znc.in> wrote:
>
>> Hi,
>>
>> Am 17.09.22 um 15:31 schrieb Andreas Falkenhahn:
>>> On 17.09.2022 at 13:47 Uli Schlachter wrote:
>> [...]
>>> It's a bit frustrating that nobody corrected this misconception because I
>>> actually started my very first email on 28th August with it. I wrote:
>>>
>>> "Is there any way to get the *exact* extents of transformed graphics?
>> AFAICS,
>>> cairo_fill_extents() is in user coordinates, i.e. it doesn't take any
>> transformation
>>> settings into account."
>>>
>>> If someone had just said "Hey, cairo_fill_extents() *does* take the
>> transformation
>>> settings into account" it would have spared me a lot of trouble :-(
>>
>> Sorry for that. I am (currently - I guess also back then)
>> misunderstanding this question as what the attached example
>> demonstrates. The "exact" made me think you meant this.
>>
>> Left part of the image: A rectangle and its extents according to
>> cairo_path_extents().
>> Right part: The same thing, but with the user coordinate space rotated
>> by 45°.
>>
>> To everyone who wonders what is going on: Cairo internally works in
>> device space. All translation from user to device space is done at the
>> API boundary. Thus, cairo_path_extents() internally gets the extents in
>> device space. This describes a rectangle. This rectangle is then
>> translated to user space.
>
>
>
>> Thus, the white rectangle in the image would
>> be "exact" if I had drawn a rectangle instead of a circle.
>>
>
> I changed line with "cairo_arc(cr, 50, 50, 20, 0, 2 * M_PI);" to
> "cairo_rectangle(cr, 30, 30, 40, 40);" and got this:
>
> [image: tmp.png]
>
> I do not understand why white rectangle here is even bigger.
Heh. I shouldn't have picked a circle. :-)
Cairo internally computes things in device space. Thus, it has the white
rectangle on the left (well, okay, things are slightly bigger than that,
but from the idea it is close to the white rectangle on the left).
Then it has to translate things to user space. This code only gets the
white rectangle as its input and then transforms this, resulting in the
right rectangle on the right.
TL;DR: The code over-approximates things when applying the
transformation matrix.
Attached is another example demonstrating this. The red rectangle show
the extents of the image in device space. This describes the extents of
the actual image tightly. cairo_path_extents() then uses the extents of
this red rectangle transformed to user space as its result value. This
produces the green rectangle. The green rectangle is also tightly, but
it is tight to the red rectangle and not the actual drawing.
Cheers,
Uli
--
- He made himself, me nothing, you nothing out of the dust
- Er machte sich mir nichts, dir nichts aus dem Staub
-------------- next part --------------
A non-text attachment was scrubbed...
Name: tmp.png
Type: image/png
Size: 1495 bytes
Desc: not available
URL: <https://lists.cairographics.org/archives/cairo/attachments/20220918/d42cee09/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.c
Type: text/x-csrc
Size: 1456 bytes
Desc: not available
URL: <https://lists.cairographics.org/archives/cairo/attachments/20220918/d42cee09/attachment.c>
More information about the cairo
mailing list