Kaynağa Gözat

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>
Ryusei Yamaguchi 9 yıl önce
ebeveyn
işleme
034a5c8a09
2 değiştirilmiş dosya ile 15 ekleme ve 1 silme
  1. 8 0
      config.def.h
  2. 7 1
      st.c

+ 8 - 0
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{|}~";

+ 7 - 1
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;
 }