The following patch is simplification only.  It puts rune lookup directly into the function that does font loading. I have a forthcoming patch that sits on top of this that fixes a rare crash situation.  This one stands alone, and because it overall removes code I feel it should be considered separately from my future submission.

Simplification.  Add rune negotiation directly to function xloadfont, removing some code from xmakeglyphfontspecs that was being done again in xloadfont anyway.



diff -U 3 a/x.c b/x.c
--- a/x.c       2018-03-21 12:23:59.111455300 -0400
+++ b/x.c       2018-03-21 12:34:14.539156700 -0400
@@ -144,7 +144,7 @@
 static void xresize(int, int);
 static void xhints(void);
 static int xloadcolor(int, const char *, Color *);
-static int xloadfont(Font *, FcPattern *);
+static int xloadfont(Font *, FcPattern *, Rune);
 static void xloadfonts(char *, double);
 static void xunloadfont(Font *);
 static void xunloadfonts(void);
@@ -828,10 +828,11 @@
 }

 int
-xloadfont(Font *f, FcPattern *pattern)
+xloadfont(Font *f, FcPattern *pattern, Rune rune)
 {
        FcPattern *configured;
        FcPattern *match;
+       FcCharSet *fccharset = NULL;
        FcResult result;
        XGlyphInfo extents;
        int wantattr, haveattr;
@@ -845,18 +846,31 @@
        if (!configured)
                return 1;

+       if (rune) {
+               fccharset = FcCharSetCreate();
+
+               FcCharSetAddChar(fccharset, rune);
+               FcPatternAddCharSet(configured, FC_CHARSET,
+                                   fccharset);
+               FcPatternAddBool(configured, FC_SCALABLE, 1);
+       }
+
        FcConfigSubstitute(NULL, configured, FcMatchPattern);
        XftDefaultSubstitute(xw.dpy, xw.scr, configured);

        match = FcFontMatch(NULL, configured, &result);
        if (!match) {
                FcPatternDestroy(configured);
+               if (fccharset)
+                       FcCharSetDestroy(fccharset);
                return 1;
        }

        if (!(f->match = XftFontOpenPattern(xw.dpy, match))) {
                FcPatternDestroy(configured);
                FcPatternDestroy(match);
+               if (fccharset)
+                       FcCharSetDestroy(fccharset);
                return 1;
        }

@@ -897,6 +911,9 @@
        f->height = f->ascent + f->descent;
        f->width = DIVCEIL(extents.xOff, strlen(ascii_printable));

+       if (fccharset)
+               FcCharSetDestroy(fccharset);
+
        return 0;
 }

@@ -938,7 +955,7 @@
                defaultfontsize = usedfontsize;
        }

-       if (xloadfont(&dc.font, pattern))
+       if (xloadfont(&dc.font, pattern, 0))
                die("st: can't open font %s\n", fontstr);

        if (usedfontsize < 0) {
@@ -955,17 +972,17 @@

        FcPatternDel(pattern, FC_SLANT);
        FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
-       if (xloadfont(&dc.ifont, pattern))
+       if (xloadfont(&dc.ifont, pattern, 0))
                die("st: can't open font %s\n", fontstr);

        FcPatternDel(pattern, FC_WEIGHT);
        FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
-       if (xloadfont(&dc.bfont, pattern))
+       if (xloadfont(&dc.bfont, pattern, 0))
                die("st: can't open font %s\n", fontstr);

        FcPatternDestroy(pattern);
@@ -1123,14 +1140,11 @@
        float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp;
        ushort mode, prevmode = USHRT_MAX;
        Font *font = &dc.font;
+       Font newFont;
        int frcflags = FRC_NORMAL;
        float runewidth = win.cw;
        Rune rune;
        FT_UInt glyphidx;
-       FcResult fcres;
-       FcPattern *fcpattern, *fontpattern;
-       FcFontSet *fcsets[] = { NULL };
-       FcCharSet *fccharset;
        int i, f, numspecs = 0;

        for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) {
@@ -1188,33 +1202,6 @@

                /* Nothing was found. Use fontconfig to find matching font. */
                if (f >= frclen) {
-                       if (!font->set)
-                               font->set = FcFontSort(0, font->pattern,
-                                                      1, 0, &fcres);
-                       fcsets[0] = font->set;
-
-                       /*
-                        * Nothing was found in the cache. Now use
-                        * some dozen of Fontconfig calls to get the
-                        * font for one single character.
-                        *
-                        * Xft and fontconfig are design failures.
-                        */
-                       fcpattern = FcPatternDuplicate(font->pattern);
-                       fccharset = FcCharSetCreate();
-
-                       FcCharSetAddChar(fccharset, rune);
-                       FcPatternAddCharSet(fcpattern, FC_CHARSET,
-                                       fccharset);
-                       FcPatternAddBool(fcpattern, FC_SCALABLE, 1);
-
-                       FcConfigSubstitute(0, fcpattern,
-                                       FcMatchPattern);
-                       FcDefaultSubstitute(fcpattern);
-
-                       fontpattern = FcFontSetMatch(0, fcsets, 1,
-                                       fcpattern, &fcres);
-
                        /*
                         * Overwrite or create the new cache entry.
                         */
@@ -1224,11 +1211,18 @@
                                frc[frclen].unicodep = 0;
                        }

-                       frc[frclen].font = XftFontOpenPattern(xw.dpy,
-                                       fontpattern);
-                       if (!frc[frclen].font)
-                               die("XftFontOpenPattern failed seeking fallback
font: %s\n",
-                                       strerror(errno));
+                       /*
+                        * Nothing was found in the cache. Now use
+                        * some dozen of Fontconfig calls to get the
+                        * font for one single character.
+                        *
+                        * Xft and fontconfig are design failures.
+                        */
+                       if (xloadfont(&newFont, font->pattern, rune)) {
+                               die("st: failed seeking fallback font: %s\n",
+                                       strerror(errno));
+                       }
+                       frc[frclen].font = newFont.match;
                        frc[frclen].flags = frcflags;
                        frc[frclen].unicodep = rune;

@@ -1236,9 +1230,6 @@

                        f = frclen;
                        frclen++;
-
-                       FcPatternDestroy(fcpattern);
-                       FcCharSetDestroy(fccharset);
                }

                specs[numspecs].font = frc[f].font;


Reply via email to