bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#37932: [PATCH] Support hidpi fringes and images with Cairo


From: Carlos Pita
Subject: bug#37932: [PATCH] Support hidpi fringes and images with Cairo
Date: Fri, 25 Oct 2019 23:17:43 -0300

Here is a patch that takes a slightly different approach than my
previous one and fixes both fringe bitmaps and general image
(including "widgets": checkboxes, arrows, etc) rendering in hidpi
screens. I've attached a number of before/after screenshots.

I added two new fields `scale_x` and `scale_y` to the frame struct. I
believe going through the rif was overkilling in terms of indirections
and in terms of legibility, specially if I wanted to implement
independent scale factors for x and y in order to honour the previous
implementation. Now it's simply f->scale_x and f->scale_y. These
fields are initialized when the frame is created. They are floating
point numbers, truncation or rounding is done after scaling.

To be rigorous, these fields should belong to the terminal or to the
display_info, because they're common to all frames in the terminal
(indeed, they are closely related to resx and resy). But display_info
structs are backend specific and adding macros or inlines to frame.h
that reference them would have required including TERM_HEADER in many
many places. Also, having them at the frame level is handy since scale
factors are often, if not always, referenced in a context where a
frame is at scope.

The strategy is simple: scale fringe bitmaps and images geometries
beforehand, so as to allow geometry calculations, but postpone actual
scaling of the contents until the moment of their actual rendering to
screen. The image module has a lot of image loading functions. In
order to reduce the risk of regressions, I decided to adjust width and
height at the end of each function, immediately before returning.

Even if I've implemented this only for cairo (both with and without
gtk), adding support for x without cairo and for w32 shouldn't be
difficult at all. The ns backend simply sets both scale factors to 1,
thus disabling scaling. Other unsupported backends now should at least
carry better geometry computations, although contents won't be
actually scaled.

This doesn't support dynamic changes of dpi or scale factor. For two
or three days (and their nights) I strived to get that working. I was
able to catch xrandr resolution-change events, I was able to catch
scale-change gtk notifications, but the assumption that everything is
set just once at the beginning is firmly entrenched in the code. In
particular, rescaling fonts on the fly turned out to be an
insurmountable problem. I tried many, many things: clearing font
caches, glyph caches, matrix caches, resetting the frame font
parameter, remapping the default face (a la C-x C-+). I finally got it
working but only for the default face, I could have gone and remapped
also modeline faces, etc. I don't think such hacks are worth the
price.

In general, what people is doing to get x working with two monitors at
different dpis is to set a common gtk scale factor that is good for
the highest resolution screen (often = 2) and then scale the lowest
resolution screen down using xrandr. This is an old hack now
"officially" implemented in Ubuntu. So, if you launched  an emacs
frame in a hidpi laptop and then plugged an external monitor with the
same or lower resolution, there won't be any problem. Otherwise, if
your emacs frame started in the lowest resolution screen, then it
should be scaled up, so the only way to go is to close it and open a
frame afresh. Sorry for that.

So, all in all, this fixes hidpi problems and should also work in the
usual multi-monitor multi-dpi scenario. For a more comprehensive
solution I see no other way than writing a modern gtk backend, which
is also the way to move towards wayland.

Best regards
--
Carlos

Attachment: tetris-after.png
Description: PNG image

Attachment: widgets-after.png
Description: PNG image

Attachment: fringe-after.png
Description: PNG image

Attachment: tetris-before.png
Description: PNG image

Attachment: widgets-before.png
Description: PNG image

Attachment: fringe-before.png
Description: PNG image

Attachment: 0001-Support-hidpi-screens-with-cairo.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]