int
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
{
- int ty, ellipsis_x = 0;
+ int i, ty, ellipsis_x = 0;
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, ellipsis_width;
XftDraw *d = NULL;
Fnt *usedfont, *curfont, *nextfont;
FcPattern *match;
XftResult result;
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; } nomatches;
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
return 0;
if (!render) {
- w = ~w;
+ w = invert ? invert : ~invert;
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
if (ew + tmpw > w) {
overflow = 1;
- utf8strlen = ellipsis_len;
+ /* called from drw_fontset_getwidth_clamp():
+ * it wants the width AFTER the overflow
+ */
+ if (!render)
+ x += tmpw;
+ else
+ utf8strlen = ellipsis_len;
} else if (curfont == usedfont) {
utf8strlen += utf8charlen;
text += utf8charlen;
* character must be drawn. */
charexists = 1;
+ for (i = 0; i < nomatches_len; ++i) {
+ /* avoid calling XftFontMatch if we know we won't find a match */
+ if (utf8codepoint == nomatches.codepoint[i])
+ goto no_match;
+ }
+
fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint);
curfont->next = usedfont;
} else {
xfont_free(usedfont);
+ nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint;
+no_match:
usedfont = drw->fonts;
}
}
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 *w, unsigned int *h)
{