[dev] [st] [patch] Move font/rune negotiation

From: Gary Allen Vollink <gary_AT_vollink.com>
Date: Wed, 21 Mar 2018 12:57:08 -0400

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
_AT_@ -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);
_AT_@ -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;
_AT_@ -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;
         }

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

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

_AT_@ -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) {
_AT_@ -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);
_AT_@ -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) {
_AT_@ -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.
                          */
_AT_@ -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;

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

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

                 specs[numspecs].font = frc[f].font;
Received on Wed Mar 21 2018 - 17:57:08 CET

This archive was generated by hypermail 2.3.0 : Wed Mar 21 2018 - 18:00:22 CET