Introduction
Introduction Statistics Contact Development Disclaimer Help
sync latest drw.{c,h} changes from dmenu - libsl - shared code master of variou…
git clone git://git.suckless.org/libsl
Log
Files
Refs
LICENSE
---
commit a8e80c1c5ec435323692b51369901f83c2ffa1b8
parent e55f29636da9cfccb2ab9b075b628de857446135
Author: Hiltjo Posthuma <[email protected]>
Date: Tue, 10 May 2022 19:08:20 +0200
sync latest drw.{c,h} changes from dmenu
Diffstat:
M drw.c | 88 ++++++++++++++++++++---------…
M drw.h | 3 ++-
2 files changed, 60 insertions(+), 31 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
@@ -12,7 +12,7 @@ typedef struct Fnt {
struct Fnt *next;
} Fnt;
-enum { ColFg, ColBg }; /* Clr scheme index */
+enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */
typedef XftColor Clr;
typedef struct {
@@ -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.