This is a common practice in C projects, which simply enforces that
each header must compile cleanly without implicit dependencies on
other headers (see also the previous commit).
Prior to this commit, a backing buffer with scale 1 was always created for
a scaled_scene_buffer before showing it, and backing buffers for specific
scales were created on output_enter events.
This commit removes this redundant re-renderings by calling
wlr_scene_buffer_set_dest_size() upon scaled_scene_buffer creation just to
receive output_enter events and delaying the first rendering to the first
output_enter event.
I needed to add font_get_buffer_size() to obtain the size of a font buffer
without actually creating it.
Arrow signs are specific to submenu items, so they would be more natural
to be handled in menu.c rather than accepting "arrow" in
font_buffer_create().
Also I allowed non-positive numbers for max_width in font_buffer_create(),
in which case the natural font width is used as the buffer width.
Add buffer_adopt_cairo_surface(), which allows wrapping an existing
cairo image surface in a struct lab_data_buffer. This is useful when
loading PNGs since most will be loaded as ARGB32 already.
Fix a memory leak in the non-ARGB32 PNG case, where we do still need to
paint to a new image surface -- we were leaking the original surface.
Eliminate an unnecessary temporary image surface in SVG loading and just
render the SVG to the image surface held by the lab_data_buffer.
I also cleaned up and clarified the buffer API a bit:
- Add a pointer to the held cairo_surface_t (so we can still access it
if there is no cairo_t).
- Remove the free_on_destroy bool (it was always true).
- Rename unscaled_width/height to logical_width/height and add an
explanatory comment. It was unclear what "unscaled" meant.
- Rename buffer_create_wrap() to buffer_create_from_data().
This is laying groundwork for some more icon fixes I am working on
(making sure icons are loaded and rendered at the correct scale).
Chase 8c5b23e592
Pango rounds glyph position and widths to nearest integer, which leads to
font dimensions jumping around when rendering with a scale, causing text
geometry to jump around when changing scale.
Disable this rounding to make the geometry stable.
Fill with the background color first only if the background color is
opaque. This is necessary for subpixel rendering to work properly (it
does not work on top of transparency).
However, if the background color is not opaque, leave the buffer
unfilled (completely transparent) since the background is already
rendered by the scene element underneath. In this case we have to
disable subpixel rendering.
v2: use 0.999 alpha cutoff and fix CodeStyleCheck
Fixes: (the rest of) #1684
After a roundabout discussion[1] with wlroots devs, it's become apparent
that subpixel text rendering (a.k.a. "ClearType") does not work properly
when rendering over a transparent background, as labwc currently does.
Basically it comes down to the fact that the color of semi-transparent
pixels (which is adjusted redder or bluer to compensate for RGB subpixel
alignment) depends somewhat on background color. When rendering over
transparency, the text engine doesn't know the intended background color
and can't adjust the pixel colors correctly.
With Pango/Cairo, the end result can range from grayscale rendering (no
subpixel rendering at all) to wrong/oversaturated colors (for example,
bright pink pixels when rendering white text on blue background).
This change solves the issue by first filling the text buffer with an
opaque background color before rendering the text over it. Currently,
this is easy since the background is always a solid color. It may be a
little more complex (but doable) if we implement gradients in future.
Note that GTK 4 (and to some degree, recent versions of Microsoft
Windows) avoid this issue by disabling subpixel rendering altogether. I
would much prefer that labwc NOT do this -- it results in noticeably
blurrier text on non-retina LCD screens, which are still common.
[1] https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3822
Move font_texture_create() to font.c so it can be used for purposes other
than rendering the menu, for example server side decoration.
Refactor menu.c and menu.h to use this more generic font_texture_create()