lab_data_buffer->logical_{width,height} are not the actual size of the
backing buffer, so wlr_buffer.{width,height} should be used when
duplicating it in get_cairo_surface_from_lab_data_buffer().
This mistake caused segfault when an icon file 1~2 times larger than
window.button.{width,height} is loaded, because the buffer for the raw
icon file is reused by setting lab_data_buffer->logical_{width,height}
with the size for display which is different from
wlr_buffer.{width,height} (see buffer_convert_cairo_surface_for_icon()),
and it is duplicated with get_cairo_surface_from_lab_data_buffer() for
hovered/rounded variants of titlebar button.
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).
wlr_scene_rects expect their color to be pre-multiplied
while cairo_set_source_rgba() expects them to not be
pre-multiplied. With this patch we now use premultiplied
colors internally by default and then reverse it when
setting cairo colors.
This ensures the titlebar uses a consistent color in case
it was defined with some transparency by the user.
Fixes: #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