From 45c60de263ae00051248116ae6a272f6d9e7198b Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sun, 7 Apr 2024 03:26:16 -0400 Subject: [PATCH] common/font: avoid rendering semi-transparent background twice 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 --- scripts/checkpatch.pl | 11 ++--------- src/common/font.c | 31 +++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 14fdb88e..72368147 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -5655,15 +5655,8 @@ sub process { $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && #labwc-custom check to ignore some pango/libxml2/etc CamelCase variants - $var !~ /^(?:PangoLayout|PangoFontDescription)/ && - $var !~ /^(?:PangoTabArray|PangoRectangle)/ && - $var !~ /^(?:PangoWeight|_PangoFontDescription)/ && - $var !~ /^(?:xmlNode|xmlIsBlankNode|xmlAttr)/ && - $var !~ /^(?:xmlGetProp|xmlChar|xmlDoc)/ && - $var !~ /^(?:xmlReadFile|xmlDocGetRootElement)/ && - $var !~ /^(?:xmlFreeDoc|xmlCleanupParser)/ && - $var !~ /^(?:xmlParseMemory)/ && - $var !~ /^(?:xmlFree)/ && + $var !~ /^(?:_?Pango\w+)/ && + $var !~ /^(?:xml\w+)/ && $var !~ /^(?:GString|GError)/ && $var !~ /^(?:RsvgRectangle|RsvgHandle)/ && $var !~ /^(?:XKB_KEY_XF86Switch_VT_1)/ && diff --git a/src/common/font.c b/src/common/font.c index 88af3489..c9e6166c 100644 --- a/src/common/font.c +++ b/src/common/font.c @@ -115,13 +115,23 @@ font_buffer_create(struct lab_data_buffer **buffer, int max_width, cairo_surface_t *surf = cairo_get_target(cairo); /* - * Fill background color first - necessary for subpixel - * rendering, which does not work properly on transparency + * Fill with the background color first 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. + * + * Note: the 0.999 cutoff was chosen to be greater than 254/255 + * (about 0.996) but leave some margin for rounding errors. */ - set_cairo_color(cairo, bg_color); - cairo_rectangle(cairo, 0, 0, (*buffer)->unscaled_width, - (*buffer)->unscaled_height); - cairo_fill(cairo); + bool opaque_bg = (bg_color[3] > 0.999f); + if (opaque_bg) { + set_cairo_color(cairo, bg_color); + cairo_paint(cairo); + } set_cairo_color(cairo, color); cairo_move_to(cairo, 0, 0); @@ -131,6 +141,15 @@ font_buffer_create(struct lab_data_buffer **buffer, int max_width, pango_layout_set_text(layout, text, -1); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); + if (!opaque_bg) { + /* disable subpixel rendering */ + cairo_font_options_t *opts = cairo_font_options_create(); + cairo_font_options_set_antialias(opts, CAIRO_ANTIALIAS_GRAY); + PangoContext *ctx = pango_layout_get_context(layout); + pango_cairo_context_set_font_options(ctx, opts); + cairo_font_options_destroy(opts); + } + PangoFontDescription *desc = font_to_pango_desc(font); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); -- 2.52.0