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;