diff options
author | Bert Münnich <ber.t@posteo.de> | 2016-08-06 15:27:58 +0200 |
---|---|---|
committer | Bert Münnich <ber.t@posteo.de> | 2016-08-06 15:27:58 +0200 |
commit | c280129cef4ff2e8667b8700c9bdf671fdd7c8ef (patch) | |
tree | f440d93fe935f2e68bb0460927097130160f97f0 /window.c | |
parent | aabc2bddbdeecdb2651394d90b10a9290a69b527 (diff) |
Use Xft for font loading and text drawing
Diffstat (limited to 'window.c')
-rw-r--r-- | window.c | 106 |
1 files changed, 32 insertions, 74 deletions
@@ -41,13 +41,7 @@ static Cursor chand; static Cursor cwatch; static GC gc; -static struct { - int ascent; - int descent; - XFontStruct *xfont; - XFontSet set; -} font; - +static XftFont *font; static int fontheight; static int barheight; @@ -56,50 +50,21 @@ Atom atoms[ATOM_COUNT]; static Bool fs_support; static Bool fs_warned; -void win_init_font(Display *dpy, const char *fontstr) +void win_init_font(const win_env_t *e, const char *fontstr) { - int n; - char *def, **missing; - - font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); - if (missing) - XFreeStringList(missing); - if (font.set) { - XFontStruct **xfonts; - char **font_names; - - font.ascent = font.descent = 0; - XExtentsOfFontSet(font.set); - n = XFontsOfFontSet(font.set, &xfonts, &font_names); - while (n--) { - font.ascent = MAX(font.ascent, (*xfonts)->ascent); - font.descent = MAX(font.descent,(*xfonts)->descent); - xfonts++; - } - } else { - if ((font.xfont = XLoadQueryFont(dpy, fontstr)) == NULL && - (font.xfont = XLoadQueryFont(dpy, "fixed")) == NULL) - { - error(EXIT_FAILURE, 0, "Error loading font '%s'", fontstr); - } - font.ascent = font.xfont->ascent; - font.descent = font.xfont->descent; - } - fontheight = font.ascent + font.descent; + if ((font = XftFontOpenName(e->dpy, e->scr, fontstr)) == NULL) + error(EXIT_FAILURE, 0, "Error loading font '%s'", fontstr); + fontheight = font->ascent + font->descent; barheight = fontheight + 2 * V_TEXT_PAD; } -unsigned long win_alloc_color(win_t *win, const char *name) +void win_alloc_color(const win_env_t *e, const char *name, XftColor *col) { - XColor col; - - if (XAllocNamedColor(win->env.dpy, - DefaultColormap(win->env.dpy, win->env.scr), - name, &col, &col) == 0) + if (!XftColorAllocName(e->dpy, DefaultVisual(e->dpy, e->scr), + DefaultColormap(e->dpy, e->scr), name, col)) { error(EXIT_FAILURE, 0, "Error allocating color '%s'", name); } - return col.pixel; } void win_check_wm_support(Display *dpy, Window root) @@ -155,13 +120,13 @@ void win_init(win_t *win) if (setlocale(LC_CTYPE, "") == NULL || XSupportsLocale() == 0) error(0, 0, "No locale support"); - win_init_font(e->dpy, BAR_FONT); + win_init_font(e, BAR_FONT); - win->bgcol = win_alloc_color(win, WIN_BG_COLOR); - win->fscol = win_alloc_color(win, WIN_FS_COLOR); - win->selcol = win_alloc_color(win, SEL_COLOR); - win->bar.bgcol = win_alloc_color(win, BAR_BG_COLOR); - win->bar.fgcol = win_alloc_color(win, BAR_FG_COLOR); + win_alloc_color(e, WIN_BG_COLOR, &win->bgcol); + win_alloc_color(e, WIN_FS_COLOR, &win->fscol); + win_alloc_color(e, SEL_COLOR, &win->selcol); + win_alloc_color(e, BAR_BG_COLOR, &win->bar.bgcol); + win_alloc_color(e, BAR_FG_COLOR, &win->bar.fgcol); win->bar.l.size = BAR_L_LEN; win->bar.r.size = BAR_R_LEN; @@ -295,7 +260,7 @@ void win_open(win_t *win) win->buf.h = e->scrh; win->buf.pm = XCreatePixmap(e->dpy, win->xwin, win->buf.w, win->buf.h, e->depth); - XSetForeground(e->dpy, gc, fullscreen ? win->fscol : win->bgcol); + XSetForeground(e->dpy, gc, fullscreen ? win->fscol.pixel : win->bgcol.pixel); XFillRectangle(e->dpy, win->buf.pm, gc, 0, 0, win->buf.w, win->buf.h); XSetWindowBackgroundPixmap(e->dpy, win->xwin, win->buf.pm); @@ -387,7 +352,7 @@ void win_clear(win_t *win) win->buf.pm = XCreatePixmap(e->dpy, win->xwin, win->buf.w, win->buf.h, e->depth); } - XSetForeground(e->dpy, gc, win->fullscreen ? win->fscol : win->bgcol); + XSetForeground(e->dpy, gc, win->fullscreen ? win->fscol.pixel : win->bgcol.pixel); XFillRectangle(e->dpy, win->buf.pm, gc, 0, 0, win->buf.w, win->buf.h); } @@ -398,33 +363,33 @@ void win_draw_bar(win_t *win) const char *dots = "..."; win_env_t *e; win_bar_t *l, *r; + XftDraw *d; if ((l = &win->bar.l)->buf == NULL || (r = &win->bar.r)->buf == NULL) return; e = &win->env; - y = win->h + font.ascent + V_TEXT_PAD; + y = win->h + font->ascent + V_TEXT_PAD; w = win->w; + d = XftDrawCreate(e->dpy, win->buf.pm, DefaultVisual(e->dpy, e->scr), + DefaultColormap(e->dpy, e->scr)); - XSetForeground(e->dpy, gc, win->bar.bgcol); + XSetForeground(e->dpy, gc, win->bar.bgcol.pixel); XFillRectangle(e->dpy, win->buf.pm, gc, 0, win->h, win->w, win->bar.h); - XSetForeground(e->dpy, gc, win->bar.fgcol); - XSetBackground(e->dpy, gc, win->bar.bgcol); + XSetForeground(e->dpy, gc, win->bar.fgcol.pixel); + XSetBackground(e->dpy, gc, win->bar.bgcol.pixel); if ((len = strlen(r->buf)) > 0) { - if ((tw = win_textwidth(r->buf, len, true)) > w) + if ((tw = win_textwidth(e, r->buf, len, true)) > w) return; x = win->w - tw + H_TEXT_PAD; w -= tw; - if (font.set) - XmbDrawString(e->dpy, win->buf.pm, font.set, gc, x, y, r->buf, len); - else - XDrawString(e->dpy, win->buf.pm, gc, x, y, r->buf, len); + XftDrawStringUtf8(d, &win->bar.fgcol, font, x, y, (XftChar8*)r->buf, len); } if ((len = strlen(l->buf)) > 0) { olen = len; - while (len > 0 && (tw = win_textwidth(l->buf, len, true)) > w) + while (len > 0 && (tw = win_textwidth(e, l->buf, len, true)) > w) len--; if (len > 0) { if (len != olen) { @@ -435,14 +400,12 @@ void win_draw_bar(win_t *win) memcpy(l->buf + len - w, dots, w); } x = H_TEXT_PAD; - if (font.set) - XmbDrawString(e->dpy, win->buf.pm, font.set, gc, x, y, l->buf, len); - else - XDrawString(e->dpy, win->buf.pm, gc, x, y, l->buf, len); + XftDrawStringUtf8(d, &win->bar.fgcol, font, x, y, (XftChar8*)l->buf, len); if (len != olen) memcpy(l->buf + len - w, rest, w); } } + XftDrawDestroy(d); } void win_draw(win_t *win) @@ -470,17 +433,12 @@ void win_draw_rect(win_t *win, int x, int y, int w, int h, bool fill, int lw, XDrawRectangle(win->env.dpy, win->buf.pm, gc, x, y, w, h); } -int win_textwidth(const char *text, unsigned int len, bool with_padding) +int win_textwidth(const win_env_t *e, const char *text, unsigned int len, bool with_padding) { - XRectangle r; - int padding = with_padding ? 2 * H_TEXT_PAD : 0; + XGlyphInfo ext; - if (font.set) { - XmbTextExtents(font.set, text, len, NULL, &r); - return r.width + padding; - } else { - return XTextWidth(font.xfont, text, len) + padding; - } + XftTextExtentsUtf8(e->dpy, font, (XftChar8*)text, len, &ext); + return ext.xOff + (with_padding ? 2 * H_TEXT_PAD : 0); } void win_set_title(win_t *win, const char *title) |