ports/143951: [PATCH] Add support for Xft fonts to x11/dmenu

Ashish SHUKLA wahjava at gmail.com
Sun Apr 4 14:20:09 UTC 2010


The following reply was made to PR ports/143951; it has been noted by GNATS.

From: wahjava at gmail.com (Ashish SHUKLA)
To: Jeroen Schot <schot at A-Eskwadraat.nl>
Cc: pav at FreeBSD.org,  bug-followup at FreeBSD.org
Subject: Re: ports/143951: [PATCH] Add support for Xft fonts to x11/dmenu
Date: Sun, 04 Apr 2010 19:44:14 +0530

 --=-=-=
 Content-Type: multipart/signed; boundary="==-=-=";
 	micalg=pgp-sha1; protocol="application/pgp-signature"
 
 --==-=-=
 Content-Transfer-Encoding: quoted-printable
 
 Jeroen Schot writes:
 > Hello Ashish SHUKLA,
 
 Hi Jeroen,
 
 > I found an other version of this patch on the dmenu meailing list that
 > claim to be an updated/improved version:
 
 > http://lists.suckless.org/dev/0911/2320.html
 
 Apologies for the late reply.
 
 This patch look cleaner and also comes with documentation :). I looked at i=
 t,
 modified it a bit, and I can maintain this patch for FreeBSD. I'm also
 attaching the updated diff file. Apart from the Xft support, it also correc=
 ts
 few issues. So please review the diff carefully, and let me know of any
 issues.
 
 Thanks
 =2D-=20
 Ashish SHUKLA
 
 P.S. I won't be available from Monday noon till Wednesday evening, so expect
 delay in replies.
 
 --==-=-=
 Content-Type: application/pgp-signature
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.14 (FreeBSD)
 
 iEYEARECAAYFAku4nroACgkQHy+EEHYuXnTUtwCcCFRx04dkWHE/8OhiPWFK9W+d
 C08AoIUBZBGR8ZPkyI5zr6LYjh28afV1
 =gMFt
 -----END PGP SIGNATURE-----
 --==-=-=--
 
 --=-=-=
 Content-Type: text/plain; charset=utf-8
 Content-Disposition: attachment; filename=dmenu.diff
 Content-Description: x11/dmenu diff
 
 diff -urN /usr/ports/x11/dmenu/Makefile dmenu/Makefile
 --- /usr/ports/x11/dmenu/Makefile	2009-04-28 00:46:36.000000000 +0530
 +++ dmenu/Makefile	2010-04-04 19:33:16.000000000 +0530
 @@ -7,6 +7,7 @@
  
  PORTNAME=	dmenu
  PORTVERSION=	4.0
 +PORTREVISION=	2
  CATEGORIES=	x11
  MASTER_SITES=	http://code.suckless.org/dl/tools/ \
  		http://schot.a-eskwadraat.nl/files/
 @@ -14,9 +15,25 @@
  MAINTAINER=	schot at a-eskwadraat.nl
  COMMENT=	X11 menu application (not only) for the dwm window manager
  
 +OPTIONS=	XFT	"XFT support" On
 +
  USE_XORG=	x11 xinerama
  
  MAN1=		dmenu.1
  PLIST_FILES=	bin/dmenu bin/dmenu_path bin/dmenu_run
  
 +.include <bsd.port.options.mk>
 +
 +.if defined(WITH_XFT)
 +EXTRA_PATCHES=	${FILESDIR}/dmenu-4.0-xft2.diff
 +PATCH_STRIP=	-p1
 +USE_XORG+=	xft
 +.endif
 +
 +post-patch:
 +	@${GREP} -Rl '%%[[:alpha:]]\+%%' ${WRKSRC}|${XARGS} ${REINPLACE_CMD} \
 +		-e "s,%%PREFIX%%,${PREFIX},g" \
 +		-e "s,%%LOCALBASE%%,${LOCALBASE},g" \
 +		-e "s,%%MANPREFIX%%,${MANPREFIX}/man,g"
 +
  .include <bsd.port.mk>
 diff -urN /usr/ports/x11/dmenu/files/dmenu-4.0-xft2.diff dmenu/files/dmenu-4.0-xft2.diff
 --- /usr/ports/x11/dmenu/files/dmenu-4.0-xft2.diff	1970-01-01 05:30:00.000000000 +0530
 +++ dmenu/files/dmenu-4.0-xft2.diff	2010-04-04 18:26:57.000000000 +0530
 @@ -0,0 +1,263 @@
 +Only in dmenu-4.0: .dmenu.c.swp
 +diff -up dmenu-4.0/config.h dmenu-4.0-xft/config.h
 +--- dmenu-4.0/config.h	2009-04-18 07:50:04.000000000 -0400
 ++++ dmenu-4.0-xft/config.h	2009-11-08 05:07:40.028951847 -0500
 +@@ -7,3 +7,4 @@ static const char *normfgcolor = "#00000
 + static const char *selbgcolor  = "#0066ff";
 + static const char *selfgcolor  = "#ffffff";
 + static unsigned int spaceitem  = 30; /* px between menu items */
 ++static const char *fontxft     = "Monospace-10:normal"; /*if set xft is used */  
 +diff -up dmenu-4.0/config.mk dmenu-4.0-xft/config.mk
 +--- dmenu-4.0/config.mk	2009-04-18 07:50:04.000000000 -0400
 ++++ dmenu-4.0-xft/config.mk	2009-11-08 05:07:40.028951847 -0500
 +@@ -15,8 +15,8 @@ XINERAMALIBS = -L${X11LIB} -lXinerama
 + XINERAMAFLAGS = -DXINERAMA
 + 
 + # includes and libs
 +-INCS = -I. -I/usr/include -I${X11INC}
 +-LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS}
 ++INCS = -I. -I%%LOCALBASE%%/include -I${X11INC} -I/usr/include -I%%LOCALBASE%%/include/freetype2
 ++LIBS = -L%%LOCALBASE%%/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS} -lXft -lX11 -lXrender -lfreetype -lz -lfontconfig -lXrender -lX11
 + 
 + # flags
 + CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
 +diff -up dmenu-4.0/dmenu.1 dmenu-4.0-xft/dmenu.1
 +--- dmenu-4.0/dmenu.1	2009-04-18 07:50:04.000000000 -0400
 ++++ dmenu-4.0-xft/dmenu.1	2009-11-08 05:07:40.028951847 -0500
 +@@ -6,6 +6,7 @@ dmenu \- dynamic menu
 + .RB [ \-i ]
 + .RB [ \-b ]
 + .RB [ \-fn " <font>"]
 ++.RB [ \-fa " <xftfont>"]
 + .RB [ \-nb " <color>"]
 + .RB [ \-nf " <color>"]
 + .RB [ \-p " <prompt>"]
 +@@ -29,6 +30,9 @@ defines that dmenu appears at the bottom
 + .B \-fn <font>
 + defines the font.
 + .TP
 ++.B \-fa <font>
 ++defines the xft font.
 ++.TP
 + .B \-nb <color>
 + defines the normal background color (#RGB, #RRGGBB, and color names are supported).
 + .TP
 +diff -up dmenu-4.0/dmenu.c dmenu-4.0-xft/dmenu.c
 +--- dmenu-4.0/dmenu.c	2009-04-18 07:50:04.000000000 -0400
 ++++ dmenu-4.0-xft/dmenu.c	2009-11-08 05:50:32.962034661 -0500
 +@@ -13,6 +13,7 @@
 + #ifdef XINERAMA
 + #include <X11/extensions/Xinerama.h>
 + #endif
 ++#include <X11/Xft/Xft.h>
 + 
 + /* macros */
 + #define CLEANMASK(mask)         (mask & ~(numlockmask | LockMask))
 +@@ -27,6 +28,7 @@ typedef struct {
 + 	int x, y, w, h;
 + 	unsigned long norm[ColLast];
 + 	unsigned long sel[ColLast];
 ++	Bool selected;
 + 	Drawable drawable;
 + 	GC gc;
 + 	struct {
 +@@ -36,6 +38,16 @@ typedef struct {
 + 		int descent;
 + 		int height;
 + 	} font;
 ++	XftDraw *xftdraw;
 ++	XftColor xftselcolor;
 ++	XftColor xftcolor;
 ++	XGlyphInfo gi;
 ++	struct {
 ++		XftFont *xft_font;
 ++		int ascent;
 ++		int descent;
 ++		int height;
 ++	} xftfont;
 + } DC; /* draw context */
 + 
 + typedef struct Item Item;
 +@@ -160,9 +172,14 @@ cleanup(void) {
 + 		free(allitems);
 + 		allitems = itm;
 + 	}
 ++	if(fontxft) {
 ++		XftColorFree (dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), &dc.xftcolor);
 ++		XftFontClose (dpy, dc.xftfont.xft_font);
 ++		XftDrawDestroy(dc.xftdraw);
 ++	}
 + 	if(dc.font.set)
 + 		XFreeFontSet(dpy, dc.font.set);
 +-	else
 ++	else if(!fontxft)
 + 		XFreeFont(dpy, dc.font.xfont);
 + 	XFreePixmap(dpy, dc.drawable);
 + 	XFreeGC(dpy, dc.gc);
 +@@ -182,7 +199,9 @@ drawmenu(void) {
 + 	/* print prompt? */
 + 	if(promptw) {
 + 		dc.w = promptw;
 ++		dc.selected = True;
 + 		drawtext(prompt, dc.sel);
 ++		dc.selected = False;
 + 	}
 + 	dc.x += promptw;
 + 	dc.w = mw - promptw;
 +@@ -200,7 +219,13 @@ drawmenu(void) {
 + 			dc.w = textw(i->text);
 + 			if(dc.w > mw / 3)
 + 				dc.w = mw / 3;
 +-			drawtext(i->text, (sel == i) ? dc.sel : dc.norm);
 ++			if(sel == i) {
 ++				dc.selected = True;
 ++				drawtext(i->text, dc.sel);
 ++				dc.selected = False;
 ++			} else {
 ++				drawtext(i->text, dc.norm);
 ++			}
 + 			dc.x += dc.w;
 + 		}
 + 		dc.x = mw - spaceitem;
 +@@ -224,7 +249,11 @@ drawtext(const char *text, unsigned long
 + 	olen = strlen(text);
 + 	h = dc.font.ascent + dc.font.descent;
 + 	y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
 +-	x = dc.x + (h / 2);
 ++	if(dc.xftfont.xft_font) {	
 ++		h = dc.xftfont.ascent + dc.xftfont.descent;
 ++		y = dc.y + (dc.h / 2) - (h / 2) + dc.xftfont.ascent;
 ++	}
 ++    x = dc.x + (h / 2);
 + 	/* shorten text if necessary */
 + 	for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--);
 + 	if(!len)
 +@@ -233,7 +262,15 @@ drawtext(const char *text, unsigned long
 + 	if(len < olen)
 + 		for(i = len; i && i > len - 3; buf[--i] = '.');
 + 	XSetForeground(dpy, dc.gc, col[ColFG]);
 +-	if(dc.font.set)
 ++	if(fontxft) {
 ++		if (!dc.xftdraw)
 ++			eprint("error, creating xft drawable failed");
 ++		if(dc.selected) {
 ++			XftDrawString8(dc.xftdraw, &dc.xftselcolor, dc.xftfont.xft_font, x, y, (unsigned char*)buf, len);
 ++		} else {
 ++			XftDrawString8(dc.xftdraw, &dc.xftcolor, dc.xftfont.xft_font, x, y, (unsigned char*)buf, len);
 ++		}
 ++	} else 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);
 +@@ -253,7 +290,6 @@ unsigned long
 + getcolor(const char *colstr) {
 + 	Colormap cmap = DefaultColormap(dpy, screen);
 + 	XColor color;
 +-
 + 	if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
 + 		eprint("error, cannot allocate color '%s'\n", colstr);
 + 	return color.pixel;
 +@@ -309,6 +345,15 @@ initfont(const char *fontstr) {
 + }
 + 
 + void
 ++initxft() {
 ++	if(!(dc.xftfont.xft_font = XftFontOpenName (dpy, screen, fontxft)))
 ++		eprint("error, cannot load xft font\n" );
 ++	dc.xftfont.ascent = dc.xftfont.xft_font->ascent;
 ++	dc.xftfont.descent = dc.xftfont.xft_font->descent;
 ++	dc.xftfont.height = dc.xftfont.ascent + dc.xftfont.descent;
 ++}
 ++
 ++void
 + kpress(XKeyEvent * e) {
 + 	char buf[32];
 + 	int i, num;
 +@@ -589,7 +634,15 @@ setup(Bool topbar) {
 + 	dc.norm[ColFG] = getcolor(normfgcolor);
 + 	dc.sel[ColBG] = getcolor(selbgcolor);
 + 	dc.sel[ColFG] = getcolor(selfgcolor);
 +-	initfont(font);
 ++	dc.selected = False;
 ++	if(fontxft){
 ++		if(!XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), (const char*)normfgcolor, &dc.xftcolor))
 ++			eprint("error, cannot allocate xft font color '%s'\n", normfgcolor);
 ++		if(!XftColorAllocName(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), (const char*)selfgcolor, &dc.xftselcolor))
 ++			eprint("error, cannot allocate xft font color '%s'\n", normfgcolor);
 ++        else
 ++			initxft();
 ++	} else initfont(font);
 + 
 + 	/* menu window */
 + 	wa.override_redirect = True;
 +@@ -597,6 +650,9 @@ setup(Bool topbar) {
 + 	wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask;
 + 
 + 	/* menu window geometry */
 ++	if(fontxft) 
 ++		mh = dc.xftfont.height + 2;
 ++	else
 + 	mh = dc.font.height + 2;
 + #if XINERAMA
 + 	if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) {
 +@@ -632,7 +688,7 @@ setup(Bool topbar) {
 + 	dc.drawable = XCreatePixmap(dpy, root, mw, mh, DefaultDepth(dpy, screen));
 + 	dc.gc = XCreateGC(dpy, root, 0, NULL);
 + 	XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
 +-	if(!dc.font.set)
 ++	if(!dc.font.set && !fontxft)
 + 		XSetFont(dpy, dc.gc, dc.font.xfont->fid);
 + 	if(maxname)
 + 		cmdw = textw(maxname);
 +@@ -645,13 +701,20 @@ setup(Bool topbar) {
 + 	text[0] = 0;
 + 	match(text);
 + 	XMapRaised(dpy, win);
 ++	if(fontxft) {
 ++		dc.xftdraw = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy,screen), DefaultColormap(dpy,screen));
 ++		if(!dc.xftdraw)
 ++			eprint("error, cannot create xft drawable\n");
 ++	}
 + }
 + 
 + int
 + textnw(const char *text, unsigned int len) {
 +-	XRectangle r;
 +-
 +-	if(dc.font.set) {
 ++	if(fontxft) {
 ++		XftTextExtents8(dpy, dc.xftfont.xft_font, (const FcChar8*)text, len, &dc.gi);
 ++		return dc.gi.width;
 ++    } else if(dc.font.set) {
 ++	    XRectangle r;
 + 		XmbTextExtents(dc.font.set, text, len, NULL, &r);
 + 		return r.width;
 + 	}
 +@@ -660,6 +723,8 @@ textnw(const char *text, unsigned int le
 + 
 + int
 + textw(const char *text) {
 ++	if(fontxft)
 ++		return textnw(text, strlen(text)) + dc.xftfont.height;
 + 	return textnw(text, strlen(text)) + dc.font.height;
 + }
 + 
 +@@ -679,6 +744,9 @@ main(int argc, char *argv[]) {
 + 		else if(!strcmp(argv[i], "-fn")) {
 + 			if(++i < argc) font = argv[i];
 + 		}
 ++		else if(!strcmp(argv[i], "-fa")) {
 ++			if(++i < argc) fontxft = argv[i];
 ++		}
 + 		else if(!strcmp(argv[i], "-nb")) {
 + 			if(++i < argc) normbgcolor = argv[i];
 + 		}
 +@@ -697,7 +765,7 @@ main(int argc, char *argv[]) {
 + 		else if(!strcmp(argv[i], "-v"))
 + 			eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n");
 + 		else
 +-			eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n"
 ++			eprint("usage: dmenu [-i] [-b] [-fn <font>] [-fa <xftfont>] [-nb <color>] [-nf <color>]\n"
 + 			       "             [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n");
 + 	if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
 + 		fprintf(stderr, "warning: no locale support\n");
 diff -urN /usr/ports/x11/dmenu/files/patch-config.mk dmenu/files/patch-config.mk
 --- /usr/ports/x11/dmenu/files/patch-config.mk	2009-04-28 00:46:36.000000000 +0530
 +++ dmenu/files/patch-config.mk	2010-04-04 18:48:07.000000000 +0530
 @@ -1,36 +1,13 @@
 ---- config.mk.orig	2009-04-18 13:50:04.000000000 +0200
 -+++ config.mk	2009-04-21 13:15:36.000000000 +0200
 -@@ -4,11 +4,11 @@
 +--- ./config.mk.orig	2010-04-04 18:37:12.000000000 +0530
 ++++ ./config.mk	2010-04-04 18:37:36.000000000 +0530
 +@@ -4,8 +4,8 @@
   # Customize below to fit your system
   
   # paths
  -PREFIX = /usr/local
  -MANPREFIX = ${PREFIX}/share/man
 -+PREFIX?= /usr/local
 -+MANPREFIX = ${PREFIX}/man
 ++PREFIX = %%PREFIX%%
 ++MANPREFIX = %%MANPREFIX%%
   
 --X11INC = /usr/X11R6/include
 --X11LIB = /usr/X11R6/lib
 -+X11INC = $(LOCALBASE)/include
 -+X11LIB = $(LOCALBASE)/lib
 - 
 - # Xinerama, comment if you don't want it
 - XINERAMALIBS = -L${X11LIB} -lXinerama
 -@@ -19,13 +19,13 @@
 - LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS}
 - 
 - # flags
 --CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
 --CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
 --LDFLAGS = -s ${LIBS}
 -+CPPFLAGS+= -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
 -+CFLAGS+= -std=c99 ${INCS} ${CPPFLAGS}
 -+LDFLAGS+= ${LIBS}
 - 
 - # Solaris
 - #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
 - #LDFLAGS = ${LIBS}
 - 
 - # compiler and linker
 --CC = cc
 -+CC?= cc
 + X11INC = /usr/X11R6/include
 + X11LIB = /usr/X11R6/lib
 
 --=-=-=--



More information about the freebsd-ports-bugs mailing list