[hackers] [libsl][PATCH] Workaround Xft BadLength X error

From: Thomas Spurden <thomas_AT_spurden.name>
Date: Wed, 16 Jan 2019 21:51:30 +0000

Modify the fontconfig pattern to prefer non-color fonts, and discard any
selected font which has the color flag set. Using these fonts with Xft is just
going to generate a BadLength X error.

---
 drw.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
The internet has lots of reports of this, sounds like it might be a bug in Xft?
Anyway, it's super annoying to have your window manager crash due to the
characters in the window title!
This has been reported several times on the suckless lists e.g.
https://lists.suckless.org/dev/1610/30710.html
https://lists.suckless.org/dev/1608/30245.html
Searching the internet for "Xft BadLength" pulls up lots of bugs in various
sofware packages which use Xft. Xterm implemented something similar to the
attached patch in version 314.
There are several recommendations of just uninstalling the color fonts (usually
seem to be the noto emoji font) e.g.
https://wiki.archlinux.org/index.php/dwm#Crashes_due_to_Emojis_in_some_fonts
That just seems like a poor solution to me!
For the record this error can be easily reproduced with
> echo -e '\xf0\x9f\x8e\xa5\x20\x56'|dmenu
(dmenu built from latest git with no modifications) assuming you have a color
emoji font installed and fontconfig selects it. Have a look through the output
of
> fc-match -s monospace
and see if you have 'Noto Color Emoji' in there (I have it second to last).
diff --git a/drw.c b/drw.c
index c1582e7..8fd1ca4 100644
--- a/drw.c
+++ b/drw.c
_AT_@ -132,6 +132,19 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
 		die("no font specified.");
 	}
 
+	/* Do not allow using color fonts. This is a workaround for a BadLength
+	 * error from Xft with color glyphs. Modelled on the Xterm workaround. See
+	 * https://bugzilla.redhat.com/show_bug.cgi?id=1498269
+	 * https://lists.suckless.org/dev/1701/30932.html
+	 * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
+	 * and lots more all over the internet.
+	 */
+	FcBool iscol;
+	if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
+		XftFontClose(drw->dpy, xfont);
+		return NULL;
+	}
+
 	font = ecalloc(1, sizeof(Fnt));
 	font->xfont = xfont;
 	font->pattern = pattern;
_AT_@ -337,6 +350,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
 			fcpattern = FcPatternDuplicate(drw->fonts->pattern);
 			FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
 			FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
+			FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
 
 			FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
 			FcDefaultSubstitute(fcpattern);
-- 
2.20.1
Received on Wed Jan 16 2019 - 22:51:30 CET

This archive was generated by hypermail 2.3.0 : Wed Jan 16 2019 - 23:00:21 CET