[wiki] [sites] [st][patch][glyph wide support] patch update || Iskustvo

From: <git_AT_suckless.org>
Date: Sat, 07 Jan 2023 02:12:25 +0100

commit c80ff623dc2b8052d5edf1a7af272d87c66e1f3c
Author: Iskustvo <iskustvo_AT_yahoo.com>
Date: Sat Jan 7 02:02:39 2023 +0100

    [st][patch][glyph wide support] patch update
    
    Add new patch which fixes the issue where wide glyphs were not being properly
    redrawn during editing.
    For more information, see https://github.com/LukeSmithxyz/st/pull/349

diff --git a/st.suckless.org/patches/glyph_wide_support/index.md b/st.suckless.org/patches/glyph_wide_support/index.md
index d5b99659..3a744e2a 100644
--- a/st.suckless.org/patches/glyph_wide_support/index.md
+++ b/st.suckless.org/patches/glyph_wide_support/index.md
_AT_@ -10,6 +10,10 @@ Download
 --------
 * [st-glyph-wide-support-20220411-ef05519.diff](st-glyph-wide-support-20220411-ef05519.diff)
 
+Use this patch if wide glyph characters are still being chopped during editing.
+For all informations about how this looks, why it might and might not happen, look [here](https://github.com/LukeSmithxyz/st/pull/349).
+* [st-glyph-wide-support-20230701-5770f2f.diff](st-glyph-wide-support-20230701-5770f2f.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)
 
_AT_@ -17,3 +21,4 @@ Authors
 -------
 * Dreomite - Creating the original commit
 * wael - 40663_AT_protonmail.com
+* Iskustvo - Fixing the solution for chopping during editing
diff --git a/st.suckless.org/patches/glyph_wide_support/st-glyph-wide-support-20230701-5770f2f.diff b/st.suckless.org/patches/glyph_wide_support/st-glyph-wide-support-20230701-5770f2f.diff
new file mode 100644
index 00000000..f0ab176c
--- /dev/null
+++ b/st.suckless.org/patches/glyph_wide_support/st-glyph-wide-support-20230701-5770f2f.diff
_AT_@ -0,0 +1,251 @@
+From 5770f2fc02afca341c275fc340bbc5003ecc3df8 Mon Sep 17 00:00:00 2001
+From: Iskustvo <iskustvo_AT_yahoo.com>
+Date: Sat, 7 Jan 2023 01:23:37 +0100
+Subject: [PATCH] [PATCH] add glyph wide support patch
+
+---
+ st.c | 3 +-
+ st.h | 6 +++
+ win.h | 2 +-
+ x.c | 141 ++++++++++++++++++++++++++++++----------------------------
+ 4 files changed, 81 insertions(+), 71 deletions(-)
+
+diff --git a/st.c b/st.c
+index 62def59..cc6c78e 100644
+--- a/st.c
++++ b/st.c
+_AT_@ -2640,7 +2640,8 @@ draw(void)
+
+ drawregion(0, 0, term.col, term.row);
+ xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
+- term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
++ term.ocx, term.ocy, term.line[term.ocy][term.ocx],
++ term.line[term.ocy], term.col);
+ term.ocx = cx;
+ term.ocy = term.c.y;
+ xfinishdraw();
+diff --git a/st.h b/st.h
+index fd3b0d8..0053050 100644
+--- a/st.h
++++ b/st.h
+_AT_@ -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/win.h b/win.h
+index 6de960d..94679e4 100644
+--- a/win.h
++++ b/win.h
+_AT_@ -25,7 +25,7 @@ enum win_mode {
+
+ void xbell(void);
+ void xclipcopy(void);
+-void xdrawcursor(int, int, Glyph, int, int, Glyph);
++void xdrawcursor(int, int, Glyph, int, int, Glyph, Line, int);
+ void xdrawline(Line, int, int, int);
+ void xfinishdraw(void);
+ void xloadcols(void);
+diff --git a/x.c b/x.c
+index aa09997..85deee6 100644
+--- a/x.c
++++ b/x.c
+_AT_@ -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);
+_AT_@ -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,
+_AT_@ -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
+_AT_@ -1513,18 +1506,21 @@ 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
+-xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og)
++xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og, Line line, int len)
+ {
+ Color drawcol;
+
+ /* remove the old cursor */
+ if (selected(ox, oy))
+ og.mode ^= ATTR_REVERSE;
+- xdrawglyph(og, ox, oy);
++
++ /* Redraw the line where cursor was previously.
++ * It will restore wide glyphs and ligatures broken by the cursor. */
++ xdrawline(line, 0, oy, len);
+
+ if (IS_SET(MODE_HIDE))
+ return;
+_AT_@ -1648,32 +1644,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.39.0
+
Received on Sat Jan 07 2023 - 02:12:25 CET

This archive was generated by hypermail 2.3.0 : Sat Jan 07 2023 - 02:12:50 CET