st

fork of suckless's simple terminal
Index Commits Files Refs README LICENSE
commit 034a5c8a09e23ce0a410d0c608dd7e050b83681e
parent 30440295bc054f37a2a8275acca769cd83bcb780
Author: Ryusei Yamaguchi <mandel59@gmail.com>
Date:   Tue,  8 Mar 2016 12:26:04 +0900

Measure the single advance width with a heuristic method

This fix is needed to use dual-width fonts, which have double-width
glyphs (e.g. CJK unified ideographs).

Signed-off-by: Ryusei Yamaguchi <mandel59@gmail.com>
Signed-off-by: Christoph Lohmann <20h@r-36.net>

Diffstat:
Mconfig.def.h | 8++++++++
Mst.c | 8+++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/config.def.h b/config.def.h
@@ -417,3 +417,11 @@ static uint selmasks[] = {
     [SEL_RECTANGULAR] = Mod1Mask,
 };
 
+/*
+ * Printable characters in ASCII, used to estimate the advance width
+ * of single wide characters.
+ */
+static char ascii_printable[] =
+    " !\"#$%&'()*+,-./0123456789:;<=>?"
+    "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
+    "`abcdefghijklmnopqrstuvwxyz{|}~";
diff --git a/st.c b/st.c
@@ -68,6 +68,7 @@ char *argv0;
 #define LEN(a)            (sizeof(a) / sizeof(a)[0])
 #define DEFAULT(a, b)        (a) = (a) ? (a) : (b)
 #define BETWEEN(x, a, b)    ((a) <= (x) && (x) <= (b))
+#define DIVCEIL(n, d)        (((n) + ((d) - 1)) / (d))
 #define ISCONTROLC0(c)        (BETWEEN(c, 0, 0x1f) || (c) == '\177')
 #define ISCONTROLC1(c)        (BETWEEN(c, 0x80, 0x9f))
 #define ISCONTROL(c)        (ISCONTROLC0(c) || ISCONTROLC1(c))
@@ -3277,6 +3278,7 @@ xloadfont(Font *f, FcPattern *pattern)
 {
     FcPattern *match;
     FcResult result;
+    XGlyphInfo extents;
 
     match = FcFontMatch(NULL, pattern, &result);
     if (!match)
@@ -3287,6 +3289,10 @@ xloadfont(Font *f, FcPattern *pattern)
         return 1;
     }
 
+    XftTextExtentsUtf8(xw.dpy, f->match,
+        (const FcChar8 *) ascii_printable,
+        LEN(ascii_printable), &extents);
+
     f->set = NULL;
     f->pattern = FcPatternDuplicate(pattern);
 
@@ -3296,7 +3302,7 @@ xloadfont(Font *f, FcPattern *pattern)
     f->rbearing = f->match->max_advance_width;
 
     f->height = f->ascent + f->descent;
-    f->width = f->lbearing + f->rbearing;
+    f->width = DIVCEIL(extents.xOff, LEN(ascii_printable));
 
     return 0;
 }