On Mon, Mar 28, 2022 at 05:57:48PM +0600, NRK wrote:
> And on the topic of ellipsis_width, we currently don't account for
> fallback font:
> 
>       usedfont = drw->fonts;
>       drw_font_getexts(usedfont, "...", 3, &ellipsis_width, NULL);
> 
> The assumption here was that every font should have '.' but if that
> turns out to be wrong, then the font width will be incorrect.

Attached a patch fixing this issue, as well as a patch guarding against
calling drw_text() with 0 width.

Think both these issues should be extremely rare, but can't hurt dealing
with them anyways.

- NRK
>From 7c22fb59aedea1e7d65b1a8ef729dccd631a4364 Mon Sep 17 00:00:00 2001
From: NRK <[email protected]>
Date: Mon, 28 Mar 2022 01:02:52 +0600
Subject: [PATCH 1/2] drw_text: guard against 0 ellipsis_w

if the width is too small for the ellipsis to fit, ellipsis_w will
remain 0.

reported by Bakkeby <[email protected]>
---
 drw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drw.c b/drw.c
index 4cccf47..411bcdd 100644
--- a/drw.c
+++ b/drw.c
@@ -336,7 +336,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
 			x += ew;
 			w -= ew;
 		}
-		if (render && overflow)
+		if (render && overflow && ellipsis_w)
 			drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
 
 		if (!*text || overflow) {
-- 
2.35.1

>From 20a9736ea91a9801a6da3a6f829976e7d59a3a32 Mon Sep 17 00:00:00 2001
From: NRK <[email protected]>
Date: Mon, 28 Mar 2022 21:38:49 +0600
Subject: [PATCH 2/2] drw_text: account for fallback fonts in ellipsis_width

this required using a static variable to stop infinite recursion.

as a side-effect, we now avoid doing some unneeded work by calculating
ellipsis_width (which shouldn't change) only once instead of calculating
it on each drw_text() call.
---
 drw.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drw.c b/drw.c
index 411bcdd..96d868d 100644
--- a/drw.c
+++ b/drw.c
@@ -252,7 +252,7 @@ int
 drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
 {
 	int i, ty, ellipsis_x = 0;
-	unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, ellipsis_width;
+	unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
 	XftDraw *d = NULL;
 	Fnt *usedfont, *curfont, *nextfont;
 	int utf8strlen, utf8charlen, render = x || y || w || h;
@@ -266,6 +266,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
 	/* keep track of a couple codepoints for which we have no match. */
 	enum { nomatches_len = 64 };
 	static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches;
+	static int ellipsis_width = -1;
 
 	if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
 		return 0;
@@ -283,7 +284,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
 	}
 
 	usedfont = drw->fonts;
-	drw_font_getexts(usedfont, "...", 3, &ellipsis_width, NULL);
+	if (ellipsis_width < 0) {
+		ellipsis_width = 0; /* stop infinite recursion */
+		ellipsis_width = drw_fontset_getwidth(drw, "...");
+	}
 	while (1) {
 		ew = ellipsis_len = utf8strlen = 0;
 		utf8str = text;
-- 
2.35.1

Reply via email to