From 08d3749a636f9cd51f70ba1eed043be8e6c2eca9 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Tue, 5 Oct 2021 16:57:55 -0700 Subject: feat(term): added ligature support. some combining character help --- sys/cmd/term/x.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'sys/cmd/term/x.c') diff --git a/sys/cmd/term/x.c b/sys/cmd/term/x.c index 308478f..3079f38 100644 --- a/sys/cmd/term/x.c +++ b/sys/cmd/term/x.c @@ -11,6 +11,10 @@ #include #include +/* harfbuzz additions */ +void hbunloadfonts(); +void hbtransform(XftGlyphFontSpec *, const Letter*, size_t, int, int); + /* types used in config.h */ typedef struct Shortcut Shortcut; typedef struct MouseShortcut MouseShortcut; @@ -1021,6 +1025,8 @@ xunloadfont(Font *f) void xunloadfonts(void) { + hbunloadfonts(); + /* Free the loaded fonts in the font cache. */ while (frclen > 0) XftFontClose(xw.dpy, frc[--frclen].font); @@ -1223,17 +1229,17 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, Letter *glyphs, int len, int x, int FcCharSet *fccharset; int i, f, numspecs = 0; - for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) { + for(i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) { /* Fetch rune and mode for current glyph. */ r = glyphs[i].u; mode = glyphs[i].mode; /* Skip dummy wide-character spacing. */ - if (mode == Gwdummy) + if(mode & Gwdummy) continue; /* Determine font for glyph if different from previous glyph. */ - if (prevmode != mode) { + if(prevmode != mode) { prevmode = mode; font = &dc.font; frcflags = FRC_NORMAL; @@ -1251,9 +1257,9 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, Letter *glyphs, int len, int x, int yp = winy + font->ascent; } - /* Lookup character index with default font. */ + /* lookup character index with default font. */ glyphidx = XftCharIndex(xw.dpy, font->match, r); - if (glyphidx) { + if(glyphidx) { specs[numspecs].font = font->match; specs[numspecs].glyph = glyphidx; specs[numspecs].x = (short)xp; @@ -1264,7 +1270,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, Letter *glyphs, int len, int x, int } /* Fallback on font cache, search the font cache for match. */ - for (f = 0; f < frclen; f++) { + for(f = 0; f < frclen; f++) { glyphidx = XftCharIndex(xw.dpy, frc[f].font, r); /* Everything correct. */ if (glyphidx && frc[f].flags == frcflags) @@ -1277,7 +1283,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, Letter *glyphs, int len, int x, int } /* Nothing was found. Use fontconfig to find matching font. */ - if (f >= frclen) { + if(f >= frclen) { if (!font->set) font->set = FcFontSort(0, font->pattern, 1, 0, &fcres); @@ -1336,6 +1342,8 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, Letter *glyphs, int len, int x, int numspecs++; } + hbtransform(specs, glyphs, len, x, y); + return numspecs; } @@ -1474,16 +1482,16 @@ xdrawglyph(Letter g, int x, int y) } void -xdrawcursor(int cx, int cy, Letter g, int ox, int oy, Letter og) +xdrawcursor(int cx, int cy, Letter g, int ox, int oy, Letter og, Letter *line, int len) { Color drawcol; /* remove the old cursor */ - if (selected(ox, oy)) + if(selected(ox, oy)) og.mode ^= Greverse; - xdrawglyph(og, ox, oy); + xdrawline(line, 0, oy, len); - if (IS_SET(Whide)) + if(IS_SET(Whide)) return; /* @@ -1491,7 +1499,7 @@ xdrawcursor(int cx, int cy, Letter g, int ox, int oy, Letter og) */ g.mode &= Gbold|Gitalic|Gunline|Gstruck|Gwide; - if (IS_SET(Wreverse)) { + if(IS_SET(Wreverse)) { g.mode |= Greverse; g.bg = defaultfg; if (selected(cx, cy)) { @@ -1502,7 +1510,7 @@ xdrawcursor(int cx, int cy, Letter g, int ox, int oy, Letter og) g.fg = defaultcs; } } else { - if (selected(cx, cy)) { + if(selected(cx, cy)) { g.fg = defaultfg; g.bg = defaultrcs; } else { @@ -1520,7 +1528,7 @@ xdrawcursor(int cx, int cy, Letter g, int ox, int oy, Letter og) } drawnew: - if (IS_SET(Wfocused)) { + if(IS_SET(Wfocused)) { switch (win.cursor) { case 7: /* st extension */ g.u = 0x2603; /* snowman (U+2603) */ -- cgit v1.2.1