Implementing HiDpi scaling

Federico Angelilli list at fedang.net
Wed Mar 20 13:32:58 UTC 2024


Thank you very much for the breakdown, I totally missed that cairo feature.

Am I right into thinking that the logical pixels don't need any calculation (apart from when comparing them to pixel information from X, like you said)? So that I just need to change the click handling and surface creation code

Also, should the size of the surface be (digital * ratio)? So the whole things looks like

1) get ratio from the monitor
2) create surface with size (digital * ratio)
3) set cairo device scale to (ratio)
4) write normally with digital
5) handle x11 events as (device / ratio)

Did I understood everything correctly?

Regards


On March 20, 2024 1:03:06 PM GMT+01:00, Emmanuele Bassi <ebassi at gmail.com> wrote:
>The way "high DPI" support is implemented is typically this:
>
>- You retrieve the scaling factor from the windowing system; in the case of
>X11 you can deduce the scaling factor from the ratio between the width and
>the height of the target monitor: anything below 192 is generally
>considered "1" and anything above is generally considered "2". If you want
>to go into fractional scaling territory, you'll likely need some other
>mechanism, like a user configuration setting.
>- Once you have a scaling factor, you create a windowing system surface
>that has two units:
>  1. device pixels, which are the physical pixels on the monitor
>  2. logical pixels, which are the scaled pixels for drawing operations
>
>Your surfaces have to be created with the size in device pixels; then you
>call cairo_surface_set_device_scale() with the scaling factor you computed:
>
>https://www.cairographics.org/manual/cairo-cairo-surface-t.html#cairo-surface-set-device-scale
>
>After that, every drawing operation must be in **logical** pixels, and the
>Cairo will automatically scale every coordinate and size appropriately.
>
>It is your responsibility to deal with device and logical coordinates; for
>instance, windowing system events will be in device coordinates, but if
>you're exposing their information to other code you will need to scale them
>appropriately.
>
>Ciao,
> Emmanuele.
>
>On Wed, 20 Mar 2024 at 11:47, Federico Angelilli <list at fedang.net> wrote:
>
>> Hello,
>> Sorry for the late reply.
>>
>> I am using cairo for drawing and pango for the text. I am creating a
>> window with xcb and using cairo_xcb_surface.
>>
>> I can easily extract the dpi information from the xrandr api calls. Now
>> that I have this ratio, I have to use it somewhere to scale my canvas
>> appropriately.
>>
>> I will try using cairo_scale, and should I also scale the size of the
>> xcb_surface by the same ratio?
>>
>> Anyway my main concern about antialising is that since I am making layered
>> shapes (think buttons) the border and the background will not match up
>> pixel perfect (which is something that I have seen in other project using
>> cairo).
>>
>> Does what I described about scaling the surface makes sense or am I
>> misinterpreting cairo_scale?
>>
>> Regards
>>
>> Ps:
>> I will soon try and post the results
>>
>>
>> On March 18, 2024 1:46:54 PM GMT+01:00, Dov Grobgeld <
>> dov.grobgeld at gmail.com> wrote:
>>
>>> I think that you should describe in detail what you expect.
>>>
>>> In pure vector graphics a contour may cut through a pixel and partially
>>> obscure it, and it is then the responsibility of the graphics engine to
>>> create anti-aliased graphics by mixing the colors of the background and the
>>> foreground. As a user you typically don't need to concern yourself with
>>> that as it is done automatically.
>>>
>>> However, e.g. for text this may cause "fuzzy" characters and the engine
>>> will then fallback to moving the contours and scale the font so that the
>>> glyphs fall on whole pixels.
>>>
>>> Note that the use of anti-aliased graphics is less needed, and less
>>> visible, for an HDPI device.
>>>
>>> In any case all that you will typically need is cairo_scale() as Uli
>>> Shlachter already described.
>>>
>>> Try it!
>>>
>>> Regards,
>>>
>>>
>>> On Sun, Mar 17, 2024 at 12:46 PM Federico Angelilli <list at fedang.net>
>>> wrote:
>>>
>>>> Hi
>>>>
>>>> Will cairo_scale make a pixel perfect image for non integer scales? To
>>>> my understanding the scale matrix will be multiplied to all the coordinates
>>>> scaling the coordinates appropriately. Should I also scale the whole
>>>> surface by that same factor?
>>>>
>>>> Regards
>>>>
>>>>
>>>> On March 16, 2024 6:27:56 PM GMT+01:00, Uli Schlachter <psychon at znc.in>
>>>> wrote:
>>>>
>>>>> Hi
>>>>>
>>>>> Am 14.03.24 um 16:34 schrieb fedang:
>>>>>
>>>>>> Hello all,
>>>>>>
>>>>>> I am writing a small X11 app using cairo as the drawing backend. I was wondering if and how to implement
>>>>>> fractional scaling to accommodate high dpi screens. After searching online I found almost nothing, so here I am.
>>>>>>
>>>>>> Can someone give me some pointers on what to do? I can get a scale factor for the screens (depending on the size)
>>>>>> but I have no idea how to actually use it in the draw code.
>>>>>>
>>>>>
>>>>> I'm not sure if I understand the question. You can use cairo_scale() to set a scale factor for all drawing. So I would say that you can just apply the scale factor with cairo_scale() before drawing.
>>>>>
>>>>> Of course, this assumes that you don't use cairo_identity_matrix() or cairo_set_matrix() in your drawing. Instead, cairo_save() and cairo_restore() should be used around temporary modifications of the transformations.
>>>>>
>>>>> Cheers,
>>>>> Uli
>>>>>
>>>>>
>
>-- 
>https://www.bassi.io
>[@] ebassi [@gmail.com]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.cairographics.org/archives/cairo/attachments/20240320/21d88dc0/attachment-0001.htm>


More information about the cairo mailing list