[wiki] [sites] Pango support for dwm statusbar. || memeplex

From: <git_AT_suckless.org>
Date: Mon, 30 Dec 2013 20:17:43 +0100

commit 8bfa47e727e9dce8981e217dc6a4632952e6dfb1
Author: memeplex <carlosjosepita_AT_gmail.com>
Date: Mon Dec 30 16:17:01 2013 -0300

    Pango support for dwm statusbar.

diff --git a/dwm.suckless.org/patches/dwm-6.0-pango.diff b/dwm.suckless.org/patches/dwm-6.0-pango.diff
new file mode 100644
index 0000000..77230c7
--- /dev/null
+++ b/dwm.suckless.org/patches/dwm-6.0-pango.diff
_AT_@ -0,0 +1,246 @@
+diff --git a/config.def.h b/config.def.h
+index 77ff358..4c266bb 100644
+--- a/config.def.h
++++ b/config.def.h
+_AT_@ -1,7 +1,7 @@
+ /* See LICENSE file for copyright and license details. */
+
+ /* appearance */
+-static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*";
++static const char font[] = "Sans 8";
+ static const char normbordercolor[] = "#444444";
+ static const char normbgcolor[] = "#222222";
+ static const char normfgcolor[] = "#bbbbbb";
+diff --git a/config.mk b/config.mk
+index 484554a..cdfb642 100644
+--- a/config.mk
++++ b/config.mk
+_AT_@ -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/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 --git a/dwm.c b/dwm.c
+index 1d78655..d441ba2 100644
+--- a/dwm.c
++++ b/dwm.c
+_AT_@ -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 /* XINERAMA */
+_AT_@ -47,8 +51,12 @@
+ * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
+ #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->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 MOUSEMASK (BUTTONMASK|PointerMotionMask)
+ #define WIDTH(X) ((X)->w + 2 * (X)->bw)
+ #define HEIGHT(X) ((X)->h + 2 * (X)->bw)
+_AT_@ -103,12 +111,16 @@ typedef struct {
+ unsigned long sel[ColLast];
+ Drawable drawable;
+ GC gc;
++ XftColor xftnorm[ColLast];
++ XftColor xftsel[ColLast];
++ XftDraw *xftdrawable;
+ struct {
+ int ascent;
+ int descent;
+ int height;
+- XFontSet set;
+- XFontStruct *xfont;
++ PangoContext *pgc;
++ PangoLayout *plo;
++ PangoFontDescription *pfd;
+ } font;
+ } DC; /* draw context */
+
+_AT_@ -186,7 +198,7 @@ static void focus(Client *c);
+ static void focusin(XEvent *e);
+ static void focusmon(const Arg *arg);
+ static void focusstack(const Arg *arg);
+-static unsigned long getcolor(const char *colstr);
++//static unsigned long getcolor(const char *colstr);
+ static Bool getrootptr(int *x, int *y);
+ static long getstate(Window w);
+ static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
+_AT_@ -485,10 +497,6 @@ cleanup(void) {
+ for(m = mons; m; m = m->next)
+ while(m->stack)
+ unmanage(m->stack, False);
+- 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);
+_AT_@ -581,6 +589,7 @@ configurenotify(XEvent *e) {
+ if(dc.drawable != 0)
+ XFreePixmap(dpy, dc.drawable);
+ dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
++ XftDrawChange(dc.xftdrawable, dc.drawable);
+ updatebars();
+ for(m = mons; m; m = m->next)
+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
+_AT_@ -796,7 +805,7 @@ drawtext(const char *text, unsigned long col[ColLast], Bool invert) {
+ 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 + (dc.h / 2) - (h / 2);
+ x = dc.x + (h / 2);
+ /* shorten text if necessary */
+ for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--);
+_AT_@ -805,11 +814,10 @@ drawtext(const char *text, unsigned long col[ColLast], Bool invert) {
+ 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.font.plo, text, len);
++ pango_xft_render_layout(dc.xftdrawable,
++ (col == dc.norm? dc.xftnorm : dc.xftsel) + (invert? ColBG : ColFG),
++ dc.font.plo, x * PANGO_SCALE, y * PANGO_SCALE);
+ }
+
+ void
+_AT_@ -927,13 +935,13 @@ getatomprop(Client *c, Atom prop) {
+ }
+
+ 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'
", colstr);
+- return color.pixel;
++ return color->pixel;
+ }
+
+ Bool
+_AT_@ -1034,35 +1042,19 @@ incnmaster(const Arg *arg) {
+
+ void
+ initfont(const char *fontstr) {
+- char *def, **missing;
+- int n;
++ PangoFontMetrics *metrics;
+
+- dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
+- if(missing) {
+- while(n--)
+- fprintf(stderr, "dwm: missing fontset: %s
", missing[n]);
+- XFreeStringList(missing);
+- }
+- if(dc.font.set) {
+- XFontStruct **xfonts;
+- char **font_names;
+-
+- dc.font.ascent = dc.font.descent = 0;
+- XExtentsOfFontSet(dc.font.set);
+- n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
+- while(n--) {
+- 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'
", fontstr);
+- dc.font.ascent = dc.font.xfont->ascent;
+- dc.font.descent = dc.font.xfont->descent;
+- }
++ dc.font.pgc = pango_xft_get_context(dpy, screen);
++ dc.font.pfd = pango_font_description_from_string(fontstr);
++
++ metrics = pango_context_get_metrics(dc.font.pgc, dc.font.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.font.plo = pango_layout_new(dc.font.pgc);
++ pango_layout_set_font_description(dc.font.plo, dc.font.pfd);
+ dc.font.height = dc.font.ascent + dc.font.descent;
+ }
+
+_AT_@ -1611,19 +1603,24 @@ setup(void) {
+ cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
+ cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
+ 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);
+- /* init bars */
++
++ dc.xftdrawable = XftDrawCreate(dpy, dc.drawable, DefaultVisual(dpy,screen), DefaultColormap(dpy,screen));
++ if(!dc.xftdrawable)
++ printf("error, cannot create drawable
");
++
++ /* init bar */
+ updatebars();
+ updatestatus();
+ /* EWMH support per view */
+_AT_@ -1692,13 +1689,10 @@ tagmon(const Arg *arg) {
+
+ 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.font.plo, text, len);
++ pango_layout_get_extents(dc.font.plo, &r, 0);
++ return r.width / PANGO_SCALE;
+ }
+
+ void
diff --git a/dwm.suckless.org/patches/pango.md b/dwm.suckless.org/patches/pango.md
new file mode 100644
index 0000000..6acae98
--- /dev/null
+++ b/dwm.suckless.org/patches/pango.md
_AT_@ -0,0 +1,30 @@
+Pango
+=====
+
+Description
+-----------
+
+This patch adds pango support for the status bar.
+
+I find pango a better alternative than xft because it supports chains of fallback fonts
+out of the box, so you can use -for example- iconic fonts as your second family: "DejaVu
+Sans, Icons 8". The Icons family is a non-overlapping merge of Awesome and Ionicons fonts
+I've made for my statusbar. In case you're interested:
+https://aur.archlinux.org/packages/ttf-font-icons/ (there is a cheatsheet with the icons
+and their unicode points linked there).
+
+This is not achievable using xft without further effort. Don't be mislead by the fact that
+fontconfig understands descriptors like "DejaVu Sans, Icons-8" or even font sequences
+defined as alias in your fonts.conf. xft will pick one font once and for all, not on a
+char-by-char basis.
+
+Download
+--------
+
+* [dwm-6.0-pango.diff](dwm-6.0-pango.diff) (8.3k) (30 Dec 2013)
+
+Author
+------
+
+* Carlos Pita (memeplex)<carlosjosepita_AT_gmail.com> (I just polished and fixed a patch that
+ I found around the web).
Received on Mon Dec 30 2013 - 20:17:43 CET

This archive was generated by hypermail 2.3.0 : Thu Jun 18 2015 - 17:38:02 CEST