[hackers] [wmii] Add Xft support. || Kris Maglione

From: <hg_AT_suckless.org>
Date: Thu, 21 May 2009 17:55:39 +0000 (UTC)

changeset: 2458:f4cd1cc8e757
tag: tip
user: Kris Maglione <jg_AT_suckless.org>
date: Thu May 21 13:55:34 2009 -0400
files: cmd/wmii/x11.c config.mk include/x11.h
description:
Add Xft support.

diff -r 1c29e1952494 -r f4cd1cc8e757 cmd/wmii/x11.c
--- a/cmd/wmii/x11.c Tue May 19 13:14:06 2009 -0400
+++ b/cmd/wmii/x11.c Thu May 21 13:55:34 2009 -0400
@@ -25,6 +25,8 @@
 
 static int errorhandler(Display*, XErrorEvent*);
 static int (*xlib_errorhandler) (Display*, XErrorEvent*);
+
+static XftColor* xftcolor(ulong);
 
 
 /* Rectangles/Points */
@@ -249,9 +251,18 @@
 
         assert(img->type == WImage);
 
+ if(img->xft)
+ XftDrawDestroy(img->xft);
         XFreePixmap(display, img->w);
         XFreeGC(display, img->gc);
         free(img);
+}
+
+static XftDraw*
+xftdrawable(Image *img) {
+ if(img->xft == nil)
+ img->xft = XftDrawCreate(display, img->w, scr.visual, scr.colormap);
+ return img->xft;
 }
 
 /* Windows */
@@ -309,6 +320,8 @@
 destroywindow(Window *w) {
         assert(w->type == WWindow);
         sethandler(w, nil);
+ if(w->xft)
+ XftDrawDestroy(w->xft);
         if(w->gc)
                 XFreeGC(display, w->gc);
         XDestroyWindow(display, w->w);
@@ -561,16 +574,25 @@
         }
 
         setgccol(dst, col);
- if(font->set)
+ switch(font->type) {
+ case FFontSet:
                 Xutf8DrawString(display, dst->w,
- font->set, dst->gc,
+ font->font.set, dst->gc,
                                 x, y,
                                 buf, len);
- else {
- XSetFont(display, dst->gc, font->xfont->fid);
+ break;
+ case FXft:
+ XftDrawStringUtf8(xftdrawable(dst), xftcolor(col),
+ font->font.xft,
+ x, y, (uchar*)buf, len);
+ break;
+ case FX11:
+ XSetFont(display, dst->gc, font->font.x11->fid);
                 XDrawString(display, dst->w, dst->gc,
- x, y,
- buf, len);
+ x, y, buf, len);
+ break;
+ default:
+ die("Invalid font type.");
         }
 
 done:
@@ -617,55 +639,98 @@
             && namedcolor(buf+16, &c->border);
 }
 
+static XftColor*
+xftcolor(ulong col) {
+ XftColor *c;
+
+ c = emallocz(sizeof *c);
+ *c = (XftColor) {
+ col, {
+ (col>>8) & 0xff00,
+ (col>>0) & 0xff00,
+ (col<<8) & 0xff00,
+ (col>>16) & 0xff00,
+ }
+ };
+ return freelater(c);
+}
+
 /* Fonts */
 Font*
 loadfont(char *name) {
+ XFontStruct **xfonts;
+ char **missing, **font_names;
         Biobuf *b;
         Font *f;
- XFontStruct **xfonts;
- char **missing, **font_names;
         int n, i;
 
         missing = nil;
         f = emallocz(sizeof *f);
         f->name = estrdup(name);
- f->set = XCreateFontSet(display, name, &missing, &n, nil);
- if(missing) {
- b = Bfdopen(dup(2), O_WRONLY);
- Bprint(b, "%s: note: missing fontset%s for '%s':", argv0,
- (n > 1 ? "s" : ""), name);
- for(i = 0; i < n; i++)
- Bprint(b, "%s %s", (i ? "," : ""), missing[i]);
- Bprint(b, "\n");
- Bterm(b);
- freestringlist(missing);
- }
+ if(!strncmp(f->name, "xft:", 4)) {
+ f->type = FXft;
 
- if(f->set) {
- XFontsOfFontSet(f->set, &xfonts, &font_names);
- f->ascent = xfonts[0]->ascent;
- f->descent = xfonts[0]->descent;
+ f->font.xft = XftFontOpenXlfd(display, scr.screen, f->name + 4);
+ if(!f->font.xft)
+ f->font.xft = XftFontOpenName(display, scr.screen, f->name + 4);
+ if(!f->font.xft)
+ goto error;
+
+ f->ascent = f->font.xft->ascent;
+ f->descent = f->font.xft->descent;
         }else {
- f->xfont = XLoadQueryFont(display, name);
- if(!f->xfont) {
- fprint(2, "%s: cannot load font: %s\n", argv0, name);
- freefont(f);
- return nil;
+ f->font.set = XCreateFontSet(display, name, &missing, &n, nil);
+ if(missing) {
+ b = Bfdopen(dup(2), O_WRONLY);
+ Bprint(b, "%s: note: missing fontset%s for '%s':", argv0,
+ (n > 1 ? "s" : ""), name);
+ for(i = 0; i < n; i++)
+ Bprint(b, "%s %s", (i ? "," : ""), missing[i]);
+ Bprint(b, "\n");
+ Bterm(b);
+ freestringlist(missing);
                 }
 
- f->ascent = f->xfont->ascent;
- f->descent = f->xfont->descent;
+ if(f->font.set) {
+ f->type = FFontSet;
+ XFontsOfFontSet(f->font.set, &xfonts, &font_names);
+ f->ascent = xfonts[0]->ascent;
+ f->descent = xfonts[0]->descent;
+ }else {
+ f->type = FX11;
+ f->font.x11 = XLoadQueryFont(display, name);
+ if(!f->font.x11)
+ goto error;
+
+ f->ascent = f->font.x11->ascent;
+ f->descent = f->font.x11->descent;
+ }
         }
         f->height = f->ascent + f->descent;
         return f;
+
+error:
+ fprint(2, "%s: cannot load font: %s\n", argv0, name);
+ f->type = 0;
+ freefont(f);
+ return nil;
 }
 
 void
 freefont(Font *f) {
- if(f->set)
- XFreeFontSet(display, f->set);
- if(f->xfont)
- XFreeFont(display, f->xfont);
+ switch(f->type) {
+ case FFontSet:
+ XFreeFontSet(display, f->font.set);
+ break;
+ case FXft:
+ XftFontClose(display, f->font.xft);
+ break;
+ case FX11:
+ XFreeFont(display, f->font.x11);
+ break;
+ default:
+ break;
+ }
         free(f->name);
         free(f);
 }
@@ -673,12 +738,21 @@
 uint
 textwidth_l(Font *font, char *text, uint len) {
         XRectangle r;
+ XGlyphInfo i;
 
- if(font->set) {
- Xutf8TextExtents(font->set, text, len, nil, &r);
+ switch(font->type) {
+ case FFontSet:
+ Xutf8TextExtents(font->font.set, text, len, nil, &r);
                 return r.width;
+ case FXft:
+ XftTextExtentsUtf8(display, font->font.xft, (uchar*)text, len, &i);
+ return i.width;
+ case FX11:
+ return XTextWidth(font->font.x11, text, len);
+ default:
+ die("Invalid font type");
+ return 0; /* shut up ken */
         }
- return XTextWidth(font->xfont, text, len);
 }
 
 uint
diff -r 1c29e1952494 -r f4cd1cc8e757 config.mk
--- a/config.mk Tue May 19 13:14:06 2009 -0400
+++ b/config.mk Thu May 21 13:55:34 2009 -0400
@@ -33,8 +33,8 @@
 # are painfully slow, and should be avoided.
 #BINSH = /bin/ash
 
-INCX11 = -I/usr/X11R6/include
-LIBX11 = -L/usr/X11R6/lib -lX11
+INCX11 = $$(pkg-config --cflags xft)
+LIBX11 = $$(pkg-config --libs xft)
 LIBICONV = # Leave blank if your libc includes iconv (glibc does)
 LIBIXP = $(LIBDIR)/libixp.a
 
diff -r 1c29e1952494 -r f4cd1cc8e757 include/x11.h
--- a/include/x11.h Tue May 19 13:14:06 2009 -0400
+++ b/include/x11.h Thu May 21 13:55:34 2009 -0400
@@ -6,6 +6,7 @@
 #define Screen XScreen
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
+#include <X11/Xft/Xft.h>
 #ifdef _X11_VISIBLE
 # include <X11/Xatom.h>
 # include <X11/extensions/shape.h>
@@ -27,12 +28,20 @@
         Center = NEast | SWest,
 };
 
+enum FontType {
+ FX11 = 1,
+ FFontSet,
+ FXft,
+};
+
 enum WindowType {
         WWindow,
         WImage,
 };
 
 typedef enum Align Align;
+typedef enum FontType FontType;
+typedef enum WindowType WindowType;
 
 typedef XSetWindowAttributes WinAttr;
 
@@ -76,12 +85,16 @@
 };
 
 struct Font {
- XFontStruct *xfont;
- XFontSet set;
- int ascent;
- int descent;
- uint height;
- char *name;
+ int type;
+ union {
+ XFontStruct* x11;
+ XFontSet set;
+ XftFont* xft;
+ } font;
+ int ascent;
+ int descent;
+ uint height;
+ char* name;
 };
 
 struct Handlers {
@@ -122,6 +135,7 @@
         int type;
         XID w;
         GC gc;
+ XftDraw* xft;
         Rectangle r;
         int border;
         Window* parent;
Received on Thu May 21 2009 - 17:55:39 UTC

This archive was generated by hypermail 2.2.0 : Thu May 21 2009 - 18:00:06 UTC