X-Git-Url: https://git.xinqibao.xyz/dmenu.git/blobdiff_plain/6be057f060543bb0f3ed9423904263617cdffffe..e5a65b68db96144227d1f1efb98fce40c749ea02:/drw.c diff --git a/drw.c b/drw.c index 7d985b1..1630777 100644 --- a/drw.c +++ b/drw.c @@ -61,7 +61,7 @@ utf8decode(const char *c, long *u, size_t clen) } Drw * -drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap) { Drw *drw = ecalloc(1, sizeof(Drw)); @@ -70,8 +70,11 @@ drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h drw->root = root; drw->w = w; drw->h = h; - drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); - drw->gc = XCreateGC(dpy, root, 0, NULL); + drw->visual = visual; + drw->depth = depth; + drw->cmap = cmap; + drw->drawable = XCreatePixmap(dpy, root, w, h, depth); + drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL); XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); return drw; @@ -87,7 +90,7 @@ drw_resize(Drw *drw, unsigned int w, unsigned int h) drw->h = h; if (drw->drawable) XFreePixmap(drw->dpy, drw->drawable); - drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); + drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth); } void @@ -194,21 +197,22 @@ drw_fontset_free(Fnt *font) } void -drw_clr_create(Drw *drw, Clr *dest, const char *clrname) +drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha) { if (!drw || !dest || !clrname) return; - if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen), + if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap, clrname, dest)) die("error, cannot allocate color '%s'", clrname); + + dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24); } /* Wrapper to create color schemes. The caller has to call free(3) on the * returned color scheme when done using it. */ Clr * -drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) +drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount) { size_t i; Clr *ret; @@ -218,7 +222,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) return NULL; for (i = 0; i < clrcount; i++) - drw_clr_create(drw, &ret[i], clrnames[i]); + drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]); return ret; } @@ -251,7 +255,7 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int 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; @@ -263,6 +267,9 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp 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; @@ -272,9 +279,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp } else { XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - d = XftDrawCreate(drw->dpy, drw->drawable, - DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen)); + d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap); x += lpad; w -= lpad; } @@ -346,6 +351,12 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp * 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); @@ -374,6 +385,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp curfont->next = usedfont; } else { xfont_free(usedfont); + nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint; +no_match: usedfont = drw->fonts; } }