aboutsummaryrefslogtreecommitdiffstats
path: root/font.c
diff options
context:
space:
mode:
Diffstat (limited to 'font.c')
-rw-r--r--font.c159
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);
+}
+