-- + - /* Lookup character index with default font. */ - glyphidx = XftCharIndex(xw.dpy, font->match, rune); - if (glyphidx) { _AT_@ -368,7 +372,7 @@ index 2a3bd38..9b97075 100644 - numspecs++; - continue; - } - +- - /* Fallback on font cache, search the font cache for match. */ - for (f = 0; f < frclen; f++) { - glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune); _AT_@ -481,13 +485,16 @@ index 2a3bd38..9b97075 100644 + } } - } -- + - /* Nothing was found. Use fontconfig to find matching font. */ - if (f >= frclen) { - if (!font->set) - font->set = FcFontSort(0, font->pattern, - 1, 0, &fcres); - fcsets[0] = font->set; ++ /* Cleanup and get ready for next segment. */ ++ hbcleanup(&shaped); ++ start = i; - /* - * Nothing was found in the cache. Now use _AT_@ -503,10 +510,7 @@ index 2a3bd38..9b97075 100644 - FcPatternAddCharSet(fcpattern, FC_CHARSET, - fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, 1); -+ /* Cleanup and get ready for next segment. */ -+ hbcleanup(&shaped); -+ start = i; - +- - FcConfigSubstitute(0, fcpattern, - FcMatchPattern); - FcDefaultSubstitute(fcpattern); _AT_@ -551,7 +555,27 @@ index 2a3bd38..9b97075 100644 } return numspecs; -_AT_@ -1517,14 +1567,17 @@ xdrawglyph(Glyph g, int x, int y) + } + + 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 charlen) + { +- int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); + int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, + width = charlen * win.cw; + Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; +_AT_@ -1510,21 +1559,24 @@ void + xdrawglyph(Glyph g, int x, int y) + { + int numspecs; +- XftGlyphFontSpec spec; ++ XftGlyphFontSpec *specs = xw.specbuf; + +- numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); +- xdrawglyphfontspecs(&spec, g, numspecs, x, y); ++ numspecs = xmakeglyphfontspecs(specs, &g, 1, x, y); ++ xdrawglyphfontspecs(specs, g, numspecs, x, y, (g.mode & ATTR_WIDE) ? 2 : 1); } void _AT_@ -571,7 +595,7 @@ index 2a3bd38..9b97075 100644 if (IS_SET(MODE_HIDE)) return; -_AT_@ -1652,18 +1705,16 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1652,18 +1704,16 @@ xdrawline(Line line, int x1, int y1, int x2) Glyph base, new; XftGlyphFontSpec *specs = xw.specbuf; _AT_@ -590,11 +614,11 @@ index 2a3bd38..9b97075 100644 - numspecs -= i; + if ((i > 0) && ATTRCMP(base, new)) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x - ox); i = 0; } if (i == 0) { -_AT_@ -1672,8 +1723,10 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1672,8 +1722,10 @@ xdrawline(Line line, int x1, int y1, int x2) } i++; } _AT_@ -602,7 +626,7 @@ index 2a3bd38..9b97075 100644 - xdrawglyphfontspecs(specs, base, i, ox, y1); + if (i > 0) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x2 - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x2 - ox); + } } diff --git a/st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-20230105-0.9.diff b/st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-20240105-0.9.diff similarity index 90% rename from st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-20230105-0.9.diff rename to st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-20240105-0.9.diff index 9ea80b0a..ff51b6c5 100644 --- a/st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-20230105-0.9.diff +++ b/st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-20240105-0.9.diff _AT_@ -43,10 +43,10 @@ index 47c615e..d7439a3 100644 STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 diff --git a/hb.c b/hb.c new file mode 100644 -index 0000000..528c040 +index 0000000..58d534b --- /dev/null +++ b/hb.c -_AT_@ -0,0 +1,124 @@ +_AT_@ -0,0 +1,125 @@ +#include <stdlib.h> +#include <stdio.h> +#include <math.h> _AT_@ -137,6 +137,7 @@ index 0000000..528c040 + + hb_buffer_t *buffer = hb_buffer_create(); + hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); ++ hb_buffer_set_cluster_level(buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); + + /* Resize the buffer if required length is larger. */ + if (hbrunebuffer.capacity < length) { _AT_@ -173,7 +174,7 @@ index 0000000..528c040 +} diff --git a/hb.h b/hb.h new file mode 100644 -index 0000000..88de9bd +index 0000000..3b0ef44 --- /dev/null +++ b/hb.h _AT_@ -0,0 +1,14 @@ _AT_@ -182,10 +183,10 @@ index 0000000..88de9bd +#include <hb-ft.h> + +typedef struct { -+ hb_buffer_t *buffer; -+ hb_glyph_info_t *glyphs; -+ hb_glyph_position_t *positions; -+ unsigned int count; ++ hb_buffer_t *buffer; ++ hb_glyph_info_t *glyphs; ++ hb_glyph_position_t *positions; ++ unsigned int count; +} HbTransformData; + +void hbunloadfonts(); _AT_@ -233,7 +234,7 @@ index 6de960d..94679e4 100644 void xfinishdraw(void); void xloadcols(void); diff --git a/x.c b/x.c -index 27e81d1..9d84793 100644 +index 27e81d1..0632636 100644 --- a/x.c +++ b/x.c _AT_@ -19,6 +19,7 @@ char *argv0; _AT_@ -244,14 +245,17 @@ index 27e81d1..9d84793 100644 /* types used in config.h */ typedef struct { -_AT_@ -142,6 +143,7 @@ typedef struct { +_AT_@ -142,8 +143,9 @@ typedef struct { } DC; static inline ushort sixd_to_16bit(int); +static void xresetfontsettings(ushort mode, Font **font, int *frcflags); 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); ++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); _AT_@ -759,7 +761,7 @@ xresize(int col, int row) xclear(0, 0, win.w, win.h); _AT_@ -303,13 +307,13 @@ index 27e81d1..9d84793 100644 int xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) { -_AT_@ -1270,121 +1291,151 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x +_AT_@ -1270,128 +1291,157 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x FcPattern *fcpattern, *fontpattern; FcFontSet *fcsets[] = { NULL }; FcCharSet *fccharset; - int i, f, numspecs = 0; + int i, f, length = 0, start = 0, numspecs = 0; -+ float cluster_xp = xp, cluster_yp = yp; ++ float cluster_xp = xp, cluster_yp = yp; + HbTransformData shaped = { 0 }; + + /* Initial values. */ _AT_@ -357,7 +361,7 @@ index 27e81d1..9d84793 100644 } - yp = winy + font->ascent; - } -- + - /* Lookup character index with default font. */ - glyphidx = XftCharIndex(xw.dpy, font->match, rune); - if (glyphidx) { _AT_@ -369,7 +373,7 @@ index 27e81d1..9d84793 100644 - numspecs++; - continue; - } - +- - /* Fallback on font cache, search the font cache for match. */ - for (f = 0; f < frclen; f++) { - glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune); _AT_@ -482,13 +486,16 @@ index 27e81d1..9d84793 100644 + } } - } -- + - /* Nothing was found. Use fontconfig to find matching font. */ - if (f >= frclen) { - if (!font->set) - font->set = FcFontSort(0, font->pattern, - 1, 0, &fcres); - fcsets[0] = font->set; ++ /* Cleanup and get ready for next segment. */ ++ hbcleanup(&shaped); ++ start = i; - /* - * Nothing was found in the cache. Now use _AT_@ -504,10 +511,7 @@ index 27e81d1..9d84793 100644 - FcPatternAddCharSet(fcpattern, FC_CHARSET, - fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, 1); -+ /* Cleanup and get ready for next segment. */ -+ hbcleanup(&shaped); -+ start = i; - +- - FcConfigSubstitute(0, fcpattern, - FcMatchPattern); - FcDefaultSubstitute(fcpattern); _AT_@ -555,7 +559,25 @@ index 27e81d1..9d84793 100644 return numspecs; } -_AT_@ -1534,14 +1585,17 @@ xdrawglyph(Glyph g, int x, int y) + 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 charlen) + { +- int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); + int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, + width = charlen * win.cw; + Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; +_AT_@ -1527,21 +1577,24 @@ void + xdrawglyph(Glyph g, int x, int y) + { + int numspecs; +- XftGlyphFontSpec spec; ++ XftGlyphFontSpec *specs = xw.specbuf; + +- numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); +- xdrawglyphfontspecs(&spec, g, numspecs, x, y); ++ numspecs = xmakeglyphfontspecs(specs, &g, 1, x, y); ++ xdrawglyphfontspecs(specs, g, numspecs, x, y, (g.mode & ATTR_WIDE) ? 2 : 1); } void _AT_@ -575,7 +597,7 @@ index 27e81d1..9d84793 100644 if (IS_SET(MODE_HIDE)) return; -_AT_@ -1669,18 +1723,16 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1669,18 +1722,16 @@ xdrawline(Line line, int x1, int y1, int x2) Glyph base, new; XftGlyphFontSpec *specs = xw.specbuf; _AT_@ -594,11 +616,11 @@ index 27e81d1..9d84793 100644 - numspecs -= i; + if ((i > 0) && ATTRCMP(base, new)) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x - ox); i = 0; } if (i == 0) { -_AT_@ -1689,8 +1741,10 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1689,8 +1740,10 @@ xdrawline(Line line, int x1, int y1, int x2) } i++; } _AT_@ -606,7 +628,7 @@ index 27e81d1..9d84793 100644 - xdrawglyphfontspecs(specs, base, i, ox, y1); + if (i > 0) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x2 - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x2 - ox); + } } diff --git a/st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-scrollback-20230105-0.9.diff b/st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-scrollback-20240105-0.9.diff similarity index 90% rename from st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-scrollback-20230105-0.9.diff rename to st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-scrollback-20240105-0.9.diff index 688cc6b5..09e9819f 100644 --- a/st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-scrollback-20230105-0.9.diff +++ b/st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-scrollback-20240105-0.9.diff _AT_@ -43,10 +43,10 @@ index 47c615e..d7439a3 100644 STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 diff --git a/hb.c b/hb.c new file mode 100644 -index 0000000..528c040 +index 0000000..99412c8 --- /dev/null +++ b/hb.c -_AT_@ -0,0 +1,124 @@ +_AT_@ -0,0 +1,125 @@ +#include <stdlib.h> +#include <stdio.h> +#include <math.h> _AT_@ -137,6 +137,7 @@ index 0000000..528c040 + + hb_buffer_t *buffer = hb_buffer_create(); + hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); ++ hb_buffer_set_cluster_level(buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); + + /* Resize the buffer if required length is larger. */ + if (hbrunebuffer.capacity < length) { _AT_@ -173,7 +174,7 @@ index 0000000..528c040 +} diff --git a/hb.h b/hb.h new file mode 100644 -index 0000000..88de9bd +index 0000000..3b0ef44 --- /dev/null +++ b/hb.h _AT_@ -0,0 +1,14 @@ _AT_@ -182,10 +183,10 @@ index 0000000..88de9bd +#include <hb-ft.h> + +typedef struct { -+ hb_buffer_t *buffer; -+ hb_glyph_info_t *glyphs; -+ hb_glyph_position_t *positions; -+ unsigned int count; ++ hb_buffer_t *buffer; ++ hb_glyph_info_t *glyphs; ++ hb_glyph_position_t *positions; ++ unsigned int count; +} HbTransformData; + +void hbunloadfonts(); _AT_@ -234,7 +235,7 @@ index 6de960d..94679e4 100644 void xfinishdraw(void); void xloadcols(void); diff --git a/x.c b/x.c -index 27e81d1..5d19ed7 100644 +index 27e81d1..5e11c1f 100644 --- a/x.c +++ b/x.c _AT_@ -19,6 +19,7 @@ char *argv0; _AT_@ -245,14 +246,17 @@ index 27e81d1..5d19ed7 100644 /* types used in config.h */ typedef struct { -_AT_@ -142,6 +143,7 @@ typedef struct { +_AT_@ -142,8 +143,9 @@ typedef struct { } DC; static inline ushort sixd_to_16bit(int); +static void xresetfontsettings(ushort mode, Font **font, int *frcflags); 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); ++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); _AT_@ -759,7 +761,7 @@ xresize(int col, int row) xclear(0, 0, win.w, win.h); _AT_@ -304,13 +308,13 @@ index 27e81d1..5d19ed7 100644 int xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) { -_AT_@ -1270,119 +1291,148 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x +_AT_@ -1270,128 +1291,156 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x FcPattern *fcpattern, *fontpattern; FcFontSet *fcsets[] = { NULL }; FcCharSet *fccharset; - int i, f, numspecs = 0; + int i, f, length = 0, start = 0, numspecs = 0; -+ float cluster_xp = xp, cluster_yp = yp; ++ float cluster_xp = xp, cluster_yp = yp; + HbTransformData shaped = { 0 }; + + /* Initial values. */ _AT_@ -358,7 +362,7 @@ index 27e81d1..5d19ed7 100644 } - yp = winy + font->ascent; - } -- + - /* Lookup character index with default font. */ - glyphidx = XftCharIndex(xw.dpy, font->match, rune); - if (glyphidx) { _AT_@ -370,7 +374,7 @@ index 27e81d1..5d19ed7 100644 - numspecs++; - continue; - } - +- - /* Fallback on font cache, search the font cache for match. */ - for (f = 0; f < frclen; f++) { - glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune); _AT_@ -483,13 +487,16 @@ index 27e81d1..5d19ed7 100644 + } } - } -- + - /* Nothing was found. Use fontconfig to find matching font. */ - if (f >= frclen) { - if (!font->set) - font->set = FcFontSort(0, font->pattern, - 1, 0, &fcres); - fcsets[0] = font->set; ++ /* Cleanup and get ready for next segment. */ ++ hbcleanup(&shaped); ++ start = i; - /* - * Nothing was found in the cache. Now use _AT_@ -505,10 +512,7 @@ index 27e81d1..5d19ed7 100644 - FcPatternAddCharSet(fcpattern, FC_CHARSET, - fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, 1); -+ /* Cleanup and get ready for next segment. */ -+ hbcleanup(&shaped); -+ start = i; - +- - FcConfigSubstitute(0, fcpattern, - FcMatchPattern); - FcDefaultSubstitute(fcpattern); _AT_@ -553,7 +557,27 @@ index 27e81d1..5d19ed7 100644 } return numspecs; -_AT_@ -1534,14 +1584,17 @@ xdrawglyph(Glyph g, int x, int y) + } + + 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 charlen) + { +- int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); + int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, + width = charlen * win.cw; + Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; +_AT_@ -1527,21 +1576,24 @@ void + xdrawglyph(Glyph g, int x, int y) + { + int numspecs; +- XftGlyphFontSpec spec; ++ XftGlyphFontSpec *specs = xw.specbuf; + +- numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); +- xdrawglyphfontspecs(&spec, g, numspecs, x, y); ++ numspecs = xmakeglyphfontspecs(specs, &g, 1, x, y); ++ xdrawglyphfontspecs(specs, g, numspecs, x, y, (g.mode & ATTR_WIDE) ? 2 : 1); } void _AT_@ -573,7 +597,7 @@ index 27e81d1..5d19ed7 100644 if (IS_SET(MODE_HIDE)) return; -_AT_@ -1669,18 +1722,16 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1669,18 +1721,16 @@ xdrawline(Line line, int x1, int y1, int x2) Glyph base, new; XftGlyphFontSpec *specs = xw.specbuf; _AT_@ -592,11 +616,11 @@ index 27e81d1..5d19ed7 100644 - numspecs -= i; + if ((i > 0) && ATTRCMP(base, new)) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x - ox); i = 0; } if (i == 0) { -_AT_@ -1689,8 +1740,10 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1689,8 +1739,10 @@ xdrawline(Line line, int x1, int y1, int x2) } i++; } _AT_@ -604,7 +628,7 @@ index 27e81d1..5d19ed7 100644 - xdrawglyphfontspecs(specs, base, i, ox, y1); + if (i > 0) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x2 - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x2 - ox); + } } diff --git a/st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-scrollback-ringbuffer-20230105-0.9.diff b/st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-scrollback-ringbuffer-20240105-0.9.diff similarity index 89% rename from st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-scrollback-ringbuffer-20230105-0.9.diff rename to st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-scrollback-ringbuffer-20240105-0.9.diff index 600a18d5..ae7da80a 100644 --- a/st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-scrollback-ringbuffer-20230105-0.9.diff +++ b/st.suckless.org/patches/ligatures/0.9/st-ligatures-alpha-scrollback-ringbuffer-20240105-0.9.diff _AT_@ -43,10 +43,10 @@ index 47c615e..d7439a3 100644 STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 diff --git a/hb.c b/hb.c new file mode 100644 -index 0000000..528c040 +index 0000000..99412c8 --- /dev/null +++ b/hb.c -_AT_@ -0,0 +1,124 @@ +_AT_@ -0,0 +1,125 @@ +#include <stdlib.h> +#include <stdio.h> +#include <math.h> _AT_@ -137,6 +137,7 @@ index 0000000..528c040 + + hb_buffer_t *buffer = hb_buffer_create(); + hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); ++ hb_buffer_set_cluster_level(buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); + + /* Resize the buffer if required length is larger. */ + if (hbrunebuffer.capacity < length) { _AT_@ -173,7 +174,7 @@ index 0000000..528c040 +} diff --git a/hb.h b/hb.h new file mode 100644 -index 0000000..88de9bd +index 0000000..3b0ef44 --- /dev/null +++ b/hb.h _AT_@ -0,0 +1,14 @@ _AT_@ -182,20 +183,20 @@ index 0000000..88de9bd +#include <hb-ft.h> + +typedef struct { -+ hb_buffer_t *buffer; -+ hb_glyph_info_t *glyphs; -+ hb_glyph_position_t *positions; -+ unsigned int count; ++ hb_buffer_t *buffer; ++ hb_glyph_info_t *glyphs; ++ hb_glyph_position_t *positions; ++ unsigned int count; +} HbTransformData; + +void hbunloadfonts(); +void hbtransform(HbTransformData *, XftFont *, const Glyph *, int, int); +void hbcleanup(HbTransformData *); diff --git a/st.c b/st.c -index 79ee9ba..454771d 100644 +index c44797b..18aa1bf 100644 --- a/st.c +++ b/st.c -_AT_@ -2711,7 +2711,9 @@ draw(void) +_AT_@ -2759,7 +2759,9 @@ draw(void) drawregion(0, 0, term.col, term.row); if (TSCREEN.off == 0) xdrawcursor(cx, term.c.y, TLINE(term.c.y)[cx], _AT_@ -207,7 +208,7 @@ index 79ee9ba..454771d 100644 term.ocy = term.c.y; xfinishdraw(); diff --git a/st.h b/st.h -index 78762a2..01eea49 100644 +index 073851a..d0b071d 100644 --- a/st.h +++ b/st.h _AT_@ -11,7 +11,8 @@ _AT_@ -234,7 +235,7 @@ index 6de960d..94679e4 100644 void xfinishdraw(void); void xloadcols(void); diff --git a/x.c b/x.c -index 27e81d1..5d19ed7 100644 +index b81f5be..c1611bb 100644 --- a/x.c +++ b/x.c _AT_@ -19,6 +19,7 @@ char *argv0; _AT_@ -245,15 +246,18 @@ index 27e81d1..5d19ed7 100644 /* types used in config.h */ typedef struct { -_AT_@ -142,6 +143,7 @@ typedef struct { +_AT_@ -144,8 +145,9 @@ typedef struct { } DC; static inline ushort sixd_to_16bit(int); +static void xresetfontsettings(ushort mode, Font **font, int *frcflags); 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); ++static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int, int); static void xdrawglyph(Glyph, int, int); -_AT_@ -759,7 +761,7 @@ xresize(int col, int row) + static void xclear(int, int, int, int); + static int xgeommasktogravity(int); +_AT_@ -761,7 +763,7 @@ xresize(int col, int row) xclear(0, 0, win.w, win.h); /* resize to new width */ _AT_@ -262,7 +266,7 @@ index 27e81d1..5d19ed7 100644 } ushort -_AT_@ -1071,6 +1073,9 @@ xunloadfont(Font *f) +_AT_@ -1073,6 +1075,9 @@ xunloadfont(Font *f) void xunloadfonts(void) { _AT_@ -272,7 +276,7 @@ index 27e81d1..5d19ed7 100644 /* Free the loaded fonts in the font cache. */ while (frclen > 0) XftFontClose(xw.dpy, frc[--frclen].font); -_AT_@ -1202,7 +1207,7 @@ xinit(int cols, int rows) +_AT_@ -1204,7 +1209,7 @@ xinit(int cols, int rows) XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); /* font spec buffer */ _AT_@ -281,7 +285,7 @@ index 27e81d1..5d19ed7 100644 /* Xft rendering context */ xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); -_AT_@ -1256,6 +1261,22 @@ xinit(int cols, int rows) +_AT_@ -1258,6 +1263,22 @@ xinit(int cols, int rows) xsel.xtarget = XA_STRING; } _AT_@ -304,13 +308,13 @@ index 27e81d1..5d19ed7 100644 int xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) { -_AT_@ -1270,119 +1291,148 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x +_AT_@ -1272,128 +1293,156 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x FcPattern *fcpattern, *fontpattern; FcFontSet *fcsets[] = { NULL }; FcCharSet *fccharset; - int i, f, numspecs = 0; + int i, f, length = 0, start = 0, numspecs = 0; -+ float cluster_xp = xp, cluster_yp = yp; ++ float cluster_xp = xp, cluster_yp = yp; + HbTransformData shaped = { 0 }; + + /* Initial values. */ _AT_@ -358,7 +362,7 @@ index 27e81d1..5d19ed7 100644 } - yp = winy + font->ascent; - } -- + - /* Lookup character index with default font. */ - glyphidx = XftCharIndex(xw.dpy, font->match, rune); - if (glyphidx) { _AT_@ -370,7 +374,7 @@ index 27e81d1..5d19ed7 100644 - numspecs++; - continue; - } - +- - /* Fallback on font cache, search the font cache for match. */ - for (f = 0; f < frclen; f++) { - glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune); _AT_@ -483,13 +487,16 @@ index 27e81d1..5d19ed7 100644 + } } - } -- + - /* Nothing was found. Use fontconfig to find matching font. */ - if (f >= frclen) { - if (!font->set) - font->set = FcFontSort(0, font->pattern, - 1, 0, &fcres); - fcsets[0] = font->set; ++ /* Cleanup and get ready for next segment. */ ++ hbcleanup(&shaped); ++ start = i; - /* - * Nothing was found in the cache. Now use _AT_@ -505,10 +512,7 @@ index 27e81d1..5d19ed7 100644 - FcPatternAddCharSet(fcpattern, FC_CHARSET, - fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, 1); -+ /* Cleanup and get ready for next segment. */ -+ hbcleanup(&shaped); -+ start = i; - +- - FcConfigSubstitute(0, fcpattern, - FcMatchPattern); - FcDefaultSubstitute(fcpattern); _AT_@ -553,7 +557,27 @@ index 27e81d1..5d19ed7 100644 } return numspecs; -_AT_@ -1534,14 +1584,17 @@ xdrawglyph(Glyph g, int x, int y) + } + + 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 charlen) + { +- int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); + int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, + width = charlen * win.cw; + Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; +_AT_@ -1529,21 +1578,24 @@ void + xdrawglyph(Glyph g, int x, int y) + { + int numspecs; +- XftGlyphFontSpec spec; ++ XftGlyphFontSpec *specs = xw.specbuf; + +- numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); +- xdrawglyphfontspecs(&spec, g, numspecs, x, y); ++ numspecs = xmakeglyphfontspecs(specs, &g, 1, x, y); ++ xdrawglyphfontspecs(specs, g, numspecs, x, y, (g.mode & ATTR_WIDE) ? 2 : 1); } void _AT_@ -573,7 +597,7 @@ index 27e81d1..5d19ed7 100644 if (IS_SET(MODE_HIDE)) return; -_AT_@ -1669,18 +1722,16 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1671,18 +1723,16 @@ xdrawline(Line line, int x1, int y1, int x2) Glyph base, new; XftGlyphFontSpec *specs = xw.specbuf; _AT_@ -592,11 +616,11 @@ index 27e81d1..5d19ed7 100644 - numspecs -= i; + if ((i > 0) && ATTRCMP(base, new)) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x - ox); i = 0; } if (i == 0) { -_AT_@ -1689,8 +1740,10 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1691,8 +1741,10 @@ xdrawline(Line line, int x1, int y1, int x2) } i++; } _AT_@ -604,7 +628,7 @@ index 27e81d1..5d19ed7 100644 - xdrawglyphfontspecs(specs, base, i, ox, y1); + if (i > 0) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x2 - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x2 - ox); + } } diff --git a/st.suckless.org/patches/ligatures/0.9/st-ligatures-boxdraw-20230105-0.9.diff b/st.suckless.org/patches/ligatures/0.9/st-ligatures-boxdraw-20240105-0.9.diff similarity index 91% rename from st.suckless.org/patches/ligatures/0.9/st-ligatures-boxdraw-20230105-0.9.diff rename to st.suckless.org/patches/ligatures/0.9/st-ligatures-boxdraw-20240105-0.9.diff index 31c91740..4f62f432 100644 --- a/st.suckless.org/patches/ligatures/0.9/st-ligatures-boxdraw-20230105-0.9.diff +++ b/st.suckless.org/patches/ligatures/0.9/st-ligatures-boxdraw-20240105-0.9.diff _AT_@ -43,10 +43,10 @@ index 1e306f8..3e13e53 100644 STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 diff --git a/hb.c b/hb.c new file mode 100644 -index 0000000..528c040 +index 0000000..99412c8 --- /dev/null +++ b/hb.c -_AT_@ -0,0 +1,124 @@ +_AT_@ -0,0 +1,125 @@ +#include <stdlib.h> +#include <stdio.h> +#include <math.h> _AT_@ -137,6 +137,7 @@ index 0000000..528c040 + + hb_buffer_t *buffer = hb_buffer_create(); + hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); ++ hb_buffer_set_cluster_level(buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); + + /* Resize the buffer if required length is larger. */ + if (hbrunebuffer.capacity < length) { _AT_@ -173,7 +174,7 @@ index 0000000..528c040 +} diff --git a/hb.h b/hb.h new file mode 100644 -index 0000000..88de9bd +index 0000000..3b0ef44 --- /dev/null +++ b/hb.h _AT_@ -0,0 +1,14 @@ _AT_@ -182,10 +183,10 @@ index 0000000..88de9bd +#include <hb-ft.h> + +typedef struct { -+ hb_buffer_t *buffer; -+ hb_glyph_info_t *glyphs; -+ hb_glyph_position_t *positions; -+ unsigned int count; ++ hb_buffer_t *buffer; ++ hb_glyph_info_t *glyphs; ++ hb_glyph_position_t *positions; ++ unsigned int count; +} HbTransformData; + +void hbunloadfonts(); _AT_@ -233,7 +234,7 @@ index 6de960d..94679e4 100644 void xfinishdraw(void); void xloadcols(void); diff --git a/x.c b/x.c -index bf6bbf9..929a59a 100644 +index bf6bbf9..96b117f 100644 --- a/x.c +++ b/x.c _AT_@ -19,6 +19,7 @@ char *argv0; _AT_@ -244,14 +245,17 @@ index bf6bbf9..929a59a 100644 /* types used in config.h */ typedef struct { -_AT_@ -141,6 +142,7 @@ typedef struct { +_AT_@ -141,8 +142,9 @@ typedef struct { } DC; static inline ushort sixd_to_16bit(int); +static void xresetfontsettings(ushort mode, Font **font, int *frcflags); 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); ++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); _AT_@ -757,7 +759,7 @@ xresize(int col, int row) xclear(0, 0, win.w, win.h); _AT_@ -303,7 +307,7 @@ index bf6bbf9..929a59a 100644 int xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) { -_AT_@ -1255,126 +1276,158 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x +_AT_@ -1255,133 +1276,164 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x FcPattern *fcpattern, *fontpattern; FcFontSet *fcsets[] = { NULL }; FcCharSet *fccharset; _AT_@ -567,7 +571,25 @@ index bf6bbf9..929a59a 100644 return numspecs; } -_AT_@ -1528,14 +1581,17 @@ xdrawglyph(Glyph g, int x, int y) + 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 charlen) + { +- int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); + int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, + width = charlen * win.cw; + Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; +_AT_@ -1521,21 +1573,24 @@ void + xdrawglyph(Glyph g, int x, int y) + { + int numspecs; +- XftGlyphFontSpec spec; ++ XftGlyphFontSpec *specs = xw.specbuf; + +- numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); +- xdrawglyphfontspecs(&spec, g, numspecs, x, y); ++ numspecs = xmakeglyphfontspecs(specs, &g, 1, x, y); ++ xdrawglyphfontspecs(specs, g, numspecs, x, y, (g.mode & ATTR_WIDE) ? 2 : 1); } void _AT_@ -587,7 +609,7 @@ index bf6bbf9..929a59a 100644 if (IS_SET(MODE_HIDE)) return; -_AT_@ -1663,18 +1719,16 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1663,18 +1718,16 @@ xdrawline(Line line, int x1, int y1, int x2) Glyph base, new; XftGlyphFontSpec *specs = xw.specbuf; _AT_@ -606,11 +628,11 @@ index bf6bbf9..929a59a 100644 - numspecs -= i; + if ((i > 0) && ATTRCMP(base, new)) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x - ox); i = 0; } if (i == 0) { -_AT_@ -1683,8 +1737,10 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1683,8 +1736,10 @@ xdrawline(Line line, int x1, int y1, int x2) } i++; } _AT_@ -618,7 +640,7 @@ index bf6bbf9..929a59a 100644 - xdrawglyphfontspecs(specs, base, i, ox, y1); + if (i > 0) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x2 - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x2 - ox); + } } diff --git a/st.suckless.org/patches/ligatures/0.9/st-ligatures-scrollback-20230105-0.9.diff b/st.suckless.org/patches/ligatures/0.9/st-ligatures-scrollback-20240105-0.9.diff similarity index 91% rename from st.suckless.org/patches/ligatures/0.9/st-ligatures-scrollback-20230105-0.9.diff rename to st.suckless.org/patches/ligatures/0.9/st-ligatures-scrollback-20240105-0.9.diff index 8f72dd95..3c21dfc3 100644 --- a/st.suckless.org/patches/ligatures/0.9/st-ligatures-scrollback-20230105-0.9.diff +++ b/st.suckless.org/patches/ligatures/0.9/st-ligatures-scrollback-20240105-0.9.diff _AT_@ -42,10 +42,10 @@ index 1e306f8..3e13e53 100644 STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 diff --git a/hb.c b/hb.c new file mode 100644 -index 0000000..528c040 +index 0000000..99412c8 --- /dev/null +++ b/hb.c -_AT_@ -0,0 +1,124 @@ +_AT_@ -0,0 +1,125 @@ +#include <stdlib.h> +#include <stdio.h> +#include <math.h> _AT_@ -136,6 +136,7 @@ index 0000000..528c040 + + hb_buffer_t *buffer = hb_buffer_create(); + hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); ++ hb_buffer_set_cluster_level(buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); + + /* Resize the buffer if required length is larger. */ + if (hbrunebuffer.capacity < length) { _AT_@ -172,7 +173,7 @@ index 0000000..528c040 +} diff --git a/hb.h b/hb.h new file mode 100644 -index 0000000..88de9bd +index 0000000..3b0ef44 --- /dev/null +++ b/hb.h _AT_@ -0,0 +1,14 @@ _AT_@ -181,10 +182,10 @@ index 0000000..88de9bd +#include <hb-ft.h> + +typedef struct { -+ hb_buffer_t *buffer; -+ hb_glyph_info_t *glyphs; -+ hb_glyph_position_t *positions; -+ unsigned int count; ++ hb_buffer_t *buffer; ++ hb_glyph_info_t *glyphs; ++ hb_glyph_position_t *positions; ++ unsigned int count; +} HbTransformData; + +void hbunloadfonts(); _AT_@ -232,7 +233,7 @@ index 6de960d..94679e4 100644 void xfinishdraw(void); void xloadcols(void); diff --git a/x.c b/x.c -index 2a3bd38..e66cf0c 100644 +index 2a3bd38..0bb51ff 100644 --- a/x.c +++ b/x.c _AT_@ -19,6 +19,7 @@ char *argv0; _AT_@ -243,14 +244,17 @@ index 2a3bd38..e66cf0c 100644 /* types used in config.h */ typedef struct { -_AT_@ -141,6 +142,7 @@ typedef struct { +_AT_@ -141,8 +142,9 @@ typedef struct { } DC; static inline ushort sixd_to_16bit(int); +static void xresetfontsettings(ushort mode, Font **font, int *frcflags); 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); ++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); _AT_@ -757,7 +759,7 @@ xresize(int col, int row) xclear(0, 0, win.w, win.h); _AT_@ -302,7 +306,7 @@ index 2a3bd38..e66cf0c 100644 int xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) { -_AT_@ -1253,121 +1274,151 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x +_AT_@ -1253,128 +1274,157 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x FcPattern *fcpattern, *fontpattern; FcFontSet *fcsets[] = { NULL }; FcCharSet *fccharset; _AT_@ -356,7 +360,7 @@ index 2a3bd38..e66cf0c 100644 } - yp = winy + font->ascent; - } -- + - /* Lookup character index with default font. */ - glyphidx = XftCharIndex(xw.dpy, font->match, rune); - if (glyphidx) { _AT_@ -368,7 +372,7 @@ index 2a3bd38..e66cf0c 100644 - numspecs++; - continue; - } - +- - /* Fallback on font cache, search the font cache for match. */ - for (f = 0; f < frclen; f++) { - glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune); _AT_@ -481,13 +485,16 @@ index 2a3bd38..e66cf0c 100644 + } } - } -- + - /* Nothing was found. Use fontconfig to find matching font. */ - if (f >= frclen) { - if (!font->set) - font->set = FcFontSort(0, font->pattern, - 1, 0, &fcres); - fcsets[0] = font->set; ++ /* Cleanup and get ready for next segment. */ ++ hbcleanup(&shaped); ++ start = i; - /* - * Nothing was found in the cache. Now use _AT_@ -503,10 +510,7 @@ index 2a3bd38..e66cf0c 100644 - FcPatternAddCharSet(fcpattern, FC_CHARSET, - fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, 1); -+ /* Cleanup and get ready for next segment. */ -+ hbcleanup(&shaped); -+ start = i; - +- - FcConfigSubstitute(0, fcpattern, - FcMatchPattern); - FcDefaultSubstitute(fcpattern); _AT_@ -554,7 +558,25 @@ index 2a3bd38..e66cf0c 100644 return numspecs; } -_AT_@ -1517,14 +1568,17 @@ xdrawglyph(Glyph g, int x, int y) + 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 charlen) + { +- int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); + int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, + width = charlen * win.cw; + Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; +_AT_@ -1510,21 +1560,24 @@ void + xdrawglyph(Glyph g, int x, int y) + { + int numspecs; +- XftGlyphFontSpec spec; ++ XftGlyphFontSpec *specs = xw.specbuf; + +- numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); +- xdrawglyphfontspecs(&spec, g, numspecs, x, y); ++ numspecs = xmakeglyphfontspecs(specs, &g, 1, x, y); ++ xdrawglyphfontspecs(specs, g, numspecs, x, y, (g.mode & ATTR_WIDE) ? 2 : 1); } void _AT_@ -574,7 +596,7 @@ index 2a3bd38..e66cf0c 100644 if (IS_SET(MODE_HIDE)) return; -_AT_@ -1652,18 +1706,16 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1652,18 +1705,16 @@ xdrawline(Line line, int x1, int y1, int x2) Glyph base, new; XftGlyphFontSpec *specs = xw.specbuf; _AT_@ -593,11 +615,11 @@ index 2a3bd38..e66cf0c 100644 - numspecs -= i; + if ((i > 0) && ATTRCMP(base, new)) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x - ox); i = 0; } if (i == 0) { -_AT_@ -1672,8 +1724,10 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1672,8 +1723,10 @@ xdrawline(Line line, int x1, int y1, int x2) } i++; } _AT_@ -605,7 +627,7 @@ index 2a3bd38..e66cf0c 100644 - xdrawglyphfontspecs(specs, base, i, ox, y1); + if (i > 0) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x2 - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x2 - ox); + } } diff --git a/st.suckless.org/patches/ligatures/0.9/st-ligatures-scrollback-ringbuffer-20230105-0.9.diff b/st.suckless.org/patches/ligatures/0.9/st-ligatures-scrollback-ringbuffer-20240105-0.9.diff similarity index 90% rename from st.suckless.org/patches/ligatures/0.9/st-ligatures-scrollback-ringbuffer-20230105-0.9.diff rename to st.suckless.org/patches/ligatures/0.9/st-ligatures-scrollback-ringbuffer-20240105-0.9.diff index e9e89453..01ec9371 100644 --- a/st.suckless.org/patches/ligatures/0.9/st-ligatures-scrollback-ringbuffer-20230105-0.9.diff +++ b/st.suckless.org/patches/ligatures/0.9/st-ligatures-scrollback-ringbuffer-20240105-0.9.diff _AT_@ -42,10 +42,10 @@ index 1e306f8..3e13e53 100644 STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 diff --git a/hb.c b/hb.c new file mode 100644 -index 0000000..528c040 +index 0000000..99412c8 --- /dev/null +++ b/hb.c -_AT_@ -0,0 +1,124 @@ +_AT_@ -0,0 +1,125 @@ +#include <stdlib.h> +#include <stdio.h> +#include <math.h> _AT_@ -136,6 +136,7 @@ index 0000000..528c040 + + hb_buffer_t *buffer = hb_buffer_create(); + hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); ++ hb_buffer_set_cluster_level(buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); + + /* Resize the buffer if required length is larger. */ + if (hbrunebuffer.capacity < length) { _AT_@ -172,7 +173,7 @@ index 0000000..528c040 +} diff --git a/hb.h b/hb.h new file mode 100644 -index 0000000..88de9bd +index 0000000..3b0ef44 --- /dev/null +++ b/hb.h _AT_@ -0,0 +1,14 @@ _AT_@ -181,10 +182,10 @@ index 0000000..88de9bd +#include <hb-ft.h> + +typedef struct { -+ hb_buffer_t *buffer; -+ hb_glyph_info_t *glyphs; -+ hb_glyph_position_t *positions; -+ unsigned int count; ++ hb_buffer_t *buffer; ++ hb_glyph_info_t *glyphs; ++ hb_glyph_position_t *positions; ++ unsigned int count; +} HbTransformData; + +void hbunloadfonts(); _AT_@ -232,7 +233,7 @@ index 6de960d..94679e4 100644 void xfinishdraw(void); void xloadcols(void); diff --git a/x.c b/x.c -index 9891e91..ec3567a 100644 +index 9891e91..7d42790 100644 --- a/x.c +++ b/x.c _AT_@ -19,6 +19,7 @@ char *argv0; _AT_@ -243,14 +244,17 @@ index 9891e91..ec3567a 100644 /* types used in config.h */ typedef struct { -_AT_@ -143,6 +144,7 @@ typedef struct { +_AT_@ -143,8 +144,9 @@ typedef struct { } DC; static inline ushort sixd_to_16bit(int); +static void xresetfontsettings(ushort mode, Font **font, int *frcflags); 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); ++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); _AT_@ -759,7 +761,7 @@ xresize(int col, int row) xclear(0, 0, win.w, win.h); _AT_@ -302,13 +306,13 @@ index 9891e91..ec3567a 100644 int xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) { -_AT_@ -1255,119 +1276,148 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x +_AT_@ -1255,128 +1276,156 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x FcPattern *fcpattern, *fontpattern; FcFontSet *fcsets[] = { NULL }; FcCharSet *fccharset; - int i, f, numspecs = 0; + int i, f, length = 0, start = 0, numspecs = 0; -+ float cluster_xp = xp, cluster_yp = yp; ++ float cluster_xp = xp, cluster_yp = yp; + HbTransformData shaped = { 0 }; + + /* Initial values. */ _AT_@ -356,7 +360,7 @@ index 9891e91..ec3567a 100644 } - yp = winy + font->ascent; - } -- + - /* Lookup character index with default font. */ - glyphidx = XftCharIndex(xw.dpy, font->match, rune); - if (glyphidx) { _AT_@ -368,7 +372,7 @@ index 9891e91..ec3567a 100644 - numspecs++; - continue; - } - +- - /* Fallback on font cache, search the font cache for match. */ - for (f = 0; f < frclen; f++) { - glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune); _AT_@ -481,13 +485,16 @@ index 9891e91..ec3567a 100644 + } } - } -- + - /* Nothing was found. Use fontconfig to find matching font. */ - if (f >= frclen) { - if (!font->set) - font->set = FcFontSort(0, font->pattern, - 1, 0, &fcres); - fcsets[0] = font->set; ++ /* Cleanup and get ready for next segment. */ ++ hbcleanup(&shaped); ++ start = i; - /* - * Nothing was found in the cache. Now use _AT_@ -503,10 +510,7 @@ index 9891e91..ec3567a 100644 - FcPatternAddCharSet(fcpattern, FC_CHARSET, - fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, 1); -+ /* Cleanup and get ready for next segment. */ -+ hbcleanup(&shaped); -+ start = i; - +- - FcConfigSubstitute(0, fcpattern, - FcMatchPattern); - FcDefaultSubstitute(fcpattern); _AT_@ -551,7 +555,27 @@ index 9891e91..ec3567a 100644 } return numspecs; -_AT_@ -1519,14 +1569,17 @@ xdrawglyph(Glyph g, int x, int y) + } + + 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 charlen) + { +- int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); + int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, + width = charlen * win.cw; + Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; +_AT_@ -1512,21 +1561,24 @@ void + xdrawglyph(Glyph g, int x, int y) + { + int numspecs; +- XftGlyphFontSpec spec; ++ XftGlyphFontSpec *specs = xw.specbuf; + +- numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); +- xdrawglyphfontspecs(&spec, g, numspecs, x, y); ++ numspecs = xmakeglyphfontspecs(specs, &g, 1, x, y); ++ xdrawglyphfontspecs(specs, g, numspecs, x, y, (g.mode & ATTR_WIDE) ? 2 : 1); } void _AT_@ -571,7 +595,7 @@ index 9891e91..ec3567a 100644 if (IS_SET(MODE_HIDE)) return; -_AT_@ -1654,18 +1707,16 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1654,18 +1706,16 @@ xdrawline(Line line, int x1, int y1, int x2) Glyph base, new; XftGlyphFontSpec *specs = xw.specbuf; _AT_@ -590,11 +614,11 @@ index 9891e91..ec3567a 100644 - numspecs -= i; + if ((i > 0) && ATTRCMP(base, new)) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x - ox); i = 0; } if (i == 0) { -_AT_@ -1674,8 +1725,10 @@ xdrawline(Line line, int x1, int y1, int x2) +_AT_@ -1674,8 +1724,10 @@ xdrawline(Line line, int x1, int y1, int x2) } i++; } _AT_@ -602,7 +626,7 @@ index 9891e91..ec3567a 100644 - xdrawglyphfontspecs(specs, base, i, ox, y1); + if (i > 0) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x2 - ox, ox, y1); -+ xdrawglyphfontspecs(specs, base, numspecs, ox, y1); ++ xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x2 - ox); + } } diff --git a/st.suckless.org/patches/ligatures/index.md b/st.suckless.org/patches/ligatures/index.md index 35d5e0b9..1c3a64d9 100644 --- a/st.suckless.org/patches/ligatures/index.md +++ b/st.suckless.org/patches/ligatures/index.md _AT_@ -28,13 +28,13 @@ Boxdraw Download -------- **0.9**: -* [st-ligatures-0.9](0.9/st-ligatures-20230105-0.9.diff) -* [st-ligatures-scrollback-0.9](0.9/st-ligatures-scrollback-20230105-0.9.diff) -* [st-ligatures-scrollback-ringbuffer-0.9](0.9/st-ligatures-scrollback-ringbuffer-20230105-0.9.diff) -* [st-ligatures-alpha-0.9](0.9/st-ligatures-alpha-20230105-0.9.diff) -* [st-ligatures-alpha-scrollback-0.9](0.9/st-ligatures-alpha-scrollback-20230105-0.9.diff) -* [st-ligatures-alpha-scrollback-ringbuffer-0.9](0.9/st-ligatures-alpha-scrollback-ringbuffer-20230105-0.9.diff) -* [st-ligatures-boxdraw-0.9](0.9/st-ligatures-boxdraw-20230105-0.9.diff) +* [st-ligatures-0.9](0.9/st-ligatures-20240105-0.9.diff) +* [st-ligatures-scrollback-0.9](0.9/st-ligatures-scrollback-20240105-0.9.diff) +* [st-ligatures-scrollback-ringbuffer-0.9](0.9/st-ligatures-scrollback-ringbuffer-20240105-0.9.diff) +* [st-ligatures-alpha-0.9](0.9/st-ligatures-alpha-20240105-0.9.diff) +* [st-ligatures-alpha-scrollback-0.9](0.9/st-ligatures-alpha-scrollback-20240105-0.9.diff) +* [st-ligatures-alpha-scrollback-ringbuffer-0.9](0.9/st-ligatures-alpha-scrollback-ringbuffer-20240105-0.9.diff) +* [st-ligatures-boxdraw-0.9](0.9/st-ligatures-boxdraw-20240105-0.9.diff) **0.8.4**: * [st-ligatures-0.8.4](0.8.4/st-ligatures-20210824-0.8.4.diff)Received on Sat Jan 06 2024 - 16:44:13 CET
This archive was generated by hypermail 2.3.0 : Sat Jan 06 2024 - 16:48:47 CET