From 78a3c399eeea485e696b40643b1fc5c94f8cafd9 Mon Sep 17 00:00:00 2001 From: bakkeby Date: Mon, 28 Mar 2022 10:53:35 +0200 Subject: [PATCH] introduce drw_fontset_getwidth_clamp() getting the width of a string is an O(n) operation, and in many cases users only care about getting the width upto a certain number. instead of calling drw_fontset_getwidth() and *then* clamping the result, this patch introduces drw_fontset_getwidth_clamp() function, similar to strnlen(), which will stop once we reach n. the `invert` parameter was overloaded internally to preserve the API, however library users should be calling drw_fontset_getwidth_clamp() and not depend upon internal behavior of drw_text(). ref. https://git.suckless.org/dmenu/commit/6be057f060543bb0f3ed9423904263617cdffffe.html --- drw.c | 30 +++++++++++++++++++++++++++--- drw.h | 2 ++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/drw.c b/drw.c index c8e65a8..f6a7a28 100644 --- a/drw.c +++ b/drw.c @@ -375,7 +375,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp return 0; if (!render) { - w = ~w; + w = invert ? invert : ~invert; } else { XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); @@ -447,7 +447,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp return 0; if (!render) { - w = ~w; + w = invert ? invert : ~invert; } else { XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); @@ -483,7 +483,13 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp if (ew + tmpw > w) { overflow = 1; - utf8strlen = ellipsis_len; + /* called from drw_fontset_getwidth_clamp(): + * it wants the width AFTER the overflow + */ + if (!render) + x += tmpw; + else + utf8strlen = ellipsis_len; } else if (curfont == usedfont) { utf8strlen += utf8charlen; text += utf8charlen; @@ -581,6 +587,15 @@ drw_font_getwidth(Drw *drw, const char *text, Bool markup) return 0; return drw_text(drw, 0, 0, 0, 0, 0, text, 0, markup); } + +unsigned int +drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) +{ + unsigned int tmp = 0; + if (drw && drw->font && text && n) + tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n, True); + return MIN(n, tmp); +} #else unsigned int drw_fontset_getwidth(Drw *drw, const char *text) @@ -589,6 +604,15 @@ drw_fontset_getwidth(Drw *drw, const char *text) return 0; return drw_text(drw, 0, 0, 0, 0, 0, text, 0); } + +unsigned int +drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) +{ + unsigned int tmp = 0; + if (drw && drw->fonts && text && n) + tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); + return MIN(n, tmp); +} #endif // PANGO_PATCH #if PANGO_PATCH diff --git a/drw.h b/drw.h index a51e6e3..af4af4d 100644 --- a/drw.h +++ b/drw.h @@ -58,11 +58,13 @@ void drw_free(Drw *drw); Fnt *drw_font_create(Drw* drw, const char font[]); void drw_font_free(Fnt* set); unsigned int drw_font_getwidth(Drw *drw, const char *text, Bool markup); +unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup); #else Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); void drw_fontset_free(Fnt* set); unsigned int drw_fontset_getwidth(Drw *drw, const char *text); +unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); #endif // PANGO_PATCH