summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBert Münnich <ber.t@posteo.de>2017-12-07 21:29:41 +0100
committerBert Münnich <ber.t@posteo.de>2017-12-07 21:29:44 +0100
commite63843d36910308338e442f848c763a02b825933 (patch)
tree37a316d872ed5debdc4080e19f62d63ae4f50988
parent3c7d6f3528432a433cd368605e4dc6f0fecaa898 (diff)
downloadnsxiv-e63843d36910308338e442f848c763a02b825933.tar.zst
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.
-rw-r--r--window.c87
1 files changed, 34 insertions, 53 deletions
diff --git a/window.c b/window.c
index b2d72d1..8c233d8 100644
--- a/window.c
+++ b/window.c
@@ -362,50 +362,45 @@ void win_clear(win_t *win)
XFillRectangle(e->dpy, win->buf.pm, gc, 0, 0, win->buf.w, win->buf.h);
}
-int win_textwidth(const win_env_t *e, const char *text, unsigned int len, bool with_padding, XftFont *fnt)
+#define TEXTWIDTH(win, text, len) \
+ win_draw_text(win, NULL, NULL, 0, 0, text, len, 0)
+
+int win_draw_text(win_t *win, XftDraw *d, XftColor *color, int x, int y,
+ char *text, int len, int w)
{
+ int err, tw = 0;
+ char *t, *next;
+ uint32_t rune;
+ XftFont *f;
+ FcCharSet *fccharset;
XGlyphInfo ext;
- XftTextExtentsUtf8(e->dpy, fnt, (XftChar8*)text, len, &ext);
- return ext.xOff + (with_padding ? 2 * H_TEXT_PAD : 0);
-}
-
-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)
-{
- size_t len = 0;
- int err, xshift = 0, newshift;
- uint32_t codep;
- char *p, *nextp;
- FcCharSet* fccharset;
- XftFont* fallback = NULL;
-
- for (p = text; *p && (len < maxlen); p = nextp, len++) {
- nextp = utf8_decode(p, &codep, &err);
- if (!XftCharExists(win->env.dpy, font, codep)) {
+ for (t = text; t - text < len; t = next) {
+ next = utf8_decode(t, &rune, &err);
+ if (XftCharExists(win->env.dpy, font, rune)) {
+ f = font;
+ } else { /* fallback font */
fccharset = FcCharSetCreate();
- FcCharSetAddChar(fccharset, codep);
- fallback = XftFontOpen(win->env.dpy, win->env.scr,
- FC_CHARSET, FcTypeCharSet, fccharset,
- FC_SCALABLE, FcTypeBool, FcTrue,
- NULL);
+ FcCharSetAddChar(fccharset, rune);
+ f = XftFontOpen(win->env.dpy, win->env.scr, FC_CHARSET, FcTypeCharSet,
+ fccharset, FC_SCALABLE, FcTypeBool, FcTrue, NULL);
FcCharSetDestroy(fccharset);
}
- newshift = win_textwidth(&win->env, p, (int) (nextp-p), false, (fallback ? fallback : font));
- if (xshift + newshift <= maximum_x)
- XftDrawStringUtf8(d, color, (fallback ? fallback : font), x + xshift, y, (XftChar8*)p, (int) (nextp-p));
- xshift += newshift;
- if (fallback) {
- XftFontClose(win->env.dpy, fallback);
- fallback = NULL;
+ XftTextExtentsUtf8(win->env.dpy, f, (XftChar8*)t, next - t, &ext);
+ tw += ext.xOff;
+ if (tw <= w) {
+ XftDrawStringUtf8(d, color, f, x, y, (XftChar8*)t, next - t);
+ x += ext.xOff;
}
+ if (f != font)
+ XftFontClose(win->env.dpy, f);
}
+ return tw;
}
void win_draw_bar(win_t *win)
{
- int len, olen, x, y, w, tw, maximum_x;
- char rest[3];
- const char *dots = "...";
+ int len, x, y, w, tw;
win_env_t *e;
win_bar_t *l, *r;
XftDraw *d;
@@ -415,7 +410,7 @@ void win_draw_bar(win_t *win)
e = &win->env;
y = win->h + font->ascent + V_TEXT_PAD;
- w = win->w;
+ w = win->w - 2*H_TEXT_PAD;
d = XftDrawCreate(e->dpy, win->buf.pm, DefaultVisual(e->dpy, e->scr),
DefaultColormap(e->dpy, e->scr));
@@ -426,30 +421,16 @@ void win_draw_bar(win_t *win)
XSetBackground(e->dpy, gc, win->bar.bgcol.pixel);
if ((len = strlen(r->buf)) > 0) {
- if ((tw = win_textwidth(e, r->buf, len, true, font)) > w)
+ if ((tw = TEXTWIDTH(win, r->buf, len)) > w)
return;
- x = win->w - tw + H_TEXT_PAD;
+ x = win->w - tw - H_TEXT_PAD;
w -= tw;
- XftDrawStringUtf8(d, &win->bar.fgcol, font, x, y, (XftChar8*)r->buf, len);
+ win_draw_text(win, d, &win->bar.fgcol, x, y, r->buf, len, tw);
}
if ((len = strlen(l->buf)) > 0) {
- olen = len;
- while (len > 0 && (tw = win_textwidth(e, l->buf, len, true, font)) > w)
- len--;
- if (len > 0) {
- maximum_x = w;
- if (len != olen) {
- w = strlen(dots);
- if (len <= w)
- return;
- memcpy(rest, l->buf + len - w, w);
- memcpy(l->buf + len - w, dots, w);
- }
- x = H_TEXT_PAD;
- win_draw_bar_text(win, d, &win->bar.fgcol, font, x, y, l->buf, len, maximum_x);
- if (len != olen)
- memcpy(l->buf + len - w, rest, w);
- }
+ x = H_TEXT_PAD;
+ w -= 2 * H_TEXT_PAD; /* gap between left and right parts */
+ win_draw_text(win, d, &win->bar.fgcol, x, y, l->buf, len, w);
}
XftDrawDestroy(d);
}