[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