I don't understand at all how you can apply this embedded-into-body
patch with all tabs replaced by spaces and lines wrapped on 80.
What magic I need for this?

Anyway, reformatted patch cleanly applying to 0.7 in the attachment.
diff --git a/config.def.h b/config.def.h
index b41747f..638c3c5 100644
--- a/config.def.h
+++ b/config.def.h
@@ -1,11 +1,16 @@
 /* See LICENSE file for copyright and license details. */
 
-/*
- * appearance
- *
- * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
+/**
+ * Array of the primary font and fallback fonts. The first string in the array
+ * is the primary font while the rest of the fonts will be used as fallbacks
+ * when preceding fonts are missing a specific glyph. See
+ * http://freedesktop.org/software/fontconfig/fontconfig-user.html for more
+ * info on font definitions.
  */
-static char font[] = "Liberation 
Mono:pixelsize=12:antialias=true:autohint=true";
+static char *fonts[] = {
+       "Liberation Mono:pixelsize=12:antialias=true:autohint=true",
+};
+
 static int borderpx = 2;
 
 /*
diff --git a/st.c b/st.c
index 2594c65..f7973bd 100644
--- a/st.c
+++ b/st.c
@@ -353,10 +353,17 @@ typedef struct {
        FcPattern *pattern;
 } Font;
 
+typedef struct {
+       Font font;
+       Font bfont;
+       Font ifont;
+       Font ibfont;
+} FontFamily;
+
 /* Drawing Context */
 typedef struct {
        Color col[MAX(LEN(colorname), 256)];
-       Font font, bfont, ifont, ibfont;
+       FontFamily fontfamily;
        GC gc;
 } DC;
 
@@ -434,7 +441,7 @@ static void xloadcols(void);
 static int xsetcolorname(int, const char *);
 static int xgeommasktogravity(int);
 static int xloadfont(Font *, FcPattern *);
-static void xloadfonts(char *, double);
+static void xloadfonts(const char *, double);
 static void xsettitle(char *);
 static void xresettitle(void);
 static void xsetpointermotion(int);
@@ -533,7 +540,7 @@ static char *opt_name  = NULL;
 static char *opt_title = NULL;
 static int oldbutton   = 3; /* button event on startup: 3 = release */
 
-static char *usedfont = NULL;
+static const char *usedfont = NULL;
 static double usedfontsize = 0;
 static double defaultfontsize = 0;
 
@@ -542,6 +549,9 @@ static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 
0xF0, 0xF8};
 static Rune utfmin[UTF_SIZ + 1] = {       0,    0,  0x80,  0x800,  0x10000};
 static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
 
+static FontFamily fontfamilies[16];
+static int fontfamiliescount = 0;
+
 /* Font Ring Cache */
 enum {
        FRC_NORMAL,
@@ -3307,11 +3317,16 @@ xloadfont(Font *f, FcPattern *pattern)
 }
 
 void
-xloadfonts(char *fontstr, double fontsize)
+xloadfonts(const char *fontstr, double fontsize)
 {
        FcPattern *pattern;
        double fontval;
        float ceilf(float);
+       FontFamily fontfamily;
+
+       if (fontfamiliescount >= LEN(fontfamilies)) {
+               die("Font family array is full.\n");
+       }
 
        if (fontstr[0] == '-') {
                pattern = XftXlfdParse(fontstr, False, False);
@@ -3345,37 +3360,43 @@ xloadfonts(char *fontstr, double fontsize)
                defaultfontsize = usedfontsize;
        }
 
-       if (xloadfont(&dc.font, pattern))
+       if (xloadfont(&fontfamily.font, pattern))
                die("st: can't open font %s\n", fontstr);
 
        if (usedfontsize < 0) {
-               FcPatternGetDouble(dc.font.match->pattern,
+               FcPatternGetDouble(fontfamily.font.match->pattern,
                                   FC_PIXEL_SIZE, 0, &fontval);
                usedfontsize = fontval;
                if (fontsize == 0)
                        defaultfontsize = fontval;
        }
 
-       /* Setting character width and height. */
-       xw.cw = ceilf(dc.font.width * cwscale);
-       xw.ch = ceilf(dc.font.height * chscale);
-
        FcPatternDel(pattern, FC_SLANT);
        FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
-       if (xloadfont(&dc.ifont, pattern))
+       if (xloadfont(&fontfamily.ifont, pattern))
                die("st: can't open font %s\n", fontstr);
 
        FcPatternDel(pattern, FC_WEIGHT);
        FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
-       if (xloadfont(&dc.ibfont, pattern))
+       if (xloadfont(&fontfamily.ibfont, pattern))
                die("st: can't open font %s\n", fontstr);
 
        FcPatternDel(pattern, FC_SLANT);
        FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
-       if (xloadfont(&dc.bfont, pattern))
+       if (xloadfont(&fontfamily.bfont, pattern))
                die("st: can't open font %s\n", fontstr);
 
        FcPatternDestroy(pattern);
+
+       /* Setting character width and height. */
+       if (!fontfamiliescount) {
+               xw.cw = ceilf(fontfamily.font.width * cwscale);
+               xw.ch = ceilf(fontfamily.font.height * chscale);
+               dc.fontfamily = fontfamily;
+               usedfont = fontstr;
+       }
+
+       fontfamilies[fontfamiliescount++] = fontfamily;
 }
 
 void
@@ -3394,10 +3415,13 @@ xunloadfonts(void)
        while (frclen > 0)
                XftFontClose(xw.dpy, frc[--frclen].font);
 
-       xunloadfont(&dc.font);
-       xunloadfont(&dc.bfont);
-       xunloadfont(&dc.ifont);
-       xunloadfont(&dc.ibfont);
+       while (fontfamiliescount > 0) {
+               fontfamiliescount--;
+               xunloadfont(&fontfamilies[fontfamiliescount].font);
+               xunloadfont(&fontfamilies[fontfamiliescount].bfont);
+               xunloadfont(&fontfamilies[fontfamiliescount].ifont);
+               xunloadfont(&fontfamilies[fontfamiliescount].ibfont);
+       }
 }
 
 void
@@ -3434,6 +3458,8 @@ xzoomreset(const Arg *arg)
 void
 xinit(void)
 {
+       int i;
+
        XGCValues gcvalues;
        Cursor cursor;
        Window parent;
@@ -3449,8 +3475,13 @@ xinit(void)
        if (!FcInit())
                die("Could not init fontconfig.\n");
 
-       usedfont = (opt_font == NULL)? font : opt_font;
-       xloadfonts(usedfont, 0);
+       if (opt_font) {
+               xloadfonts(opt_font, 0);
+       }
+
+       for (i = 0; i < LEN(fonts); i++) {
+               xloadfonts(fonts[i], 0);
+       }
 
        /* colors */
        xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
@@ -3546,9 +3577,9 @@ xinit(void)
 int
 xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int 
x, int y)
 {
-       float winx = borderpx + x * xw.cw, winy = borderpx + y * xw.ch, xp, yp;
-       ushort mode, prevmode = USHRT_MAX;
-       Font *font = &dc.font;
+       float winx = borderpx + x * xw.cw, winy = borderpx + y * xw.ch, xp;
+       ushort mode;
+       Font *font, *reference = NULL;
        int frcflags = FRC_NORMAL;
        float runewidth = xw.cw;
        Rune rune;
@@ -3559,7 +3590,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph 
*glyphs, int len, int x
        FcCharSet *fccharset;
        int i, f, numspecs = 0;
 
-       for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) {
+       for (i = 0, xp = winx; i < len; ++i) {
                /* Fetch rune and mode for current glyph. */
                rune = glyphs[i].u;
                mode = glyphs[i].mode;
@@ -3568,32 +3599,33 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const 
Glyph *glyphs, int len, int x
                if (mode == ATTR_WDUMMY)
                        continue;
 
-               /* Determine font for glyph if different from previous glyph. */
-               if (prevmode != mode) {
-                       prevmode = mode;
-                       font = &dc.font;
+               /* Lookup character index within user-defined fonts. */
+               for (glyphidx = 0, f = 0; f < fontfamiliescount && !glyphidx; 
f++) {
+                       font = &fontfamilies[f].font;
                        frcflags = FRC_NORMAL;
                        runewidth = xw.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f);
                        if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) {
-                               font = &dc.ibfont;
+                               font = &fontfamilies[f].ibfont;
                                frcflags = FRC_ITALICBOLD;
                        } else if (mode & ATTR_ITALIC) {
-                               font = &dc.ifont;
+                               font = &fontfamilies[f].ifont;
                                frcflags = FRC_ITALIC;
                        } else if (mode & ATTR_BOLD) {
-                               font = &dc.bfont;
+                               font = &fontfamilies[f].bfont;
                                frcflags = FRC_BOLD;
                        }
-                       yp = winy + font->ascent;
+
+                       if (!f) {
+                               reference = font;
+                       }
+                       glyphidx = XftCharIndex(xw.dpy, font->match, rune);
                }
 
-               /* Lookup character index with default font. */
-               glyphidx = XftCharIndex(xw.dpy, font->match, rune);
                if (glyphidx) {
                        specs[numspecs].font = font->match;
                        specs[numspecs].glyph = glyphidx;
                        specs[numspecs].x = (short)xp;
-                       specs[numspecs].y = (short)yp;
+                       specs[numspecs].y = (short) (winy + font->ascent);
                        xp += runewidth;
                        numspecs++;
                        continue;
@@ -3612,12 +3644,14 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const 
Glyph *glyphs, int len, int x
                        }
                }
 
-               /* Nothing was found. Use fontconfig to find matching font. */
+               /* Nothing was found. Use fontconfig to find matching font 
using the
+                * default font as the reference font.
+                */
                if (f >= frclen) {
-                       if (!font->set)
-                               font->set = FcFontSort(0, font->pattern,
-                                                      1, 0, &fcres);
-                       fcsets[0] = font->set;
+                       if (!reference->set)
+                               reference->set = FcFontSort(0, 
reference->pattern,
+                                                           1, 0, &fcres);
+                       fcsets[0] = reference->set;
 
                        /*
                         * Nothing was found in the cache. Now use
@@ -3626,7 +3660,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph 
*glyphs, int len, int x
                         *
                         * Xft and fontconfig are design failures.
                         */
-                       fcpattern = FcPatternDuplicate(font->pattern);
+                       fcpattern = FcPatternDuplicate(reference->pattern);
                        fccharset = FcCharSetCreate();
 
                        FcCharSetAddChar(fccharset, rune);
@@ -3667,7 +3701,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph 
*glyphs, int len, int x
                specs[numspecs].font = frc[f].font;
                specs[numspecs].glyph = glyphidx;
                specs[numspecs].x = (short)xp;
-               specs[numspecs].y = (short)yp;
+               specs[numspecs].y = (short) (winy + frc[f].font->ascent);
                xp += runewidth;
                numspecs++;
        }
@@ -3796,12 +3830,12 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, 
Glyph base, int len, int x, i
 
        /* Render underline and strikethrough. */
        if (base.mode & ATTR_UNDERLINE) {
-               XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1,
+               XftDrawRect(xw.draw, fg, winx, winy + dc.fontfamily.font.ascent 
+ 1,
                                width, 1);
        }
 
        if (base.mode & ATTR_STRUCK) {
-               XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3,
+               XftDrawRect(xw.draw, fg, winx, winy + 2 * 
dc.fontfamily.font.ascent / 3,
                                width, 1);
        }
 

Reply via email to