diff options
Diffstat (limited to 'font.c')
-rw-r--r-- | font.c | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/font.c b/font.c new file mode 100644 index 0000000..403466b --- /dev/null +++ b/font.c @@ -0,0 +1,159 @@ +/* + * font.c - cwm font abstraction + * + * Copyright (c) 2005 Marius Eriksen <marius@monkey.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "hash.h" +#include "headers.h" +#include "calmwm.h" + +static XftFont *_make_font(struct screen_ctx *sc, struct fontdesc *fdp); + +HASH_GENERATE(fonthash, fontdesc, node, fontdesc_cmp); + +int +fontdesc_cmp(struct fontdesc *a, struct fontdesc *b) +{ + return strcmp(a->name, b->name); +} + +/* + * Fowler/Noll/Vo hash + * http://www.isthe.com/chongo/tech/comp/fnv/ + */ + +#define FNV_P_32 ((unsigned int)0x01000193) /* 16777619 */ +#define FNV_1_32 ((unsigned int)0x811c9dc5) /* 2166136261 */ + +unsigned int +fontdesc_hash(struct fontdesc *fdp) +{ + const unsigned char *p, *end, *start; + unsigned int hash = FNV_1_32; + + start = fdp->name; + end = (const unsigned char *)fdp->name + strlen(fdp->name); + + for (p = start; p < end; p++) { + hash *= FNV_P_32; + hash ^= (unsigned int)*p; + } + + return (hash); +} + +void +font_init(struct screen_ctx *sc) +{ + XColor xcolor, tmp; + + HASH_INIT(&sc->fonthash, fontdesc_hash); + sc->xftdraw = XftDrawCreate(G_dpy, sc->rootwin, + DefaultVisual(G_dpy, sc->which), DefaultColormap(G_dpy, sc->which)); + if (sc->xftdraw == NULL) + errx(1, "XftDrawCreate"); + + if (!XAllocNamedColor(G_dpy, DefaultColormap(G_dpy, sc->which), + "black", &xcolor, &tmp)) + errx(1, "XAllocNamedColor"); + + sc->xftcolor.color.red = xcolor.red; + sc->xftcolor.color.green = xcolor.green; + sc->xftcolor.color.blue = xcolor.blue; + sc->xftcolor.color.alpha = 0x00ff00; + sc->xftcolor.pixel = xcolor.pixel; +} + +struct fontdesc * +font_getx(struct screen_ctx *sc, const char *name) +{ + struct fontdesc *fdp; + + if ((fdp = font_get(sc, name)) == NULL) + errx(1, "font_get()"); + + return (fdp); +} + +struct fontdesc * +font_get(struct screen_ctx *sc, const char *name) +{ + struct fontdesc fd, *fdp; + XftFont *fn; + + fd.name = name; + + if ((fdp = HASH_FIND(fonthash, &sc->fonthash, &fd)) == NULL + && (fn = _make_font(sc, &fd)) != NULL) { + fdp = xmalloc(sizeof(*fdp)); + fdp->name = xstrdup(fd.name); + fdp->fn = fn; + fdp->sc = sc; + HASH_INSERT(fonthash, &sc->fonthash, fdp); + } + + return (fdp); +} + +int +font_width(struct fontdesc *fdp, const char *text, int len) +{ + XGlyphInfo extents; + XftTextExtents8(G_dpy, fdp->fn, (const XftChar8*)text, len, &extents); + + return (extents.xOff); +} + +void +font_draw(struct fontdesc *fdp, const char *text, int len, + Drawable d, int x, int y) +{ + XftDrawChange(fdp->sc->xftdraw, d); + /* Really needs to be UTF8'd. */ + XftDrawString8(fdp->sc->xftdraw, &fdp->sc->xftcolor, fdp->fn, x, y, + (const FcChar8*)text, len); +} + +int +font_ascent(struct fontdesc *fdp) +{ + return fdp->fn->ascent; +} + +int +font_descent(struct fontdesc *fdp) +{ + return fdp->fn->descent; +} + +static XftFont * +_make_font(struct screen_ctx *sc, struct fontdesc *fdp) +{ + XftFont *fn = NULL; + FcPattern *pat, *patx; + XftResult res; + + if ((pat = FcNameParse(fdp->name)) == NULL) + return (NULL); + + if ((patx = XftFontMatch(G_dpy, sc->which, pat, &res)) != NULL) + fn = XftFontOpenPattern(G_dpy, patx); + + FcPatternDestroy(pat); + + return (fn); +} + |