introduce drw_fontset_getwidth_clamp() 6be057f0
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().
NRK · 2022-03-24 02:00 2 file(s) · +18 −2
drw.c +17 −2
268 268
		return 0;
269 269
270 270
	if (!render) {
271 -
		w = ~w;
271 +
		w = invert ? invert : ~invert;
272 272
	} else {
273 273
		XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
274 274
		XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
300 300
301 301
					if (ew + tmpw > w) {
302 302
						overflow = 1;
303 -
						utf8strlen = ellipsis_len;
303 +
						/* called from drw_fontset_getwidth_clamp():
304 +
						 * it wants the width AFTER the overflow
305 +
						 */
306 +
						if (!render)
307 +
							x += tmpw;
308 +
						else
309 +
							utf8strlen = ellipsis_len;
304 310
					} else if (curfont == usedfont) {
305 311
						utf8strlen += utf8charlen;
306 312
						text += utf8charlen;
395 401
	if (!drw || !drw->fonts || !text)
396 402
		return 0;
397 403
	return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
404 +
}
405 +
406 +
unsigned int
407 +
drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
408 +
{
409 +
	unsigned int tmp = 0;
410 +
	if (drw && drw->fonts && text && n)
411 +
		tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
412 +
	return MIN(n, tmp);
398 413
}
399 414
400 415
void
drw.h +1 −0
35 35
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
36 36
void drw_fontset_free(Fnt* set);
37 37
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
38 +
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
38 39
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
39 40
40 41
/* Colorscheme abstraction */