commit ffe921a73bc23ff07321631bd0f4be4def97ffe4
Author: Alexander Rogachev <[email protected]>
Date:   Thu Apr 30 00:02:36 2020 +0300

    [st][ligatures] Improved and simplified ligature drawing logic, removed 
excessive redraws.

diff --git 
a/st.suckless.org/patches/ligatures/st-ligatures-20200406-28ad288.diff 
b/st.suckless.org/patches/ligatures/st-ligatures-20200428-28ad288.diff
similarity index 84%
rename from st.suckless.org/patches/ligatures/st-ligatures-20200406-28ad288.diff
rename to st.suckless.org/patches/ligatures/st-ligatures-20200428-28ad288.diff
index 5d4198a8..140470bf 100644
--- a/st.suckless.org/patches/ligatures/st-ligatures-20200406-28ad288.diff
+++ b/st.suckless.org/patches/ligatures/st-ligatures-20200428-28ad288.diff
@@ -22,7 +22,7 @@ index 470ac86..38240da 100644
  $(OBJ): config.h config.mk
  
 diff --git a/config.mk b/config.mk
-index 0cbb002..76c5c4f 100644
+index 0cbb002..a021b2c 100644
 --- a/config.mk
 +++ b/config.mk
 @@ -15,10 +15,12 @@ PKG_CONFIG = pkg-config
@@ -42,7 +42,7 @@ index 0cbb002..76c5c4f 100644
  STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600
 diff --git a/hb.c b/hb.c
 new file mode 100644
-index 0000000..bb0bea8
+index 0000000..7df2828
 --- /dev/null
 +++ b/hb.c
 @@ -0,0 +1,136 @@
@@ -184,7 +184,7 @@ index 0000000..bb0bea8
 +}
 diff --git a/hb.h b/hb.h
 new file mode 100644
-index 0000000..a209238
+index 0000000..b3e02d0
 --- /dev/null
 +++ b/hb.h
 @@ -0,0 +1,7 @@
@@ -196,21 +196,16 @@ index 0000000..a209238
 +void hbtransform(XftGlyphFontSpec *, const Glyph *, size_t, int, int);
 +
 diff --git a/st.c b/st.c
-index 3e48410..073e4c7 100644
+index 3e48410..e5064d6 100644
 --- a/st.c
 +++ b/st.c
-@@ -2584,8 +2584,14 @@ draw(void)
-               cx--;
+@@ -2585,7 +2585,8 @@ draw(void)
  
        drawregion(0, 0, term.col, term.row);
-+      /* Draw current line to format ligatures properly. */
-+      xdrawline(term.line[term.c.y], 0, term.c.y, term.col);
-+
        xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
-                       term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
-+      /* If cursor was on a transformed glyph, we need to redraw the previous 
line. */
-+      if (term.ocy != term.c.y && (term.line[term.ocy][term.ocx].mode & 
ATTR_LIGA))
-+              xdrawline(term.line[term.ocy], 0, term.ocy, term.col);
+-                      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();
        xximspot(term.ocx, term.ocy);
@@ -236,8 +231,21 @@ index a1928ca..07ba678 100644
        ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
  };
  
+diff --git a/win.h b/win.h
+index a6ef1b9..bc0d180 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 4cf6b21..447f475 100644
+index 4cf6b21..410994d 100644
 --- a/x.c
 +++ b/x.c
 @@ -19,6 +19,7 @@ static char *argv0;
@@ -277,3 +285,23 @@ index 4cf6b21..447f475 100644
        return numspecs;
  }
  
+@@ -1485,14 +1492,17 @@ xdrawglyph(Glyph g, int x, int y)
+ }
+ 
+ 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 the ligatures broken by the cursor. */
++      xdrawline(line, 0, oy, len);
+ 
+       if (IS_SET(MODE_HIDE))
+               return;
diff --git 
a/st.suckless.org/patches/ligatures/st-ligatures-alpha-20200406-28ad288.diff 
b/st.suckless.org/patches/ligatures/st-ligatures-alpha-20200428-28ad288.diff
similarity index 85%
rename from 
st.suckless.org/patches/ligatures/st-ligatures-alpha-20200406-28ad288.diff
rename to 
st.suckless.org/patches/ligatures/st-ligatures-alpha-20200428-28ad288.diff
index ed830712..0d3b27bd 100644
--- a/st.suckless.org/patches/ligatures/st-ligatures-alpha-20200406-28ad288.diff
+++ b/st.suckless.org/patches/ligatures/st-ligatures-alpha-20200428-28ad288.diff
@@ -196,21 +196,16 @@ index 0000000..a209238
 +void hbtransform(XftGlyphFontSpec *, const Glyph *, size_t, int, int);
 +
 diff --git a/st.c b/st.c
-index 3e48410..073e4c7 100644
+index 3e48410..e5064d6 100644
 --- a/st.c
 +++ b/st.c
-@@ -2584,8 +2584,14 @@ draw(void)
-               cx--;
+@@ -2585,7 +2585,8 @@ draw(void)
  
        drawregion(0, 0, term.col, term.row);
-+      /* Draw current line to format ligatures properly. */
-+      xdrawline(term.line[term.c.y], 0, term.c.y, term.col);
-+
        xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
-                       term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
-+      /* If cursor was on a transformed glyph, we need to redraw the previous 
line.*/
-+      if (term.ocy != term.c.y && (term.line[term.ocy][term.ocx].mode & 
ATTR_LIGA))
-+              xdrawline(term.line[term.ocy], 0, term.ocy, term.col);
+-                      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();
        xximspot(term.ocx, term.ocy);
@@ -236,8 +231,21 @@ index a1928ca..07ba678 100644
        ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
  };
  
+diff --git a/win.h b/win.h
+index a6ef1b9..bc0d180 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 4cf6b21..447f475 100644
+index 4cf6b21..410994d 100644
 --- a/x.c
 +++ b/x.c
 @@ -19,6 +19,7 @@ static char *argv0;
@@ -277,3 +285,23 @@ index 4cf6b21..447f475 100644
        return numspecs;
  }
 
+@@ -1485,14 +1492,17 @@ xdrawglyph(Glyph g, int x, int y)
+ }
+ 
+ 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 the ligatures broken by the cursor. */
++      xdrawline(line, 0, oy, len);
+ 
+       if (IS_SET(MODE_HIDE))
+               return;
diff --git 
a/st.suckless.org/patches/ligatures/st-ligatures-alpha-scrollback-20200406-28ad288.diff
 
b/st.suckless.org/patches/ligatures/st-ligatures-alpha-scrollback-20200428-28ad288.diff
similarity index 82%
rename from 
st.suckless.org/patches/ligatures/st-ligatures-alpha-scrollback-20200406-28ad288.diff
rename to 
st.suckless.org/patches/ligatures/st-ligatures-alpha-scrollback-20200428-28ad288.diff
index 08f280d3..06e99a18 100644
--- 
a/st.suckless.org/patches/ligatures/st-ligatures-alpha-scrollback-20200406-28ad288.diff
+++ 
b/st.suckless.org/patches/ligatures/st-ligatures-alpha-scrollback-20200428-28ad288.diff
@@ -22,7 +22,7 @@ index 470ac86..38240da 100644
  $(OBJ): config.h config.mk
  
 diff --git a/config.mk b/config.mk
-index 0cbb002..76c5c4f 100644
+index 1d2f0e2..fd92921 100644
 --- a/config.mk
 +++ b/config.mk
 @@ -15,10 +15,12 @@ PKG_CONFIG = pkg-config
@@ -184,7 +184,7 @@ index 0000000..bd3fb71
 +}
 diff --git a/hb.h b/hb.h
 new file mode 100644
-index 0000000..4505444
+index 0000000..a209238
 --- /dev/null
 +++ b/hb.h
 @@ -0,0 +1,7 @@
@@ -196,32 +196,21 @@ index 0000000..4505444
 +void hbtransform(XftGlyphFontSpec *, const Glyph *, size_t, int, int);
 +
 diff --git a/st.c b/st.c
-index 130bf22..07b2f3b 100644
+index f8b6f67..a6c3ee7 100644
 --- a/st.c
 +++ b/st.c
-@@ -2652,9 +2652,17 @@ draw(void)
-               cx--;
- 
+@@ -2656,7 +2656,8 @@ draw(void)
        drawregion(0, 0, term.col, term.row);
--      if (term.scr == 0)
--              xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
+       if (term.scr == 0)
+               xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
 -                              term.ocx, term.ocy, 
term.line[term.ocy][term.ocx]);
-+      if (term.scr == 0) {
-+              /* Draw current line to format ligatures properly. */
-+              xdrawline(term.line[term.c.y], 0, term.c.y, term.col);
-+
-+              xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
-+                              term.ocx, term.ocy, 
term.line[term.ocy][term.ocx]);
-+
-+              /* If cursor was on a transformed glyph, we need to redraw the 
previous line. */
-+              if (term.ocy != term.c.y && (term.line[term.ocy][term.ocx].mode 
& ATTR_LIGA))
-+                      xdrawline(term.line[term.ocy], 0, term.ocy, term.col);
-+  }
++                              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();
        xximspot(term.ocx, term.ocy);
 diff --git a/st.h b/st.h
-index 1332cf1..6b5218d 100644
+index c67ebc3..073ae82 100644
 --- a/st.h
 +++ b/st.h
 @@ -11,7 +11,8 @@
@@ -242,8 +231,21 @@ index 1332cf1..6b5218d 100644
        ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
  };
  
+diff --git a/win.h b/win.h
+index a6ef1b9..bc0d180 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 4cf6b21..f6b09da 100644
+index 139f7ff..eaf764f 100644
 --- a/x.c
 +++ b/x.c
 @@ -19,6 +19,7 @@ static char *argv0;
@@ -254,7 +256,7 @@ index 4cf6b21..f6b09da 100644
  
  /* types used in config.h */
  typedef struct {
-@@ -1031,6 +1032,9 @@ xunloadfont(Font *f)
+@@ -1040,6 +1041,9 @@ xunloadfont(Font *f)
  void
  xunloadfonts(void)
  {
@@ -264,7 +266,7 @@ index 4cf6b21..f6b09da 100644
        /* Free the loaded fonts in the font cache.  */
        while (frclen > 0)
                XftFontClose(xw.dpy, frc[--frclen].font);
-@@ -1229,7 +1233,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph 
*glyphs, int len, int x
+@@ -1246,7 +1250,7 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph 
*glyphs, int len, int x
                mode = glyphs[i].mode;
  
                /* Skip dummy wide-character spacing. */
@@ -273,7 +275,7 @@ index 4cf6b21..f6b09da 100644
                        continue;
  
                /* Determine font for glyph if different from previous glyph. */
-@@ -1336,6 +1340,9 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph 
*glyphs, int len, int x
+@@ -1353,6 +1357,9 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph 
*glyphs, int len, int x
                numspecs++;
        }
  
@@ -283,3 +285,23 @@ index 4cf6b21..f6b09da 100644
        return numspecs;
  }
  
+@@ -1502,14 +1509,17 @@ xdrawglyph(Glyph g, int x, int y)
+ }
+ 
+ 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 the ligatures broken by the cursor. */
++      xdrawline(line, 0, oy, len);
+ 
+       if (IS_SET(MODE_HIDE))
+               return;
diff --git 
a/st.suckless.org/patches/ligatures/st-ligatures-boxdraw-20200407-28ad288.diff 
b/st.suckless.org/patches/ligatures/st-ligatures-boxdraw-20200428-28ad288.diff
similarity index 86%
rename from 
st.suckless.org/patches/ligatures/st-ligatures-boxdraw-20200407-28ad288.diff
rename to 
st.suckless.org/patches/ligatures/st-ligatures-boxdraw-20200428-28ad288.diff
index 99057ce7..9b496877 100644
--- 
a/st.suckless.org/patches/ligatures/st-ligatures-boxdraw-20200407-28ad288.diff
+++ 
b/st.suckless.org/patches/ligatures/st-ligatures-boxdraw-20200428-28ad288.diff
@@ -200,21 +200,16 @@ index 0000000..a209238
 +void hbtransform(XftGlyphFontSpec *, const Glyph *, size_t, int, int);
 +
 diff --git a/st.c b/st.c
-index 3e48410..073e4c7 100644
+index 3e48410..e5064d6 100644
 --- a/st.c
 +++ b/st.c
-@@ -2584,8 +2584,14 @@ draw(void)
-               cx--;
+@@ -2585,7 +2585,8 @@ draw(void)
  
        drawregion(0, 0, term.col, term.row);
-+      /* Draw current line to format ligatures properly. */
-+      xdrawline(term.line[term.c.y], 0, term.c.y, term.col);
-+
        xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
-                       term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
-+      /* If cursor was on a transformed glyph, we need to redraw the previous 
line. */
-+      if (term.ocy != term.c.y && (term.line[term.ocy][term.ocx].mode & 
ATTR_LIGA))
-+              xdrawline(term.line[term.ocy], 0, term.ocy, term.col);
+-                      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();
        xximspot(term.ocx, term.ocy);
@@ -241,6 +236,19 @@ index a1928ca..07ba678 100644
        ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
  };
  
+diff --git a/win.h b/win.h
+index a6ef1b9..bc0d180 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 4cf6b21..447f475 100644
 --- a/x.c
@@ -282,3 +290,23 @@ index 4cf6b21..447f475 100644
        return numspecs;
  }
  
+@@ -1485,14 +1492,17 @@ xdrawglyph(Glyph g, int x, int y)
+ }
+ 
+ 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 the ligatures broken by the cursor. */
++      xdrawline(line, 0, oy, len);
+ 
+       if (IS_SET(MODE_HIDE))
+               return;
diff --git 
a/st.suckless.org/patches/ligatures/st-ligatures-scrollback-20200406-28ad288.diff
 
b/st.suckless.org/patches/ligatures/st-ligatures-scrollback-20200428-28ad288.diff
similarity index 85%
rename from 
st.suckless.org/patches/ligatures/st-ligatures-scrollback-20200406-28ad288.diff
rename to 
st.suckless.org/patches/ligatures/st-ligatures-scrollback-20200428-28ad288.diff
index c65ff7c9..8a64711f 100644
--- 
a/st.suckless.org/patches/ligatures/st-ligatures-scrollback-20200406-28ad288.diff
+++ 
b/st.suckless.org/patches/ligatures/st-ligatures-scrollback-20200428-28ad288.diff
@@ -196,32 +196,21 @@ index 0000000..4505444
 +void hbtransform(XftGlyphFontSpec *, const Glyph *, size_t, int, int);
 +
 diff --git a/st.c b/st.c
-index 130bf22..07b2f3b 100644
+index f8b6f67..a6c3ee7 100644
 --- a/st.c
 +++ b/st.c
-@@ -2652,9 +2652,17 @@ draw(void)
-               cx--;
- 
+@@ -2656,7 +2656,8 @@ draw(void)
        drawregion(0, 0, term.col, term.row);
--      if (term.scr == 0)
--              xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
+       if (term.scr == 0)
+               xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
 -                              term.ocx, term.ocy, 
term.line[term.ocy][term.ocx]);
-+      if (term.scr == 0) {
-+              /* Draw current line to format ligatures properly. */
-+              xdrawline(term.line[term.c.y], 0, term.c.y, term.col);
-+
-+              xdrawcursor(cx, term.c.y, term.line[term.c.y][cx],
-+                              term.ocx, term.ocy, 
term.line[term.ocy][term.ocx]);
-+
-+              /* If cursor was on a transformed glyph, we need to redraw the 
previous line. */
-+              if (term.ocy != term.c.y && (term.line[term.ocy][term.ocx].mode 
& ATTR_LIGA))
-+                      xdrawline(term.line[term.ocy], 0, term.ocy, term.col);
-+  }
++                              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();
        xximspot(term.ocx, term.ocy);
 diff --git a/st.h b/st.h
-index 1332cf1..6b5218d 100644
+index c67ebc3..073ae82 100644
 --- a/st.h
 +++ b/st.h
 @@ -11,7 +11,8 @@
@@ -242,8 +231,21 @@ index 1332cf1..6b5218d 100644
        ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
  };
  
+diff --git a/win.h b/win.h
+index a6ef1b9..bc0d180 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 4cf6b21..f6b09da 100644
+index 4cf6b21..410994d 100644
 --- a/x.c
 +++ b/x.c
 @@ -19,6 +19,7 @@ static char *argv0;
@@ -283,3 +285,23 @@ index 4cf6b21..f6b09da 100644
        return numspecs;
  }
  
+@@ -1485,14 +1492,17 @@ xdrawglyph(Glyph g, int x, int y)
+ }
+ 
+ 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 the ligatures broken by the cursor. */
++      xdrawline(line, 0, oy, len);
+ 
+       if (IS_SET(MODE_HIDE))
+               return;


Reply via email to