commit a23971fff1aeca0b5beaf71bfc6c88d5888c7731
parent ef994f3e6d0b59dcd7083a0f68a8f9fe73f96c6c
Author: bakkeby <bakkeby@gmail.com>
Date: Sat, 14 Nov 2020 16:24:07 +0100
Adding wide glyphs patch
Diffstat:
4 files changed, 82 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
@@ -15,6 +15,8 @@ Refer to [https://st.suckless.org/](https://st.suckless.org/) for details on the
### Changelog:
+2020-11-14 - Added the wide glyphs patch
+
2020-10-23 - Added the monochrome patch
2020-08-08 - Re-added the visualbell patch
@@ -151,6 +153,9 @@ Refer to [https://st.suckless.org/](https://st.suckless.org/) for details on the
- [w3m](https://st.suckless.org/patches/w3m/)
- adds support for w3m images
+ - [wide-glyphs](https://www.reddit.com/r/suckless/comments/jt90ai/update_support_for_proper_glyph_rendering_in_st/)
+ - adds proper support for wide glyphs, as opposed to rendering smaller or cut glyphs
+
- [workingdir](https://st.suckless.org/patches/workingdir/)
- allows user to specify the initial path st should use as the working directory
diff --git a/patches.def.h b/patches.def.h
@@ -235,6 +235,13 @@
*/
#define W3M_PATCH 0
+/* Adds proper glyphs rendering in st allowing wide glyphs to be drawn as-is as opposed to
+ * smaller or cut glyphs being rendered.
+ * https://github.com/Dreomite/st/commit/e3b821dcb3511d60341dec35ee05a4a0abfef7f2
+ * https://www.reddit.com/r/suckless/comments/jt90ai/update_support_for_proper_glyph_rendering_in_st/
+ */
+#define WIDE_GLYPHS_PATCH 0
+
/* This patch allows user to specify the initial path st should use as the working directory.
* https://st.suckless.org/patches/workingdir/
*/
diff --git a/st.h b/st.h
@@ -51,6 +51,14 @@ enum glyph_attribute {
ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
};
+#if WIDE_GLYPHS_PATCH
+enum drawing_mode {
+ DRAW_NONE = 0,
+ DRAW_BG = 1 << 0,
+ DRAW_FG = 1 << 1,
+};
+#endif // WIDE_GLYPHS_PATCH
+
enum selection_mode {
SEL_IDLE = 0,
SEL_EMPTY = 1,
diff --git a/x.c b/x.c
@@ -168,7 +168,11 @@ typedef struct {
static inline ushort sixd_to_16bit(int);
static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int);
+#if WIDE_GLYPHS_PATCH
+static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int, int);
+#else
static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int);
+#endif // WIDE_GLYPHS_PATCH
static void xdrawglyph(Glyph, int, int);
static void xclear(int, int, int, int);
static int xgeommasktogravity(int);
@@ -1604,7 +1608,11 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
}
void
+#if WIDE_GLYPHS_PATCH
+xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y, int dmode)
+#else
xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
+#endif // WIDE_GLYPHS_PATCH
{
int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1);
#if ANYSIZE_PATCH
@@ -1721,6 +1729,9 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
}
#endif // INVERT_PATCH
+ #if WIDE_GLYPHS_PATCH
+ if (dmode & DRAW_BG) {
+ #endif // WIDE_GLYPHS_PATCH
/* Intelligent cleaning up of the borders. */
#if ANYSIZE_PATCH
if (x == 0) {
@@ -1752,8 +1763,11 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
xclear(winx, winy + win.ch, winx + width, win.h);
#endif // ANYSIZE_PATCH
- // /* Clean up the region we want to draw to. */
+ /* Clean up the region we want to draw to. */
XftDrawRect(xw.draw, bg, winx, winy, width, win.ch);
+ #if WIDE_GLYPHS_PATCH
+ }
+ #endif // WIDE_GLYPHS_PATCH
/* Set the clip region because Xft is sometimes dirty. */
r.x = 0;
@@ -1762,6 +1776,9 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
r.width = width;
XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1);
+ #if WIDE_GLYPHS_PATCH
+ if (dmode & DRAW_FG) {
+ #endif // WIDE_GLYPHS_PATCH
#if BOXDRAW_PATCH
if (base.mode & ATTR_BOXDRAW) {
drawboxes(winx, winy, width / len, win.ch, fg, bg, specs, len);
@@ -1794,6 +1811,9 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
width, 1);
#endif // VERTCENTER_PATCH
}
+ #if WIDE_GLYPHS_PATCH
+ }
+ #endif // WIDE_GLYPHS_PATCH
/* Reset clip to none. */
XftDrawSetClip(xw.draw, 0);
@@ -1806,7 +1826,11 @@ xdrawglyph(Glyph g, int x, int y)
XftGlyphFontSpec spec;
numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y);
+ #if WIDE_GLYPHS_PATCH
+ xdrawglyphfontspecs(&spec, g, numspecs, x, y, DRAW_BG | DRAW_FG);
+ #else
xdrawglyphfontspecs(&spec, g, numspecs, x, y);
+ #endif // WIDE_GLYPHS_PATCH
}
void
@@ -1978,7 +2002,43 @@ void
xdrawline(Line line, int x1, int y1, int x2)
{
int i, x, ox, numspecs;
+ #if WIDE_GLYPHS_PATCH
+ int numspecs_cached;
+ #endif // WIDE_GLYPHS_PATCH
Glyph base, new;
+ #if WIDE_GLYPHS_PATCH
+ 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++;
+ }
+ if (i > 0)
+ xdrawglyphfontspecs(specs, base, i, ox, y1, dmode);
+ }
+ #else
XftGlyphFontSpec *specs = xw.specbuf;
numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
@@ -2003,6 +2063,7 @@ xdrawline(Line line, int x1, int y1, int x2)
}
if (i > 0)
xdrawglyphfontspecs(specs, base, i, ox, y1);
+ #endif // WIDE_GLYPHS_PATCH
}
void