commit 034a5c8a09e23ce0a410d0c608dd7e050b83681e from: Ryusei Yamaguchi via: Christoph Lohmann <20h@r-36.net> date: Tue Mar 8 12:46:42 2016 UTC 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 Signed-off-by: Christoph Lohmann <20h@r-36.net> commit - 30440295bc054f37a2a8275acca769cd83bcb780 commit + 034a5c8a09e23ce0a410d0c608dd7e050b83681e blob - fd09d72b7cde7e477b66a08ce0a40175ff72f288 blob + a1e7d5a9cc9b4338a211e9031a3e64cb4c9c49a4 --- config.def.h +++ 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{|}~"; blob - 2473af7b44b01fcb7d62d45f7b1ce749c7bf4c52 blob + ca126d7448962d2a4bd175715aa6a184c0522341 --- st.c +++ 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; }