Introduction
Introduction Statistics Contact Development Disclaimer Help
sync latest drw.{c,h} changes from dmenu - dwm - dynamic window manager
git clone git://git.suckless.org/dwm
Log
Files
Refs
README
LICENSE
---
commit d3f93c7c1a13a2a78f04fb41ad1935525df948db
parent cd0773cee9bad694dc9a6b1355a32bbe61abadff
Author: Hiltjo Posthuma <[email protected]>
Date: Tue, 10 May 2022 19:07:56 +0200
sync latest drw.{c,h} changes from dmenu
Diffstat:
M drw.c | 88 ++++++++++++++++++++---------…
M drw.h | 1 +
2 files changed, 59 insertions(+), 30 deletions(-)
---
diff --git a/drw.c b/drw.c
@@ -251,12 +251,10 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned…
int
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int …
{
- char buf[1024];
- int ty;
- unsigned int ew;
+ int i, ty, ellipsis_x = 0;
+ unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
XftDraw *d = NULL;
Fnt *usedfont, *curfont, *nextfont;
- size_t i, len;
int utf8strlen, utf8charlen, render = x || y || w || h;
long utf8codepoint = 0;
const char *utf8str;
@@ -264,13 +262,17 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned…
FcPattern *fcpattern;
FcPattern *match;
XftResult result;
- int charexists = 0;
+ int charexists = 0, overflow = 0;
+ /* 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; } nom…
+ static unsigned int ellipsis_width = 0;
- if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
+ if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
return 0;
if (!render) {
- w = ~w;
+ w = invert ? invert : ~invert;
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg :…
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
@@ -282,8 +284,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned …
}
usedfont = drw->fonts;
+ if (!ellipsis_width && render)
+ ellipsis_width = drw_fontset_getwidth(drw, "...");
while (1) {
- utf8strlen = 0;
+ ew = ellipsis_len = utf8strlen = 0;
utf8str = text;
nextfont = NULL;
while (*text) {
@@ -291,9 +295,27 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned …
for (curfont = drw->fonts; curfont; curfont = curfont-…
charexists = charexists || XftCharExists(drw->…
if (charexists) {
- if (curfont == usedfont) {
+ drw_font_getexts(curfont, text, utf8ch…
+ if (ew + ellipsis_width <= w) {
+ /* keep track where the ellips…
+ ellipsis_x = x + ew;
+ ellipsis_w = w - ew;
+ ellipsis_len = utf8strlen;
+ }
+
+ if (ew + tmpw > w) {
+ overflow = 1;
+ /* called from drw_fontset_get…
+ * it wants the width AFTER th…
+ */
+ if (!render)
+ x += tmpw;
+ else
+ utf8strlen = ellipsis_…
+ } else if (curfont == usedfont) {
utf8strlen += utf8charlen;
text += utf8charlen;
+ ew += tmpw;
} else {
nextfont = curfont;
}
@@ -301,36 +323,25 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned…
}
}
- if (!charexists || nextfont)
+ if (overflow || !charexists || nextfont)
break;
else
charexists = 0;
}
if (utf8strlen) {
- drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, N…
- /* shorten text if necessary */
- for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew…
- drw_font_getexts(usedfont, utf8str, len, &ew, …
-
- if (len) {
- memcpy(buf, utf8str, len);
- buf[len] = '\0';
- if (len < utf8strlen)
- for (i = len; i && i > len - 3; buf[--…
- ; /* NOP */
-
- if (render) {
- ty = y + (h - usedfont->h) / 2 + usedf…
- XftDrawStringUtf8(d, &drw->scheme[inve…
- usedfont->xfont, x, …
- }
- x += ew;
- w -= ew;
+ if (render) {
+ ty = y + (h - usedfont->h) / 2 + usedfont->xfo…
+ XftDrawStringUtf8(d, &drw->scheme[invert ? Col…
+ usedfont->xfont, x, ty, (Xft…
}
+ x += ew;
+ w -= ew;
}
+ if (render && overflow)
+ drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", …
- if (!*text) {
+ if (!*text || overflow) {
break;
} else if (nextfont) {
charexists = 0;
@@ -340,6 +351,12 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned …
* character must be drawn. */
charexists = 1;
+ for (i = 0; i < nomatches_len; ++i) {
+ /* avoid calling XftFontMatch if we know we wo…
+ if (utf8codepoint == nomatches.codepoint[i])
+ goto no_match;
+ }
+
fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint);
@@ -368,6 +385,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned i…
curfont->next = usedfont;
} else {
xfont_free(usedfont);
+ nomatches.codepoint[++nomatches.idx % …
+no_match:
usedfont = drw->fonts;
}
}
@@ -397,6 +416,15 @@ drw_fontset_getwidth(Drw *drw, const char *text)
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);
+}
+
void
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *…
{
diff --git a/drw.h b/drw.h
@@ -35,6 +35,7 @@ void drw_free(Drw *drw);
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 i…
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned …
/* Colorscheme abstraction */
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.