[dev] [st][bug] Font fallback fails on some systems

From: Sergei Grechanik <Sergei.Grechanik_AT_gmail.com>
Date: Sat, 22 Jun 2024 11:08:44 -0700

I've recently upgraded my system and noticed that many Unicode
characters are no longer displayed in st, although other applications
were unaffected. After some investigation, I found that it's a font
fallback failure: the font returned by FcFontSetMatch lacked the
character requested via the charset. Apparently, this is possible if
the pattern is nonsensical, in my case, the pattern was something like
this (simplified):

    JetBrainsMonoNerdFontMono:charset=2807:lang=und-zsye,en

U2807 is a Braille character, for which st needed a fallback. The
lang=und-zsye is for emojis. This combination confused fontconfig and
it returned 'Noto Color Emoji', which doesn't contain Braille
characters (although I still find it strange that fontconfig doesn't
prioritize the charset).
I propose two possible solutions for this:

1) Fix the pattern. "lang=und-zsye" was added to the pattern by a call
to FcConfigSubstitute. On my system there are some fontconfig rules
that eventually add emoji fonts to every pattern. Although these rules
may be buggy, other applications were not affected, indicating that st
does something differently. I think the difference is that it calls
FcConfigSubstitute twice: the first time when it searches for the main
font and the second time when it searches for the fallback font. It's
the second call that makes the pattern nonsensical. My guess is that
calling it twice is not correct. This patch removes the second call
and fixes the issue:

diff --git a/x.c b/x.c
index bd23686..639b06b 100644
--- a/x.c
+++ b/x.c
_AT_@ -1330,8 +1330,6 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs,
const Glyph *glyphs, int len, int x
                                        fccharset);
                        FcPatternAddBool(fcpattern, FC_SCALABLE, 1);

- FcConfigSubstitute(0, fcpattern,
- FcMatchPattern);
                        FcDefaultSubstitute(fcpattern);

                        fontpattern = FcFontSetMatch(0, fcsets, 1,


2) Explicitly verify whether the fallback font contains the character
(I think, xterm does something like this). Please find the patch in
the attachment.

Please consider applying one or both of these patches to the mainline
(or addressing the issue in some other way). Note that I have no prior
experience with fontconfig, so I don't really know what I'm doing, and
the patches may require some modifications.

Received on Sat Jun 22 2024 - 20:08:44 CEST

This archive was generated by hypermail 2.3.0 : Sat Jun 22 2024 - 22:00:09 CEST