On Tue, Mar 29, 2022 at 05:18:12PM +0200, Stein Gunnar Bakkeby wrote:
> For 0002 how about leaving the ellipsis_width as 0 and do this?
> 
> if (!ellipsis_width && render)
>     ellipsis_width = drw_fontset_getwidth(drw, ellipsis);

When invoked from drw_fontset_getwidth(), `render` wont be active, so
yeah this will get rid of the infinite recursion as well. And
ellipsis_width is only relevant when rendering, so it makes sense to do
it this way.

In fact, I think just reducing the condition to `if (render)` and
reverting ellipsis_width to be automatic variable again would work as
well. But since ellipsis_width won't change, makes sense to make it
static and calculate it only once.

> Moving the "..." to a static(?) const variable named ellipsis would make it
> easier to replace this with something else (like the ellipsis character for
> example).

Currently it's used only in 2 locations, so don't think it should be
hard for someone to change it if they wish.

Attached the amended patches.

- NRK
>From cdf867f85a2aef1d43c0e1313d788646477884ab 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: don't segfault when called with 0 width

this patch just rejects *any* 0 width draws, which is surely an error by
the caller.

this also guards against cases where the width is too small for the
ellipsis to fit, so 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 a50c9ee..2f3a5df 100644
--- a/drw.c
+++ b/drw.c
@@ -267,7 +267,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
 	enum { nomatches_len = 64 };
 	static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches;
 
-	if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
+	if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
 		return 0;
 
 	if (!render) {
-- 
2.35.1

>From 5c4f072aef6c7e52f02dc421c164e5d3401174f2 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

additionally, ellipsis_width (which shouldn't change) is made static to
avoid re-calculating it on each drw_text() call.
---
 drw.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drw.c b/drw.c
index 2f3a5df..ced7d37 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 unsigned int ellipsis_width = 0;
 
 	if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
 		return 0;
@@ -283,7 +284,8 @@ 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 && render)
+		ellipsis_width = drw_fontset_getwidth(drw, "...");
 	while (1) {
 		ew = ellipsis_len = utf8strlen = 0;
 		utf8str = text;
-- 
2.35.1

Reply via email to