Okay, you seem to be right. Before I upgraded my Ubuntu at the end of last year I did have this issue there, too. I can assure you that this /was/ a crash on Linux, and perhaps you've just had a more recent version of the relevant X libraries since I started on this list.
I know - for certain - that loaded screen fonts are still being closed, but that is no longer an error condition. It just slows things down a tiny bit. Assuming first that you do not have a font that handles Chinese Extended range E, this is my way to recreate. #Start st: #Four default "Source Code Pro" fonts loaded (three are default medium). #The array frc[] is empty. #The first block of echo statements will fill up frc[16], interestingly X simply re-loads the current default font when it cannot find a glyph. echo -e "\xf0\xab\xa0\xa0" echo -e "\xf0\xab\xa0\xa1" echo -e "\xf0\xab\xa0\xa2" echo -e "\xf0\xab\xa0\xa3" echo -e "\xf0\xab\xa0\xa4" echo -e "\xf0\xab\xa0\xa5" echo -e "\xf0\xab\xa0\xa6" echo -e "\xf0\xab\xa0\xa7" echo -e "\xf0\xab\xa0\xa8" echo -e "\xf0\xab\xa0\xa9" echo -e "\xf0\xab\xa0\xaa" echo -e "\xf0\xab\xa0\xab" echo -e "\xf0\xab\xa0\xac" echo -e "\xf0\xab\xa0\xad" echo -e "\xf0\xab\xa0\xae" echo -e "\xf0\xab\xa0\xaf" #Now frc[] has 16 open copies of "Source Code Pro". # #The next steps is tricker since everyone has a different fontconfig. Find two glyphs that you DO have fonts for, but are not represented in your default font. For me, "Place of Interest" works nicely. echo -e "\xe2\x8c\x98" # Now frc[15] has closed its unused "Source Code Pro", and instead has opened up "Segoe UI Symbol". # Since THAT copy of "Source Code Pro" isn't on screen this never caused harm. # (it was only held open to keep track of "\xf0\xab\xa0\xaf") # That means, though, that printing anything new that doesn't use an already open font will close # "Segoe UI Symbol" and open that new font. # Have some smiley shades echo -e "\xf0\x9f\x98\x8e" I hope that makes sense. Thanks, Gary On Wed, Mar 21, 2018 at 3:35 PM, Hiltjo Posthuma <hil...@codemadness.org> wrote: > On Wed, Mar 21, 2018 at 02:18:53PM -0400, Gary Allen Vollink wrote: >> This patch is over my previous simplification patch >> (https://lists.suckless.org/dev/1803/32601.html), though it could be >> reworked to go in without it. >> >> Problem: When working with text from many languages, it does not take long >> to run out of font slots for Runes that do not exist within any given >> fontconfig. Currently, each rune that is not part of a default set takes up >> another font slot (whether or not that rune is even found).I have found that >> runes in text (not emoji) have a tendency of showing up in sets, for >> instance a whole block of text may be in Cyrillic, which quickly takes up >> the 16 slots available for loaded fonts. This is fine until another rune IS >> found and put on screen. Whenever that happens, the next time a rune isn't >> found that font is closed and a new one inserted (whether or not that font >> includes the required glyph). Unloading an on-screen font at the next >> not-found rune will crash st. >> >> >> What I have is a partial Fix. This patch makes it take longer for this >> problem to manifest by making sure the limited font slots are not kept open >> when a glyph cannot be found. Note that this does not really help the issue >> on MacOS where the noglyph font will always claim a glyph (even though it's >> nothing but a binarybox). I haven't found a way to fix it completely (on >> MacOS and/or over long periods of usage on Linux) without writing something >> that even I think sucks. I personally got over this by /also/ adjusting the >> size of the frc[] array on my own build. Either way, this is what I have to >> offer... >> >> >> >> Patch: >> >> Track runes that are not found separately from the Fontcache, frc[], forget >> not-found runes in fifo, not lifo. Close an opened font if it doesn't >> include the required glyph (not taking up an frc[] slot). >> >> >> diff -U 3 -p a/x.c b/x.c >> --- a/x.c 2018-03-21 13:22:53.549236600 -0400 >> +++ b/x.c 2018-03-21 13:32:00.894134500 -0400 >> @@ -3,6 +3,7 @@ >> #include <math.h> >> #include <limits.h> >> #include <locale.h> >> +#include <wchar.h> >> #include <signal.h> >> #include <sys/select.h> >> #include <time.h> >> @@ -219,9 +220,12 @@ enum { >> typedef struct { >> XftFont *font; >> int flags; >> - Rune unicodep; >> } Fontcache; >> >> +/* Runes not found array. */ >> +static wchar_t noglyph[1024]; >> +static int noglyphlen = 0; >> + >> /* Fontcache is an array now. A new font will be appended to the array. */ >> static Fontcache frc[16]; >> static int frclen = 0; >> @@ -1145,7 +1149,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *sp >> float runewidth = win.cw; >> Rune rune; >> FT_UInt glyphidx; >> - int i, f, numspecs = 0; >> + int i, f, r, numspecs = 0; >> >> for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) { >> /* Fetch rune and mode for current glyph. */ >> @@ -1177,7 +1181,8 @@ xmakeglyphfontspecs(XftGlyphFontSpec *sp >> >> /* Lookup character index with default font. */ >> glyphidx = XftCharIndex(xw.dpy, font->match, rune); >> - if (glyphidx) { >> + /* OR if already failed to find a glyph for this rune. */ >> + if ((glyphidx) || (wmemchr(noglyph, rune, noglyphlen))) { >> specs[numspecs].font = font->match; >> specs[numspecs].glyph = glyphidx; >> specs[numspecs].x = (short)xp; >> @@ -1193,11 +1198,6 @@ xmakeglyphfontspecs(XftGlyphFontSpec *sp >> /* Everything correct. */ >> if (glyphidx && frc[f].flags == frcflags) >> break; >> - /* We got a default font for a not found glyph. */ >> - if (!glyphidx && frc[f].flags == frcflags >> - && frc[f].unicodep == rune) { >> - break; >> - } >> } >> >> /* Nothing was found. Use fontconfig to find matching font. >> */ >> @@ -1208,7 +1208,6 @@ xmakeglyphfontspecs(XftGlyphFontSpec *sp >> if (frclen >= LEN(frc)) { >> frclen = LEN(frc) - 1; >> XftFontClose(xw.dpy, frc[frclen].font); >> - frc[frclen].unicodep = 0; >> } >> >> /* >> @@ -1224,12 +1223,23 @@ xmakeglyphfontspecs(XftGlyphFontSpec *sp >> } >> frc[frclen].font = newFont.match; >> frc[frclen].flags = frcflags; >> - frc[frclen].unicodep = rune; >> >> glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, >> rune); >> >> - f = frclen; >> - frclen++; >> + if (!glyphidx) { >> + XftFontClose(xw.dpy, frc[frclen].font); >> + if (noglyphlen >= LEN(noglyph)) { >> + /* Get rid of the oldest not found >> rune */ >> + for (r=1; r <= LEN(noglyph); r++) { >> + noglyph[r-1] = noglyph[r]; >> + } >> + noglyphlen = LEN(noglyph) - 1; >> + } >> + noglyph[noglyphlen++] = rune; >> + } else { >> + f = frclen; >> + frclen++; >> + } >> } >> >> specs[numspecs].font = frc[f].font; >> >> >> > > I've never had this issue and cannot reproduce it all (still). Can you > provide more information? Recently there are some issues reported by users > using MacOS and st, this makes for wasted debugging sessions: MacOS and it's > ecosystem is not supported. > > There are also some code-style issues in the patch (newFont -> newfont name). > > -- > Kind regards, > Hiltjo >