I manage to use wenquanyi bitmap song to display Chinese characters on
the dwm bar in Arch linux,  but there is always something wrong on
Ubuntu. Now I give up. I begin to use Xft.

You can use Xft. There are several patches which enable Xft.

The attached patch uses pango to render text. You can apply the patch
and change your font to something like sans-10. Then pango and
fontconfig will select proper fonts for you.

I found this patch on this mailing list, but I do not remember who write it.

On Fri, Apr 17, 2009 at 9:21 PM, Preben Randhol <rand...@pvv.org> wrote:
> I'm currently using the terminus font, but it doesn't seem to work with
> unicode. Is there another font you would recommend that works with
> unicode?
>
> Thanks in advance
>
> Preben
>
>
>
diff -r b4e7c220422d config.mk
--- a/config.mk	Sat Feb 21 19:20:11 2009 +0000
+++ b/config.mk	Sun Mar 01 15:22:30 2009 +0800
@@ -15,8 +15,8 @@
 #XINERAMAFLAGS = -DXINERAMA
 
 # includes and libs
-INCS = -I. -I/usr/include -I${X11INC}
-LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS}
+INCS = -I. -I/usr/include -I${X11INC} `pkg-config --cflags xft pango pangoxft`
+LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} `pkg-config --libs xft pango pangoxft`
 
 # flags
 CPPFLAGS = -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
diff -r b4e7c220422d dwm.c
--- a/dwm.c	Sat Feb 21 19:20:11 2009 +0000
+++ b/dwm.c	Sun Mar 01 15:22:30 2009 +0800
@@ -36,6 +36,10 @@
 #include <X11/Xlib.h>
 #include <X11/Xproto.h>
 #include <X11/Xutil.h>
+#include <X11/Xft/Xft.h>
+#include <pango/pango.h>
+#include <pango/pangoxft.h>
+#include <pango/pango-font.h>
 #ifdef XINERAMA
 #include <X11/extensions/Xinerama.h>
 #endif
@@ -46,8 +50,12 @@
 #define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH))
 #define ISVISIBLE(x)            (x->tags & tagset[seltags])
 #define LENGTH(x)               (sizeof x / sizeof x[0])
+#ifndef MAX
 #define MAX(a, b)               ((a) > (b) ? (a) : (b))
+#endif
+#ifndef MIN
 #define MIN(a, b)               ((a) < (b) ? (a) : (b))
+#endif
 #define MAXTAGLEN               16
 #define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
 #define WIDTH(x)                ((x)->w + 2 * (x)->bw)
@@ -98,12 +106,19 @@
 	unsigned long sel[ColLast];
 	Drawable drawable;
 	GC gc;
+
+	XftColor  xftnorm[ColLast];
+	XftColor  xftsel[ColLast];
+	XftDraw  *xftdrawable;
+
+	PangoContext *pgc;
+	PangoLayout  *plo;
+	PangoFontDescription *pfd;
+
 	struct {
 		int ascent;
 		int descent;
 		int height;
-		XFontSet set;
-		XFontStruct *xfont;
 	} font;
 } DC; /* draw context */
 
@@ -152,7 +167,7 @@
 static void focusin(XEvent *e);
 static void focusstack(const Arg *arg);
 static Client *getclient(Window w);
-static unsigned long getcolor(const char *colstr);
+//static unsigned long getcolor(const char *colstr);
 static long getstate(Window w);
 static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
 static void grabbuttons(Client *c, Bool focused);
@@ -351,10 +366,6 @@
 	lt[sellt] = &foo;
 	while(stack)
 		unmanage(stack);
-	if(dc.font.set)
-		XFreeFontSet(dpy, dc.font.set);
-	else
-		XFreeFont(dpy, dc.font.xfont);
 	XUngrabKey(dpy, AnyKey, AnyModifier, root);
 	XFreePixmap(dpy, dc.drawable);
 	XFreeGC(dpy, dc.gc);
@@ -568,7 +579,7 @@
 		return;
 	olen = strlen(text);
 	h = dc.font.ascent + dc.font.descent;
-	y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
+	y = dc.y;
 	x = dc.x + (h / 2);
 	/* shorten text if necessary */
 	for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--);
@@ -577,11 +588,8 @@
 	memcpy(buf, text, len);
 	if(len < olen)
 		for(i = len; i && i > len - 3; buf[--i] = '.');
-	XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]);
-	if(dc.font.set)
-		XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
-	else
-		XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
+	pango_layout_set_text(dc.plo, text, len);
+	pango_xft_render_layout(dc.xftdrawable, (col==dc.norm?dc.xftnorm:dc.xftsel)+(invert?ColBG:ColFG), dc.plo, x * PANGO_SCALE, y * PANGO_SCALE);
 }
 
 void
@@ -671,13 +679,13 @@
 }
 
 unsigned long
-getcolor(const char *colstr) {
+getcolor(const char *colstr, XftColor *color) {
 	Colormap cmap = DefaultColormap(dpy, screen);
-	XColor color;
+	Visual *vis = DefaultVisual(dpy, screen);
 
-	if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
+	if(!XftColorAllocName(dpy,vis,cmap,colstr, color))
 		die("error, cannot allocate color '%s'\n", colstr);
-	return color.pixel;
+	return color->pixel;
 }
 
 long
@@ -762,36 +770,20 @@
 
 void
 initfont(const char *fontstr) {
-	char *def, **missing;
-	int i, n;
+	PangoFontMetrics *metrics;
 
-	missing = NULL;
-	dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
-	if(missing) {
-		while(n--)
-			fprintf(stderr, "dwm: missing fontset: %s\n", missing[n]);
-		XFreeStringList(missing);
-	}
-	if(dc.font.set) {
-		XFontSetExtents *font_extents;
-		XFontStruct **xfonts;
-		char **font_names;
-		dc.font.ascent = dc.font.descent = 0;
-		font_extents = XExtentsOfFontSet(dc.font.set);
-		n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
-		for(i = 0, dc.font.ascent = 0, dc.font.descent = 0; i < n; i++) {
-			dc.font.ascent = MAX(dc.font.ascent, (*xfonts)->ascent);
-			dc.font.descent = MAX(dc.font.descent,(*xfonts)->descent);
-			xfonts++;
-		}
-	}
-	else {
-		if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr))
-		&& !(dc.font.xfont = XLoadQueryFont(dpy, "fixed")))
-			die("error, cannot load font: '%s'\n", fontstr);
-		dc.font.ascent = dc.font.xfont->ascent;
-		dc.font.descent = dc.font.xfont->descent;
-	}
+	dc.pgc = pango_xft_get_context(dpy, screen);
+	dc.pfd = pango_font_description_from_string(fontstr);
+
+	metrics = pango_context_get_metrics(dc.pgc, dc.pfd, pango_language_from_string(setlocale(LC_CTYPE, "")));
+
+	dc.font.ascent  = pango_font_metrics_get_ascent(metrics) / PANGO_SCALE;
+	dc.font.descent = pango_font_metrics_get_descent(metrics) / PANGO_SCALE;
+
+	pango_font_metrics_unref(metrics);
+
+	dc.plo = pango_layout_new(dc.pgc);
+	pango_layout_set_font_description(dc.plo, dc.pfd);
 	dc.font.height = dc.font.ascent + dc.font.descent;
 }
 
@@ -1287,17 +1279,18 @@
 	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
 
 	/* init appearance */
-	dc.norm[ColBorder] = getcolor(normbordercolor);
-	dc.norm[ColBG] = getcolor(normbgcolor);
-	dc.norm[ColFG] = getcolor(normfgcolor);
-	dc.sel[ColBorder] = getcolor(selbordercolor);
-	dc.sel[ColBG] = getcolor(selbgcolor);
-	dc.sel[ColFG] = getcolor(selfgcolor);
+ 	dc.norm[ColBorder] = getcolor(normbordercolor, dc.xftnorm+ColBorder);
+ 	dc.norm[ColBG] = getcolor(normbgcolor, dc.xftnorm+ColBG);
+ 	dc.norm[ColFG] = getcolor(normfgcolor, dc.xftnorm+ColFG);
+ 	dc.sel[ColBorder] = getcolor(selbordercolor, dc.xftsel+ColBorder);
+ 	dc.sel[ColBG] = getcolor(selbgcolor, dc.xftsel+ColBG);
+ 	dc.sel[ColFG] = getcolor(selfgcolor, dc.xftsel+ColFG);
 	dc.drawable = XCreatePixmap(dpy, root, DisplayWidth(dpy, screen), bh, DefaultDepth(dpy, screen));
 	dc.gc = XCreateGC(dpy, root, 0, NULL);
 	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
-	if(!dc.font.set)
-		XSetFont(dpy, dc.gc, dc.font.xfont->fid);
+	dc.xftdrawable = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy,screen), DefaultColormap(dpy,screen));
+	if(!dc.xftdrawable)
+		printf("error, cannot create drawable\n");
 
 	/* init bar */
 	for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) {
@@ -1376,13 +1369,10 @@
 
 int
 textnw(const char *text, unsigned int len) {
-	XRectangle r;
-
-	if(dc.font.set) {
-		XmbTextExtents(dc.font.set, text, len, NULL, &r);
-		return r.width;
-	}
-	return XTextWidth(dc.font.xfont, text, len);
+	PangoRectangle r;
+	pango_layout_set_text(dc.plo, text, len);
+	pango_layout_get_extents(dc.plo, &r, 0);
+	return r.width / PANGO_SCALE;
 }
 
 void
@@ -1497,6 +1487,7 @@
 	if(dc.drawable != 0)
 		XFreePixmap(dpy, dc.drawable);
 	dc.drawable = XCreatePixmap(dpy, root, ww, bh, DefaultDepth(dpy, screen));
+	XftDrawChange(dc.xftdrawable, dc.drawable);
 	XMoveResizeWindow(dpy, barwin, wx, by, ww, bh);
 }
 

Reply via email to