add second font suport - st - personal variant of st
 (HTM) git clone https://git.drkhsh.at/st.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 24ec170b2a6ad4f9ca9b92a18fb20716542743b8
 (DIR) parent abd2f3eea5bd3fd9ffb13dbe41b51bef91bf5d0f
 (HTM) Author: drkhsh <me@drkhsh.at>
       Date:   Sun, 23 Apr 2023 17:57:22 +0200
       
       add second font suport
       
       This patch allows to add spare font besides default. Some glyphs
       can be not present in default font. For this glyphs st uses
       font-config and try to find them in font cache first. This patch
       append fonts defined in font2 variable to the beginning of font cache.
       So they will be used first for glyphs that absent in default font.
       
       https://st.suckless.org/patches/font2/
       
       Diffstat:
         M config.def.h                        |       6 ++++++
         M x.c                                 |     101 +++++++++++++++++++++++++++++++
       
       2 files changed, 107 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/config.def.h b/config.def.h
       @@ -6,6 +6,12 @@
         * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
         */
        static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
       +/* Spare fonts */
       +static char *font2[] = {
       +/*        "Inconsolata for Powerline:pixelsize=12:antialias=true:autohint=true", */
       +/*        "Hack Nerd Font Mono:pixelsize=11:antialias=true:autohint=true", */
       +};
       +
        static int borderpx = 2;
        
        /*
 (DIR) diff --git a/x.c b/x.c
       @@ -157,6 +157,8 @@ static void xhints(void);
        static int xloadcolor(int, const char *, Color *);
        static int xloadfont(Font *, FcPattern *);
        static void xloadfonts(const char *, double);
       +static int xloadsparefont(FcPattern *, int);
       +static void xloadsparefonts(void);
        static void xunloadfont(Font *);
        static void xunloadfonts(void);
        static void xsetenv(void);
       @@ -306,6 +308,7 @@ zoomabs(const Arg *arg)
        {
                xunloadfonts();
                xloadfonts(usedfont, arg->f);
       +        xloadsparefonts();
                cresize(0, 0);
                redraw();
                xhints();
       @@ -1051,6 +1054,101 @@ xloadfonts(const char *fontstr, double fontsize)
                FcPatternDestroy(pattern);
        }
        
       +int
       +xloadsparefont(FcPattern *pattern, int flags)
       +{
       +        FcPattern *match;
       +        FcResult result;
       +
       +        match = FcFontMatch(NULL, pattern, &result);
       +        if (!match) {
       +                return 1;
       +        }
       +
       +        if (!(frc[frclen].font = XftFontOpenPattern(xw.dpy, match))) {
       +                FcPatternDestroy(match);
       +                return 1;
       +        }
       +
       +        frc[frclen].flags = flags;
       +        /* Believe U+0000 glyph will present in each default font */
       +        frc[frclen].unicodep = 0;
       +        frclen++;
       +
       +        return 0;
       +}
       +
       +void
       +xloadsparefonts(void)
       +{
       +        FcPattern *pattern;
       +        double sizeshift, fontval;
       +        int fc;
       +        char **fp;
       +
       +        if (frclen != 0)
       +                die("can't embed spare fonts. cache isn't empty");
       +
       +        /* Calculate count of spare fonts */
       +        fc = sizeof(font2) / sizeof(*font2);
       +        if (fc == 0)
       +                return;
       +
       +        /* Allocate memory for cache entries. */
       +        if (frccap < 4 * fc) {
       +                frccap += 4 * fc - frccap;
       +                frc = xrealloc(frc, frccap * sizeof(Fontcache));
       +        }
       +
       +        for (fp = font2; fp - font2 < fc; ++fp) {
       +
       +                if (**fp == '-')
       +                        pattern = XftXlfdParse(*fp, False, False);
       +                else
       +                        pattern = FcNameParse((FcChar8 *)*fp);
       +
       +                if (!pattern)
       +                        die("can't open spare font %s\n", *fp);
       +
       +                if (defaultfontsize > 0) {
       +                        sizeshift = usedfontsize - defaultfontsize;
       +                        if (sizeshift != 0 &&
       +                                        FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) ==
       +                                        FcResultMatch) {
       +                                fontval += sizeshift;
       +                                FcPatternDel(pattern, FC_PIXEL_SIZE);
       +                                FcPatternDel(pattern, FC_SIZE);
       +                                FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval);
       +                        }
       +                }
       +
       +                FcPatternAddBool(pattern, FC_SCALABLE, 1);
       +
       +                FcConfigSubstitute(NULL, pattern, FcMatchPattern);
       +                XftDefaultSubstitute(xw.dpy, xw.scr, pattern);
       +
       +                if (xloadsparefont(pattern, FRC_NORMAL))
       +                        die("can't open spare font %s\n", *fp);
       +
       +                FcPatternDel(pattern, FC_SLANT);
       +                FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
       +                if (xloadsparefont(pattern, FRC_ITALIC))
       +                        die("can't open spare font %s\n", *fp);
       +
       +                FcPatternDel(pattern, FC_WEIGHT);
       +                FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
       +                if (xloadsparefont(pattern, FRC_ITALICBOLD))
       +                        die("can't open spare font %s\n", *fp);
       +
       +                FcPatternDel(pattern, FC_SLANT);
       +                FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
       +                if (xloadsparefont(pattern, FRC_BOLD))
       +                        die("can't open spare font %s\n", *fp);
       +
       +                FcPatternDestroy(pattern);
       +        }
       +}
       +
        void
        xunloadfont(Font *f)
        {
       @@ -1148,6 +1246,9 @@ xinit(int cols, int rows)
                usedfont = (opt_font == NULL)? font : opt_font;
                xloadfonts(usedfont, 0);
        
       +        /* spare fonts */
       +        xloadsparefonts();
       +
                /* colors */
                xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
                xloadcols();