On Thu, May 07, 2026 at 11:38:26PM +0000, mohamed.apdelrazeq wrote:
> This patch adds bidirectional text (BiDi) support to stusing the GNU FriBidi library.
>
> RTL languages such as Arabic, Hebrew, and Farsi are now
> displayed correctly. Mixed LTR/RTL text is also handled.
>
> The reordering is done in xdrawline() via fribidi_log2vis()
> before glyphs are rendered.
>
> Dependency: libfribidi
>
> Changes:
> - config.mk: link against libfribidi via pkg-config
> - st.h: include <fribidi.h>
> - x.c: add BiDi reordering in xdrawline()
>
> Tested on: Void Linux x86_64, st 0.9.3
>
> Author: Mohamed <mohamed.apdelrazeq_AT_proton.me>
>
>
>
>
>
> diff --git a/config.mk b/config.mk
> index 2fc854e..f2a80f7 100644
> --- a/config.mk
> +++ b/config.mk
> _AT_@ -15,10 +15,12 @@ PKG_CONFIG = pkg-config
> # includes and libs
> INCS = -I$(X11INC) \
> `$(PKG_CONFIG) --cflags fontconfig` \
> - `$(PKG_CONFIG) --cflags freetype2`
> + `$(PKG_CONFIG) --cflags freetype2` \
> + `$(PKG_CONFIG) --cflags fribidi`
> LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \
> `$(PKG_CONFIG) --libs fontconfig` \
> - `$(PKG_CONFIG) --libs freetype2`
> + `$(PKG_CONFIG) --libs freetype2` \
> + `$(PKG_CONFIG) --libs fribidi`
>
> # flags
> STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600
> diff --git a/st.c b/st.c
> index 6f40e35..3e826c7 100644
> --- a/st.c
> +++ b/st.c
> _AT_@ -2703,3 +2703,4 @@ redraw(void)
> tfulldirt();
> draw();
> }
> +
> diff --git a/st.h b/st.h
> index fd3b0d8..a7d5a37 100644
> --- a/st.h
> +++ b/st.h
> _AT_@ -2,7 +2,7 @@
>
> #include <stdint.h>
> #include <sys/types.h>
> -
> +#include <fribidi.h>
> /* macros */
> #define MIN(a, b) ((a) < (b) ? (a) : (b))
> #define MAX(a, b) ((a) < (b) ? (b) : (a))
> diff --git a/x.c b/x.c
> index d73152b..ae5bfc5 100644
> --- a/x.c
> +++ b/x.c
> _AT_@ -19,7 +19,7 @@ char *argv0;
> #include "arg.h"
> #include "st.h"
> #include "win.h"
> -
> +#include <fribidi.h>
> /* types used in config.h */
> typedef struct {
> uint mod;
> _AT_@ -1657,14 +1657,33 @@ xstartdraw(void)
> void
> xdrawline(Line line, int x1, int y1, int x2)
> {
> - int i, x, ox, numspecs;
> + int i, x, ox, numspecs, len;
> Glyph base, new;
> XftGlyphFontSpec *specs = xw.specbuf;
>
> - numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1);
> + /* BiDi reordering */
> + len = x2 - x1;
> + FriBidiChar fribidi_src[len], fribidi_dst[len];
> + FriBidiParType base_dir = FRIBIDI_PAR_ON;
> + FriBidiLevel *embedding_levels = NULL;
> +
> + for (i = 0; i < len; i++)
> + fribidi_src[i] = (FriBidiChar)line[x1 + i].u;
> +
> + fribidi_log2vis(fribidi_src, len, &base_dir,
> + fribidi_dst, NULL, NULL, NULL);
> +
> + /* Copy reordered codepoints back into a temporary line */
> + Glyph bidi_line[len];
> + for (i = 0; i < len; i++) {
> + bidi_line[i] = line[x1 + i];
> + bidi_line[i].u = (Rune)fribidi_dst[i];
> + }
> +
> + numspecs = xmakeglyphfontspecs(specs, bidi_line, len, x1, y1);
> i = ox = 0;
> for (x = x1; x < x2 && i < numspecs; x++) {
> - new = line[x];
> + new = bidi_line[x - x1];
> if (new.mode == ATTR_WDUMMY)
> continue;
> if (selected(x, y1))
Thanks for the patch, but it's not something st is going to support.
You're welcome to add the patch to the wiki.
--
Kind regards,
Hiltjo
Received on Fri May 08 2026 - 12:26:24 CEST