sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit 2c39bdf5279bac62e0271363136b9f339dc52090
parent ec8efabdc652adc31a9eff40dc2034fbcec8ec0c
Author: wael <40663@protonmail.com>
Date:   Mon, 11 Apr 2022 17:29:10 +0300

[st][patch][glyph wide support] new patch

Diffstat:
Ast.suckless.org/patches/glyph_wide_support/index.md | 19+++++++++++++++++++
Ast.suckless.org/patches/glyph_wide_support/st-glyph-wide-support-20220411-ef05519.diff | 206+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ast.suckless.org/patches/glyph_wide_support/st-glyph-wide-support-boxdraw-20220411-ef05519.diff | 213+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 438 insertions(+), 0 deletions(-)

diff --git a/st.suckless.org/patches/glyph_wide_support/index.md b/st.suckless.org/patches/glyph_wide_support/index.md @@ -0,0 +1,19 @@ +glyph wide support +================================ + +Description +----------- +This patch fixes wide glyphs truncation. +This patch is based from [Lukesmithxyz/st's commit on github](https://github.com/LukeSmithxyz/st/commit/e3b821dcb3511d60341dec35ee05a4a0abfef7f2) + +Download +-------- +* [st-glyph-wide-support-20220411-ef05519.diff](st-glyph-wide-support-20220411-ef05519.diff) + +Use this patch if you are using boxdraw. +* [st-glyph-wide-support-boxdraw-20220411-ef05519.diff](st-glyph-wide-support-boxdraw-20220411-ef05519.diff) + +Authors +------- +* Dreomite - Creating the original commit +* wael - 40663@protonmail.com diff --git a/st.suckless.org/patches/glyph_wide_support/st-glyph-wide-support-20220411-ef05519.diff b/st.suckless.org/patches/glyph_wide_support/st-glyph-wide-support-20220411-ef05519.diff @@ -0,0 +1,206 @@ +From 68de38fadd04f2f454bceccea0fccc8276b635cb Mon Sep 17 00:00:00 2001 +From: wael <40663@protonmail.com> +Date: Mon, 11 Apr 2022 16:45:49 +0300 +Subject: [PATCH] add glyph wide support patch + +--- + st.h | 6 +++ + x.c | 134 +++++++++++++++++++++++++++++------------------------------ + 2 files changed, 73 insertions(+), 67 deletions(-) + +diff --git a/st.h b/st.h +index 519b9bd..4f74621 100644 +--- a/st.h ++++ b/st.h +@@ -36,6 +36,12 @@ enum glyph_attribute { + ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT, + }; + ++enum drawing_mode { ++ DRAW_NONE = 0, ++ DRAW_BG = 1 << 0, ++ DRAW_FG = 1 << 1, ++}; ++ + enum selection_mode { + SEL_IDLE = 0, + SEL_EMPTY = 1, +diff --git a/x.c b/x.c +index 2a3bd38..d60df52 100644 +--- a/x.c ++++ b/x.c +@@ -142,7 +142,7 @@ typedef struct { + + static inline ushort sixd_to_16bit(int); + static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int); +-static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int); ++static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int, int); + static void xdrawglyph(Glyph, int, int); + static void xclear(int, int, int, int); + static int xgeommasktogravity(int); +@@ -1372,7 +1372,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x + } + + void +-xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) ++xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y, int dmode) + { + int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); + int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, +@@ -1463,47 +1463,40 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i + if (base.mode & ATTR_INVISIBLE) + fg = bg; + +- /* Intelligent cleaning up of the borders. */ +- if (x == 0) { +- xclear(0, (y == 0)? 0 : winy, borderpx, +- winy + win.ch + +- ((winy + win.ch >= borderpx + win.th)? win.h : 0)); +- } +- if (winx + width >= borderpx + win.tw) { +- xclear(winx + width, (y == 0)? 0 : winy, win.w, +- ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); +- } +- if (y == 0) +- xclear(winx, 0, winx + width, borderpx); +- if (winy + win.ch >= borderpx + win.th) +- xclear(winx, winy + win.ch, winx + width, win.h); +- +- /* Clean up the region we want to draw to. */ +- XftDrawRect(xw.draw, bg, winx, winy, width, win.ch); +- +- /* Set the clip region because Xft is sometimes dirty. */ +- r.x = 0; +- r.y = 0; +- r.height = win.ch; +- r.width = width; +- XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1); +- +- /* Render the glyphs. */ +- XftDrawGlyphFontSpec(xw.draw, fg, specs, len); +- +- /* Render underline and strikethrough. */ +- if (base.mode & ATTR_UNDERLINE) { +- XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1, +- width, 1); +- } +- +- if (base.mode & ATTR_STRUCK) { +- XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3, +- width, 1); +- } +- +- /* Reset clip to none. */ +- XftDrawSetClip(xw.draw, 0); ++ if (dmode & DRAW_BG) { ++ /* Intelligent cleaning up of the borders. */ ++ if (x == 0) { ++ xclear(0, (y == 0)? 0 : winy, borderpx, ++ winy + win.ch + ++ ((winy + win.ch >= borderpx + win.th)? win.h : 0)); ++ } ++ if (winx + width >= borderpx + win.tw) { ++ xclear(winx + width, (y == 0)? 0 : winy, win.w, ++ ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); ++ } ++ if (y == 0) ++ xclear(winx, 0, winx + width, borderpx); ++ if (winy + win.ch >= borderpx + win.th) ++ xclear(winx, winy + win.ch, winx + width, win.h); ++ /* Fill the background */ ++ XftDrawRect(xw.draw, bg, winx, winy, width, win.ch); ++ } ++ ++ if (dmode & DRAW_FG) { ++ /* Render the glyphs. */ ++ XftDrawGlyphFontSpec(xw.draw, fg, specs, len); ++ ++ /* Render underline and strikethrough. */ ++ if (base.mode & ATTR_UNDERLINE) { ++ XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1, ++ width, 1); ++ } ++ ++ if (base.mode & ATTR_STRUCK) { ++ XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3, ++ width, 1); ++ } ++ } + } + + void +@@ -1513,7 +1506,7 @@ xdrawglyph(Glyph g, int x, int y) + XftGlyphFontSpec spec; + + numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); +- xdrawglyphfontspecs(&spec, g, numspecs, x, y); ++ xdrawglyphfontspecs(&spec, g, numspecs, x, y, DRAW_BG | DRAW_FG); + } + + void +@@ -1648,32 +1641,39 @@ xstartdraw(void) + void + xdrawline(Line line, int x1, int y1, int x2) + { +- int i, x, ox, numspecs; ++ int i, x, ox, numspecs, numspecs_cached; + Glyph base, new; +- XftGlyphFontSpec *specs = xw.specbuf; +- +- numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1); +- i = ox = 0; +- for (x = x1; x < x2 && i < numspecs; x++) { +- new = line[x]; +- if (new.mode == ATTR_WDUMMY) +- continue; +- if (selected(x, y1)) +- new.mode ^= ATTR_REVERSE; +- if (i > 0 && ATTRCMP(base, new)) { +- xdrawglyphfontspecs(specs, base, i, ox, y1); +- specs += i; +- numspecs -= i; +- i = 0; +- } +- if (i == 0) { +- ox = x; +- base = new; ++ XftGlyphFontSpec *specs; ++ ++ numspecs_cached = xmakeglyphfontspecs(xw.specbuf, &line[x1], x2 - x1, x1, y1); ++ ++ /* Draw line in 2 passes: background and foreground. This way wide glyphs ++ won't get truncated (#223) */ ++ for (int dmode = DRAW_BG; dmode <= DRAW_FG; dmode <<= 1) { ++ specs = xw.specbuf; ++ numspecs = numspecs_cached; ++ i = ox = 0; ++ for (x = x1; x < x2 && i < numspecs; x++) { ++ new = line[x]; ++ if (new.mode == ATTR_WDUMMY) ++ continue; ++ if (selected(x, y1)) ++ new.mode ^= ATTR_REVERSE; ++ if (i > 0 && ATTRCMP(base, new)) { ++ xdrawglyphfontspecs(specs, base, i, ox, y1, dmode); ++ specs += i; ++ numspecs -= i; ++ i = 0; ++ } ++ if (i == 0) { ++ ox = x; ++ base = new; ++ } ++ i++; + } +- i++; ++ if (i > 0) ++ xdrawglyphfontspecs(specs, base, i, ox, y1, dmode); + } +- if (i > 0) +- xdrawglyphfontspecs(specs, base, i, ox, y1); + } + + void +-- +2.35.1 + diff --git a/st.suckless.org/patches/glyph_wide_support/st-glyph-wide-support-boxdraw-20220411-ef05519.diff b/st.suckless.org/patches/glyph_wide_support/st-glyph-wide-support-boxdraw-20220411-ef05519.diff @@ -0,0 +1,213 @@ +From 9583955da47177c9557210f70baaaf9511ba106c Mon Sep 17 00:00:00 2001 +From: wael <40663@protonmail.com> +Date: Mon, 11 Apr 2022 17:14:06 +0300 +Subject: [PATCH] boxdraw support for glyph wide support + +--- + st.h | 6 +++ + x.c | 139 ++++++++++++++++++++++++++++++----------------------------- + 2 files changed, 76 insertions(+), 69 deletions(-) + +diff --git a/st.h b/st.h +index 07a7c66..3b8c97d 100644 +--- a/st.h ++++ b/st.h +@@ -37,6 +37,12 @@ enum glyph_attribute { + ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT, + }; + ++enum drawing_mode { ++ DRAW_NONE = 0, ++ DRAW_BG = 1 << 0, ++ DRAW_FG = 1 << 1, ++}; ++ + enum selection_mode { + SEL_IDLE = 0, + SEL_EMPTY = 1, +diff --git a/x.c b/x.c +index bf6bbf9..1311c0d 100644 +--- a/x.c ++++ b/x.c +@@ -142,7 +142,7 @@ typedef struct { + + static inline ushort sixd_to_16bit(int); + static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int); +-static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int); ++static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int, int); + static void xdrawglyph(Glyph, int, int); + static void xclear(int, int, int, int); + static int xgeommasktogravity(int); +@@ -1379,7 +1379,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x + } + + void +-xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) ++xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y, int dmode) + { + int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); + int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, +@@ -1470,51 +1470,45 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i + if (base.mode & ATTR_INVISIBLE) + fg = bg; + +- /* Intelligent cleaning up of the borders. */ +- if (x == 0) { +- xclear(0, (y == 0)? 0 : winy, borderpx, +- winy + win.ch + +- ((winy + win.ch >= borderpx + win.th)? win.h : 0)); +- } +- if (winx + width >= borderpx + win.tw) { +- xclear(winx + width, (y == 0)? 0 : winy, win.w, +- ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); +- } +- if (y == 0) +- xclear(winx, 0, winx + width, borderpx); +- if (winy + win.ch >= borderpx + win.th) +- xclear(winx, winy + win.ch, winx + width, win.h); +- +- /* Clean up the region we want to draw to. */ +- XftDrawRect(xw.draw, bg, winx, winy, width, win.ch); +- +- /* Set the clip region because Xft is sometimes dirty. */ +- r.x = 0; +- r.y = 0; +- r.height = win.ch; +- r.width = width; +- XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1); +- +- if (base.mode & ATTR_BOXDRAW) { +- drawboxes(winx, winy, width / len, win.ch, fg, bg, specs, len); +- } else { +- /* Render the glyphs. */ +- XftDrawGlyphFontSpec(xw.draw, fg, specs, len); +- } ++ if (dmode & DRAW_BG) { ++ /* Intelligent cleaning up of the borders. */ ++ if (x == 0) { ++ xclear(0, (y == 0)? 0 : winy, borderpx, ++ winy + win.ch + ++ ((winy + win.ch >= borderpx + win.th)? win.h : 0)); ++ } ++ if (winx + width >= borderpx + win.tw) { ++ xclear(winx + width, (y == 0)? 0 : winy, win.w, ++ ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); ++ } ++ if (y == 0) ++ xclear(winx, 0, winx + width, borderpx); ++ if (winy + win.ch >= borderpx + win.th) ++ xclear(winx, winy + win.ch, winx + width, win.h); ++ /* Fill the background */ ++ XftDrawRect(xw.draw, bg, winx, winy, width, win.ch); ++ } ++ ++ ++ if (dmode & DRAW_FG) { ++ if (base.mode & ATTR_BOXDRAW) { ++ drawboxes(winx, winy, width / len, win.ch, fg, bg, specs, len); ++ } else { ++ /* Render the glyphs. */ ++ XftDrawGlyphFontSpec(xw.draw, fg, specs, len); ++ } + +- /* Render underline and strikethrough. */ +- if (base.mode & ATTR_UNDERLINE) { +- XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1, +- width, 1); +- } ++ /* Render underline and strikethrough. */ ++ if (base.mode & ATTR_UNDERLINE) { ++ XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1, ++ width, 1); ++ } + +- if (base.mode & ATTR_STRUCK) { +- XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent * chscale / 3, +- width, 1); +- } +- +- /* Reset clip to none. */ +- XftDrawSetClip(xw.draw, 0); ++ if (base.mode & ATTR_STRUCK) { ++ XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3, ++ width, 1); ++ } ++ } + } + + void +@@ -1524,7 +1518,7 @@ xdrawglyph(Glyph g, int x, int y) + XftGlyphFontSpec spec; + + numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); +- xdrawglyphfontspecs(&spec, g, numspecs, x, y); ++ xdrawglyphfontspecs(&spec, g, numspecs, x, y, DRAW_BG | DRAW_FG); + } + + void +@@ -1659,32 +1653,39 @@ xstartdraw(void) + void + xdrawline(Line line, int x1, int y1, int x2) + { +- int i, x, ox, numspecs; ++ int i, x, ox, numspecs, numspecs_cached; + Glyph base, new; +- XftGlyphFontSpec *specs = xw.specbuf; +- +- numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1); +- i = ox = 0; +- for (x = x1; x < x2 && i < numspecs; x++) { +- new = line[x]; +- if (new.mode == ATTR_WDUMMY) +- continue; +- if (selected(x, y1)) +- new.mode ^= ATTR_REVERSE; +- if (i > 0 && ATTRCMP(base, new)) { +- xdrawglyphfontspecs(specs, base, i, ox, y1); +- specs += i; +- numspecs -= i; +- i = 0; +- } +- if (i == 0) { +- ox = x; +- base = new; ++ XftGlyphFontSpec *specs; ++ ++ numspecs_cached = xmakeglyphfontspecs(xw.specbuf, &line[x1], x2 - x1, x1, y1); ++ ++ /* Draw line in 2 passes: background and foreground. This way wide glyphs ++ won't get truncated (#223) */ ++ for (int dmode = DRAW_BG; dmode <= DRAW_FG; dmode <<= 1) { ++ specs = xw.specbuf; ++ numspecs = numspecs_cached; ++ i = ox = 0; ++ for (x = x1; x < x2 && i < numspecs; x++) { ++ new = line[x]; ++ if (new.mode == ATTR_WDUMMY) ++ continue; ++ if (selected(x, y1)) ++ new.mode ^= ATTR_REVERSE; ++ if (i > 0 && ATTRCMP(base, new)) { ++ xdrawglyphfontspecs(specs, base, i, ox, y1, dmode); ++ specs += i; ++ numspecs -= i; ++ i = 0; ++ } ++ if (i == 0) { ++ ox = x; ++ base = new; ++ } ++ i++; + } +- i++; ++ if (i > 0) ++ xdrawglyphfontspecs(specs, base, i, ox, y1, dmode); + } +- if (i > 0) +- xdrawglyphfontspecs(specs, base, i, ox, y1); + } + + void +-- +2.35.1 +