commit 2c39bdf5279bac62e0271363136b9f339dc52090
Author: wael <[email protected]>
Date:   Mon Apr 11 17:29:10 2022 +0300

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

diff --git a/st.suckless.org/patches/glyph_wide_support/index.md 
b/st.suckless.org/patches/glyph_wide_support/index.md
new file mode 100644
index 00000000..d5b99659
--- /dev/null
+++ 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 - [email protected]
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
new file mode 100644
index 00000000..f88c5eef
--- /dev/null
+++ 
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 <[email protected]>
+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
new file mode 100644
index 00000000..0448226f
--- /dev/null
+++ 
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 <[email protected]>
+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
+


Reply via email to