Krolyxon
Commit e63843d

Branches

Refs →

nsxive63843d

Simplify drawing of bar text

Non-fitting text is truncated by simply cutting it off.

win_textwidth() has been replaced by a simple macro wrapper around
win_draw_text() with a maximum width of zero, which results in a dry-run that
still calculates the number of pixels used by the text, much like snprintf(3)
with a buffer length of zero.
Author
Bert Münnich
Date
2017-12-07 21:29 +0100
Committer
Bert Münnich · 2017-12-07 21:29 +0100
Parent
3c7d6f3
Commit
e63843d36910308338e442f848c763a02b825933

+34 −53

1 file changed

  1. M window.c +34 −53
M window.c View
@@ -362,50 +362,45 @@ void win_clear(win_t *win)
362362 XFillRectangle(e->dpy, win->buf.pm, gc, 0, 0, win->buf.w, win->buf.h);
363363 }
364364
365−int win_textwidth(const win_env_t *e, const char *text, unsigned int len, bool with_padding, XftFont *fnt)
365+#define TEXTWIDTH(win, text, len) \
366+ win_draw_text(win, NULL, NULL, 0, 0, text, len, 0)
367+
368+int win_draw_text(win_t *win, XftDraw *d, XftColor *color, int x, int y,
369+ char *text, int len, int w)
366370 {
371+ int err, tw = 0;
372+ char *t, *next;
373+ uint32_t rune;
374+ XftFont *f;
375+ FcCharSet *fccharset;
367376 XGlyphInfo ext;
368377
369− XftTextExtentsUtf8(e->dpy, fnt, (XftChar8*)text, len, &ext);
370− return ext.xOff + (with_padding ? 2 * H_TEXT_PAD : 0);
371−}
372−
373−void win_draw_bar_text(win_t *win, XftDraw *d, XftColor *color, XftFont *font, int x, int y, char *text, int maxlen, int maximum_x)
374−{
375− size_t len = 0;
376− int err, xshift = 0, newshift;
377− uint32_t codep;
378− char *p, *nextp;
379− FcCharSet* fccharset;
380− XftFont* fallback = NULL;
381−
382− for (p = text; *p && (len < maxlen); p = nextp, len++) {
383− nextp = utf8_decode(p, &codep, &err);
384− if (!XftCharExists(win->env.dpy, font, codep)) {
378+ for (t = text; t - text < len; t = next) {
379+ next = utf8_decode(t, &rune, &err);
380+ if (XftCharExists(win->env.dpy, font, rune)) {
381+ f = font;
382+ } else { /* fallback font */
385383 fccharset = FcCharSetCreate();
386− FcCharSetAddChar(fccharset, codep);
387− fallback = XftFontOpen(win->env.dpy, win->env.scr,
388− FC_CHARSET, FcTypeCharSet, fccharset,
389− FC_SCALABLE, FcTypeBool, FcTrue,
390− NULL);
384+ FcCharSetAddChar(fccharset, rune);
385+ f = XftFontOpen(win->env.dpy, win->env.scr, FC_CHARSET, FcTypeCharSet,
386+ fccharset, FC_SCALABLE, FcTypeBool, FcTrue, NULL);
391387 FcCharSetDestroy(fccharset);
392388 }
393− newshift = win_textwidth(&win->env, p, (int) (nextp-p), false, (fallback ? fallback : font));
394− if (xshift + newshift <= maximum_x)
395− XftDrawStringUtf8(d, color, (fallback ? fallback : font), x + xshift, y, (XftChar8*)p, (int) (nextp-p));
396− xshift += newshift;
397− if (fallback) {
398− XftFontClose(win->env.dpy, fallback);
399− fallback = NULL;
389+ XftTextExtentsUtf8(win->env.dpy, f, (XftChar8*)t, next - t, &ext);
390+ tw += ext.xOff;
391+ if (tw <= w) {
392+ XftDrawStringUtf8(d, color, f, x, y, (XftChar8*)t, next - t);
393+ x += ext.xOff;
400394 }
395+ if (f != font)
396+ XftFontClose(win->env.dpy, f);
401397 }
398+ return tw;
402399 }
403400
404401 void win_draw_bar(win_t *win)
405402 {
406− int len, olen, x, y, w, tw, maximum_x;
407− char rest[3];
408− const char *dots = "...";
403+ int len, x, y, w, tw;
409404 win_env_t *e;
410405 win_bar_t *l, *r;
411406 XftDraw *d;
@@ -415,7 +410,7 @@ void win_draw_bar(win_t *win)
415410
416411 e = &win->env;
417412 y = win->h + font->ascent + V_TEXT_PAD;
418− w = win->w;
413+ w = win->w - 2*H_TEXT_PAD;
419414 d = XftDrawCreate(e->dpy, win->buf.pm, DefaultVisual(e->dpy, e->scr),
420415 DefaultColormap(e->dpy, e->scr));
421416
@@ -426,30 +421,16 @@ void win_draw_bar(win_t *win)
426421 XSetBackground(e->dpy, gc, win->bar.bgcol.pixel);
427422
428423 if ((len = strlen(r->buf)) > 0) {
429− if ((tw = win_textwidth(e, r->buf, len, true, font)) > w)
424+ if ((tw = TEXTWIDTH(win, r->buf, len)) > w)
430425 return;
431− x = win->w - tw + H_TEXT_PAD;
426+ x = win->w - tw - H_TEXT_PAD;
432427 w -= tw;
433− XftDrawStringUtf8(d, &win->bar.fgcol, font, x, y, (XftChar8*)r->buf, len);
428+ win_draw_text(win, d, &win->bar.fgcol, x, y, r->buf, len, tw);
434429 }
435430 if ((len = strlen(l->buf)) > 0) {
436− olen = len;
437− while (len > 0 && (tw = win_textwidth(e, l->buf, len, true, font)) > w)
438− len--;
439− if (len > 0) {
440− maximum_x = w;
441− if (len != olen) {
442− w = strlen(dots);
443− if (len <= w)
444− return;
445− memcpy(rest, l->buf + len - w, w);
446− memcpy(l->buf + len - w, dots, w);
447− }
448− x = H_TEXT_PAD;
449− win_draw_bar_text(win, d, &win->bar.fgcol, font, x, y, l->buf, len, maximum_x);
450− if (len != olen)
451− memcpy(l->buf + len - w, rest, w);
452− }
431+ x = H_TEXT_PAD;
432+ w -= 2 * H_TEXT_PAD; /* gap between left and right parts */
433+ win_draw_text(win, d, &win->bar.fgcol, x, y, l->buf, len, w);
453434 }
454435 XftDrawDestroy(d);
455436 }