commit c80ff623dc2b8052d5edf1a7af272d87c66e1f3c
Author: Iskustvo <[email protected]>
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
@@ -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)
 
@@ -17,3 +21,4 @@ Authors
 -------
 * Dreomite - Creating the original commit
 * wael - [email protected]
+* 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
@@ -0,0 +1,251 @@
+From 5770f2fc02afca341c275fc340bbc5003ecc3df8 Mon Sep 17 00:00:00 2001
+From: Iskustvo <[email protected]>
+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
+@@ -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
+@@ -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
+@@ -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
+@@ -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,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;
+@@ -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
+


Reply via email to