diff --git a/x11/st-sdk/Makefile b/x11/st-sdk/Makefile index 27661a9..e119b3c 100644 --- a/x11/st-sdk/Makefile +++ b/x11/st-sdk/Makefile @@ -11,8 +11,9 @@ SUPDISTFILES.p= scrollback/st-scrollback-0.8.5.diff \ sync/st-appsync-20200618-b27a383.diff \ disable_bold_italic_fonts/st-disable-bold-italic-fonts-0.8.2.diff \ glyph_wide_support/st-glyph-wide-support-boxdraw-20220411-ef05519.diff \ - anysize/st-expected-anysize-0.9.diff -REVISION= 2 + anysize/st-expected-anysize-0.9.diff \ + alpha/st-alpha-20220206-0.8.5.diff +REVISION= 32 CATEGORIES= x11 @@ -24,11 +25,13 @@ MAINTAINER= Stefan Hagen PERMIT_PACKAGE= Yes # uses pledge() -WANTLIB= X11 Xft c fontconfig freetype m util +WANTLIB= X11 Xft c fontconfig freetype m util harfbuzz SITES= https://dl.suckless.org/st/ SITES.p= https://st.suckless.org/patches/ +LIB_DEPENDS = devel/harfbuzz,-main + MAKE_ENV= LDFLAGS="${LDFLAGS}" \ X11INC=${X11BASE}/include \ X11LIB=${X11BASE}/lib @@ -41,6 +44,9 @@ PATCH_DIST_STRIP= -p1 post-extract: cp ${FILESDIR}/config.h ${WRKSRC}/config.h +post-patch: + cd ${WRKSRC} && patch < ${FILESDIR}/ligatures.diff + do-install: ${INSTALL_PROGRAM} ${WRKBUILD}/st ${PREFIX}/bin/ ${INSTALL_MAN} ${WRKSRC}/st.1 ${PREFIX}/man/man1/ diff --git a/x11/st-sdk/distinfo b/x11/st-sdk/distinfo index 812b360..0498317 100644 --- a/x11/st-sdk/distinfo +++ b/x11/st-sdk/distinfo @@ -1,3 +1,4 @@ +SHA256 (st/alpha/st-alpha-20220206-0.8.5.diff) = QuSAPOKmeDX35TOnB6iijjgEomztFjFFEIlwua7l+4E= SHA256 (st/anysize/st-expected-anysize-0.9.diff) = YosSUn9eALdCt/EsNwNVyOkakJvNnTq251FBCpCb+xE= SHA256 (st/boxdraw/st-boxdraw_v2-0.8.5.diff) = BGRSYG/Otiq8jwaNiRxaXqPY0rinE9BTtWj5cQAYEIE= SHA256 (st/charoffsets/st-charoffsets-20220311-0.8.5.diff) = 5UV0fcvZkRMMuGkyohGcg5a1f0l1OPiD4bTFQvyL1OM= @@ -6,6 +7,7 @@ SHA256 (st/glyph_wide_support/st-glyph-wide-support-boxdraw-20220411-ef05519.dif SHA256 (st/scrollback/st-scrollback-0.8.5.diff) = 3H9SI7JvyBPZHUrjW9qlTWMCTK6fGK/Zs1lLozmd+lU= SHA256 (st/st-0.9.tar.gz) = 82NZeZc06ueFvss3QGPwvoM88i+ItPFpzSUbmTJOCOc= SHA256 (st/sync/st-appsync-20200618-b27a383.diff) = JP0d515EoPNTyv4rr4imEyvgc6OxJ7JecUZKcItZWPQ= +SIZE (st/alpha/st-alpha-20220206-0.8.5.diff) = 4339 SIZE (st/anysize/st-expected-anysize-0.9.diff) = 441 SIZE (st/boxdraw/st-boxdraw_v2-0.8.5.diff) = 17960 SIZE (st/charoffsets/st-charoffsets-20220311-0.8.5.diff) = 1244 diff --git a/x11/st-sdk/files/config.h b/x11/st-sdk/files/config.h index 8a98904..9aa6c37 100644 --- a/x11/st-sdk/files/config.h +++ b/x11/st-sdk/files/config.h @@ -46,7 +46,7 @@ static short cyoffset = 0; * * More advanced example: L" `'\"()[]{}" */ -wchar_t *worddelimiters = L" `'\"|()[]{}·»«›‹‘’;│"; +wchar_t *worddelimiters = L" `'\"|()[]{}·»«›‹‘’;│\t"; /* selection timeouts (in milliseconds) */ static unsigned int doubleclicktimeout = 300; @@ -123,6 +123,9 @@ char *termname = "xterm-256color"; */ unsigned int tabspaces = 8; +/* bg opacity */ +float alpha = 0.65; + /* Terminal colors (16 first used in escape sequence) */ static const char *colorname[] = { /* 8 normal colors */ @@ -148,9 +151,9 @@ static const char *colorname[] = { [255] = 0, /* more colors can be added after 255 to use with DefaultXX */ - "#FF6A00", + "#008080", "#555555", - "#000000", + "#001010", }; /* diff --git a/x11/st-sdk/files/ligatures.diff b/x11/st-sdk/files/ligatures.diff new file mode 100644 index 0000000..8dc7dd3 --- /dev/null +++ b/x11/st-sdk/files/ligatures.diff @@ -0,0 +1,303 @@ +--- Makefile.orig Tue Feb 13 20:36:32 2024 ++++ Makefile Tue Feb 13 20:37:04 2024 +@@ -4,7 +4,7 @@ + + include config.mk + +-SRC = st.c x.c boxdraw.c ++SRC = st.c x.c boxdraw.c hb.c + OBJ = $(SRC:.c=.o) + + all: options st +@@ -22,7 +22,8 @@ + $(CC) $(STCFLAGS) -c $< + + st.o: config.h st.h win.h +-x.o: arg.h config.h st.h win.h ++x.o: arg.h config.h st.h win.h hb.h ++hb.o: st.h + boxdraw.o: config.h st.h boxdraw_data.h + + $(OBJ): config.h config.mk +--- config.mk.orig Tue Feb 13 20:36:32 2024 ++++ config.mk Tue Feb 13 20:38:06 2024 +@@ -15,10 +15,12 @@ + # includes and libs + INCS = -I$(X11INC) \ + `$(PKG_CONFIG) --cflags fontconfig` \ +- `$(PKG_CONFIG) --cflags freetype2` ++ `$(PKG_CONFIG) --cflags freetype2` \ ++ `$(PKG_CONFIG) --cflags harfbuzz` + LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender\ + `$(PKG_CONFIG) --libs fontconfig` \ +- `$(PKG_CONFIG) --libs freetype2` ++ `$(PKG_CONFIG) --libs freetype2` \ ++ `$(PKG_CONFIG) --libs harfbuzz` + + # flags + STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 +@@ -29,7 +31,8 @@ + CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -D_BSD_SOURCE + LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \ + `$(PKG_CONFIG) --libs fontconfig` \ +- `$(PKG_CONFIG) --libs freetype2` ++ `$(PKG_CONFIG) --libs freetype2` \ ++ `$(PKG_CONFIG) --libs harfbuzz` + MANPREFIX = ${PREFIX}/man + + # compiler and linker +--- hb.c.orig Tue Feb 13 20:37:04 2024 ++++ hb.c Tue Feb 13 20:37:04 2024 +@@ -0,0 +1,140 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "st.h" ++ ++void hbtransformsegment(XftFont *xfont, const Glyph *string, hb_codepoint_t *codepoints, int start, int length); ++hb_font_t *hbfindfont(XftFont *match); ++ ++typedef struct { ++ XftFont *match; ++ hb_font_t *font; ++} HbFontMatch; ++ ++static int hbfontslen = 0; ++static HbFontMatch *hbfontcache = NULL; ++ ++void ++hbunloadfonts() ++{ ++ for (int i = 0; i < hbfontslen; i++) { ++ hb_font_destroy(hbfontcache[i].font); ++ XftUnlockFace(hbfontcache[i].match); ++ } ++ ++ if (hbfontcache != NULL) { ++ free(hbfontcache); ++ hbfontcache = NULL; ++ } ++ hbfontslen = 0; ++} ++ ++hb_font_t * ++hbfindfont(XftFont *match) ++{ ++ for (int i = 0; i < hbfontslen; i++) { ++ if (hbfontcache[i].match == match) ++ return hbfontcache[i].font; ++ } ++ ++ /* Font not found in cache, caching it now. */ ++ hbfontcache = realloc(hbfontcache, sizeof(HbFontMatch) * (hbfontslen + 1)); ++ FT_Face face = XftLockFace(match); ++ hb_font_t *font = hb_ft_font_create(face, NULL); ++ if (font == NULL) ++ die("Failed to load Harfbuzz font."); ++ ++ hbfontcache[hbfontslen].match = match; ++ hbfontcache[hbfontslen].font = font; ++ hbfontslen += 1; ++ ++ return font; ++} ++ ++void ++hbtransform(XftGlyphFontSpec *specs, const Glyph *glyphs, size_t len, int x, int y) ++{ ++ int start = 0, length = 1, gstart = 0; ++ hb_codepoint_t *codepoints = calloc(len, sizeof(hb_codepoint_t)); ++ ++ for (int idx = 1, specidx = 1; idx < len; idx++) { ++ if (glyphs[idx].mode & ATTR_WDUMMY) { ++ length += 1; ++ continue; ++ } ++ ++ if (specs[specidx].font != specs[start].font || ATTRCMP(glyphs[gstart], glyphs[idx]) || selected(x + idx, y) != selected(x + gstart, y)) { ++ hbtransformsegment(specs[start].font, glyphs, codepoints, gstart, length); ++ ++ /* Reset the sequence. */ ++ length = 1; ++ start = specidx; ++ gstart = idx; ++ } else { ++ length += 1; ++ } ++ ++ specidx++; ++ } ++ ++ /* EOL. */ ++ hbtransformsegment(specs[start].font, glyphs, codepoints, gstart, length); ++ ++ /* Apply the transformation to glyph specs. */ ++ for (int i = 0, specidx = 0; i < len; i++) { ++ if (glyphs[i].mode & ATTR_WDUMMY) ++ continue; ++ if (glyphs[i].mode & ATTR_BOXDRAW) { ++ specidx++; ++ continue; ++ } ++ ++ if (codepoints[i] != specs[specidx].glyph) ++ ((Glyph *)glyphs)[i].mode |= ATTR_LIGA; ++ ++ specs[specidx++].glyph = codepoints[i]; ++ } ++ ++ free(codepoints); ++} ++ ++void ++hbtransformsegment(XftFont *xfont, const Glyph *string, hb_codepoint_t *codepoints, int start, int length) ++{ ++ hb_font_t *font = hbfindfont(xfont); ++ if (font == NULL) ++ return; ++ ++ Rune rune; ++ ushort mode = USHRT_MAX; ++ hb_buffer_t *buffer = hb_buffer_create(); ++ hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); ++ ++ /* Fill buffer with codepoints. */ ++ for (int i = start; i < (start+length); i++) { ++ rune = string[i].u; ++ mode = string[i].mode; ++ if (mode & ATTR_WDUMMY) ++ rune = 0x0020; ++ hb_buffer_add_codepoints(buffer, &rune, 1, 0, 1); ++ } ++ ++ /* Shape the segment. */ ++ hb_shape(font, buffer, NULL, 0); ++ ++ /* Get new glyph info. */ ++ hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buffer, NULL); ++ ++ /* Write new codepoints. */ ++ for (int i = 0; i < length; i++) { ++ hb_codepoint_t gid = info[i].codepoint; ++ codepoints[start+i] = gid; ++ } ++ ++ /* Cleanup. */ ++ hb_buffer_destroy(buffer); ++} +--- hb.h.orig Tue Feb 13 20:37:04 2024 ++++ hb.h Tue Feb 13 20:37:04 2024 +@@ -0,0 +1,7 @@ ++#include ++#include ++#include ++ ++void hbunloadfonts(); ++void hbtransform(XftGlyphFontSpec *, const Glyph *, size_t, int, int); ++ +--- st.c.orig Tue Feb 13 20:36:32 2024 ++++ st.c Tue Feb 13 20:38:55 2024 +@@ -2758,7 +2758,8 @@ + drawregion(0, 0, term.col, term.row); + 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]); ++ 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(); +--- st.h.orig Tue Feb 13 20:36:32 2024 ++++ st.h Tue Feb 13 20:37:04 2024 +@@ -11,7 +11,8 @@ + #define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d)) + #define DEFAULT(a, b) (a) = (a) ? (a) : (b) + #define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) +-#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \ ++#define ATTRCMP(a, b) (((a).mode & (~ATTR_WRAP) & (~ATTR_LIGA)) != ((b).mode & (~ATTR_WRAP) & (~ATTR_LIGA)) || \ ++ (a).fg != (b).fg || \ + (a).bg != (b).bg) + #define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \ + (t1.tv_nsec-t2.tv_nsec)/1E6) +@@ -34,6 +35,7 @@ + ATTR_WIDE = 1 << 9, + ATTR_WDUMMY = 1 << 10, + ATTR_BOXDRAW = 1 << 11, ++ ATTR_LIGA = 1 << 12, + ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT, + }; + +--- win.h.orig Tue Oct 4 19:41:26 2022 ++++ win.h Tue Feb 13 20:37:04 2024 +@@ -25,7 +25,7 @@ + + 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); +--- x.c.orig Tue Feb 13 20:36:32 2024 ++++ x.c Tue Feb 13 20:37:04 2024 +@@ -19,6 +19,7 @@ + #include "arg.h" + #include "st.h" + #include "win.h" ++#include "hb.h" + + /* types used in config.h */ + typedef struct { +@@ -1079,6 +1080,9 @@ + void + xunloadfonts(void) + { ++ /* Clear Harfbuzz font cache. */ ++ hbunloadfonts(); ++ + /* Free the loaded fonts in the font cache. */ + while (frclen > 0) + XftFontClose(xw.dpy, frc[--frclen].font); +@@ -1288,7 +1292,7 @@ + mode = glyphs[i].mode; + + /* Skip dummy wide-character spacing. */ +- if (mode == ATTR_WDUMMY) ++ if (mode & ATTR_WDUMMY) + continue; + + /* Determine font for glyph if different from previous glyph. */ +@@ -1400,6 +1404,9 @@ + numspecs++; + } + ++ /* Harfbuzz transformation for ligatures. */ ++ hbtransform(specs, glyphs, len, x, y); ++ + return numspecs; + } + +@@ -1547,14 +1554,17 @@ + } + + 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;