From 2788c027f8e6b8364bd35eac4d9a7c43b606faf3 Mon Sep 17 00:00:00 2001 From: doryan Date: Tue, 10 Sep 2024 18:43:02 +0400 Subject: [PATCH] add ligatures --- Makefile | 5 +- Makefile.orig | 57 ++++++ config.h | 474 ++++++++++++++++++++++++++++++++++++++++++++++++++ config.mk | 6 +- hb.c | 125 +++++++++++++ hb.h | 14 ++ st | Bin 0 -> 110432 bytes st.c | 3 +- st.h | 3 +- st.o | Bin 0 -> 77920 bytes win.h | 2 +- x.c | 290 +++++++++++++++++------------- x.o | Bin 0 -> 74760 bytes 13 files changed, 853 insertions(+), 126 deletions(-) create mode 100644 Makefile.orig create mode 100644 config.h create mode 100644 hb.c create mode 100644 hb.h create mode 100755 st create mode 100644 st.o create mode 100644 x.o diff --git a/Makefile b/Makefile index 4d49649..a65af59 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ include config.mk -SRC = st.c x.c +SRC = st.c x.c hb.c OBJ = $(SRC:.c=.o) all: options st @@ -22,7 +22,8 @@ config.h: $(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 $(OBJ): config.h config.mk diff --git a/Makefile.orig b/Makefile.orig new file mode 100644 index 0000000..4d49649 --- /dev/null +++ b/Makefile.orig @@ -0,0 +1,57 @@ +# st - simple terminal +# See LICENSE file for copyright and license details. +.POSIX: + +include config.mk + +SRC = st.c x.c +OBJ = $(SRC:.c=.o) + +all: options st + +options: + @echo st build options: + @echo "CFLAGS = $(STCFLAGS)" + @echo "LDFLAGS = $(STLDFLAGS)" + @echo "CC = $(CC)" + +config.h: + cp config.def.h config.h + +.c.o: + $(CC) $(STCFLAGS) -c $< + +st.o: config.h st.h win.h +x.o: arg.h config.h st.h win.h + +$(OBJ): config.h config.mk + +st: $(OBJ) + $(CC) -o $@ $(OBJ) $(STLDFLAGS) + +clean: + rm -f st $(OBJ) st-$(VERSION).tar.gz config.h + +dist: clean + mkdir -p st-$(VERSION) + cp -R FAQ LEGACY TODO LICENSE Makefile README config.mk\ + config.def.h st.info st.1 arg.h st.h win.h $(SRC)\ + st-$(VERSION) + tar -cf - st-$(VERSION) | gzip > st-$(VERSION).tar.gz + rm -rf st-$(VERSION) + +install: st + mkdir -p $(DESTDIR)$(PREFIX)/bin + cp -f st $(DESTDIR)$(PREFIX)/bin + chmod 755 $(DESTDIR)$(PREFIX)/bin/st + mkdir -p $(DESTDIR)$(MANPREFIX)/man1 + sed "s/VERSION/$(VERSION)/g" < st.1 > $(DESTDIR)$(MANPREFIX)/man1/st.1 + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/st.1 + tic -sx st.info + @echo Please see the README file regarding the terminfo entry of st. + +uninstall: + rm -f $(DESTDIR)$(PREFIX)/bin/st + rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1 + +.PHONY: all options clean dist install uninstall diff --git a/config.h b/config.h new file mode 100644 index 0000000..91ab8ca --- /dev/null +++ b/config.h @@ -0,0 +1,474 @@ +/* See LICENSE file for copyright and license details. */ + +/* + * appearance + * + * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html + */ +static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; +static int borderpx = 2; + +/* + * What program is execed by st depends of these precedence rules: + * 1: program passed with -e + * 2: scroll and/or utmp + * 3: SHELL environment variable + * 4: value of shell in /etc/passwd + * 5: value of shell in config.h + */ +static char *shell = "/bin/sh"; +char *utmp = NULL; +/* scroll program: to enable use a string like "scroll" */ +char *scroll = NULL; +char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400"; + +/* identification sequence returned in DA and DECID */ +char *vtiden = "\033[?6c"; + +/* Kerning / character bounding-box multipliers */ +static float cwscale = 1.0; +static float chscale = 1.0; + +/* + * word delimiter string + * + * More advanced example: L" `'\"()[]{}" + */ +wchar_t *worddelimiters = L" "; + +/* selection timeouts (in milliseconds) */ +static unsigned int doubleclicktimeout = 300; +static unsigned int tripleclicktimeout = 600; + +/* alt screens */ +int allowaltscreen = 1; + +/* allow certain non-interactive (insecure) window operations such as: + setting the clipboard text */ +int allowwindowops = 0; + +/* + * draw latency range in ms - from new content/keypress/etc until drawing. + * within this range, st draws when content stops arriving (idle). mostly it's + * near minlatency, but it waits longer for slow updates to avoid partial draw. + * low minlatency will tear/flicker more, as it can "detect" idle too early. + */ +static double minlatency = 8; +static double maxlatency = 33; + +/* + * blinking timeout (set to 0 to disable blinking) for the terminal blinking + * attribute. + */ +static unsigned int blinktimeout = 800; + +/* + * thickness of underline and bar cursors + */ +static unsigned int cursorthickness = 2; + +/* + * bell volume. It must be a value between -100 and 100. Use 0 for disabling + * it + */ +static int bellvolume = 0; + +/* default TERM value */ +char *termname = "st-256color"; + +/* + * spaces per tab + * + * When you are changing this value, don't forget to adapt the »it« value in + * the st.info and appropriately install the st.info in the environment where + * you use this st version. + * + * it#$tabspaces, + * + * Secondly make sure your kernel is not expanding tabs. When running `stty + * -a` »tab0« should appear. You can tell the terminal to not expand tabs by + * running following command: + * + * stty tabs + */ +unsigned int tabspaces = 8; + +/* Terminal colors (16 first used in escape sequence) */ +static const char *colorname[] = { + /* 8 normal colors */ + "black", + "red3", + "green3", + "yellow3", + "blue2", + "magenta3", + "cyan3", + "gray90", + + /* 8 bright colors */ + "gray50", + "red", + "green", + "yellow", + "#5c5cff", + "magenta", + "cyan", + "white", + + [255] = 0, + + /* more colors can be added after 255 to use with DefaultXX */ + "#cccccc", + "#555555", + "gray90", /* default foreground colour */ + "black", /* default background colour */ +}; + + +/* + * Default colors (colorname index) + * foreground, background, cursor, reverse cursor + */ +unsigned int defaultfg = 258; +unsigned int defaultbg = 259; +unsigned int defaultcs = 256; +static unsigned int defaultrcs = 257; + +/* + * Default shape of cursor + * 2: Block ("█") + * 4: Underline ("_") + * 6: Bar ("|") + * 7: Snowman ("☃") + */ +static unsigned int cursorshape = 2; + +/* + * Default columns and rows numbers + */ + +static unsigned int cols = 80; +static unsigned int rows = 24; + +/* + * Default colour and shape of the mouse cursor + */ +static unsigned int mouseshape = XC_xterm; +static unsigned int mousefg = 7; +static unsigned int mousebg = 0; + +/* + * Color used to display font attributes when fontconfig selected a font which + * doesn't match the ones requested. + */ +static unsigned int defaultattr = 11; + +/* + * Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set). + * Note that if you want to use ShiftMask with selmasks, set this to an other + * modifier, set to 0 to not use it. + */ +static uint forcemousemod = ShiftMask; + +/* + * Internal mouse shortcuts. + * Beware that overloading Button1 will disable the selection. + */ +static MouseShortcut mshortcuts[] = { + /* mask button function argument release */ + { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, + { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, + { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, + { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, + { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, +}; + +/* Internal keyboard shortcuts. */ +#define MODKEY Mod1Mask +#define TERMMOD (ControlMask|ShiftMask) + +static Shortcut shortcuts[] = { + /* mask keysym function argument */ + { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} }, + { ControlMask, XK_Print, toggleprinter, {.i = 0} }, + { ShiftMask, XK_Print, printscreen, {.i = 0} }, + { XK_ANY_MOD, XK_Print, printsel, {.i = 0} }, + { TERMMOD, XK_Prior, zoom, {.f = +1} }, + { TERMMOD, XK_Next, zoom, {.f = -1} }, + { TERMMOD, XK_Home, zoomreset, {.f = 0} }, + { TERMMOD, XK_C, clipcopy, {.i = 0} }, + { TERMMOD, XK_V, clippaste, {.i = 0} }, + { TERMMOD, XK_Y, selpaste, {.i = 0} }, + { ShiftMask, XK_Insert, selpaste, {.i = 0} }, + { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, +}; + +/* + * Special keys (change & recompile st.info accordingly) + * + * Mask value: + * * Use XK_ANY_MOD to match the key no matter modifiers state + * * Use XK_NO_MOD to match the key alone (no modifiers) + * appkey value: + * * 0: no value + * * > 0: keypad application mode enabled + * * = 2: term.numlock = 1 + * * < 0: keypad application mode disabled + * appcursor value: + * * 0: no value + * * > 0: cursor application mode enabled + * * < 0: cursor application mode disabled + * + * Be careful with the order of the definitions because st searches in + * this table sequentially, so any XK_ANY_MOD must be in the last + * position for a key. + */ + +/* + * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) + * to be mapped below, add them to this array. + */ +static KeySym mappedkeys[] = { -1 }; + +/* + * State bits to ignore when matching key or button events. By default, + * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored. + */ +static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; + +/* + * This is the huge key array which defines all compatibility to the Linux + * world. Please decide about changes wisely. + */ +static Key key[] = { + /* keysym mask string appkey appcursor */ + { XK_KP_Home, ShiftMask, "\033[2J", 0, -1}, + { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1}, + { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1}, + { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1}, + { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0}, + { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1}, + { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1}, + { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0}, + { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1}, + { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1}, + { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0}, + { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1}, + { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1}, + { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0}, + { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1}, + { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1}, + { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0}, + { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, + { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0}, + { XK_KP_End, ControlMask, "\033[J", -1, 0}, + { XK_KP_End, ControlMask, "\033[1;5F", +1, 0}, + { XK_KP_End, ShiftMask, "\033[K", -1, 0}, + { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0}, + { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0}, + { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0}, + { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0}, + { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0}, + { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0}, + { XK_KP_Insert, ControlMask, "\033[L", -1, 0}, + { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0}, + { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, + { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, + { XK_KP_Delete, ControlMask, "\033[M", -1, 0}, + { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0}, + { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0}, + { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0}, + { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0}, + { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, + { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0}, + { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0}, + { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0}, + { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0}, + { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0}, + { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0}, + { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0}, + { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0}, + { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0}, + { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0}, + { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0}, + { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0}, + { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0}, + { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0}, + { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0}, + { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0}, + { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0}, + { XK_Up, ShiftMask, "\033[1;2A", 0, 0}, + { XK_Up, Mod1Mask, "\033[1;3A", 0, 0}, + { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0}, + { XK_Up, ControlMask, "\033[1;5A", 0, 0}, + { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0}, + { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0}, + { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0}, + { XK_Up, XK_ANY_MOD, "\033[A", 0, -1}, + { XK_Up, XK_ANY_MOD, "\033OA", 0, +1}, + { XK_Down, ShiftMask, "\033[1;2B", 0, 0}, + { XK_Down, Mod1Mask, "\033[1;3B", 0, 0}, + { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0}, + { XK_Down, ControlMask, "\033[1;5B", 0, 0}, + { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0}, + { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0}, + { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0}, + { XK_Down, XK_ANY_MOD, "\033[B", 0, -1}, + { XK_Down, XK_ANY_MOD, "\033OB", 0, +1}, + { XK_Left, ShiftMask, "\033[1;2D", 0, 0}, + { XK_Left, Mod1Mask, "\033[1;3D", 0, 0}, + { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0}, + { XK_Left, ControlMask, "\033[1;5D", 0, 0}, + { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0}, + { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0}, + { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0}, + { XK_Left, XK_ANY_MOD, "\033[D", 0, -1}, + { XK_Left, XK_ANY_MOD, "\033OD", 0, +1}, + { XK_Right, ShiftMask, "\033[1;2C", 0, 0}, + { XK_Right, Mod1Mask, "\033[1;3C", 0, 0}, + { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0}, + { XK_Right, ControlMask, "\033[1;5C", 0, 0}, + { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0}, + { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0}, + { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0}, + { XK_Right, XK_ANY_MOD, "\033[C", 0, -1}, + { XK_Right, XK_ANY_MOD, "\033OC", 0, +1}, + { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0}, + { XK_Return, Mod1Mask, "\033\r", 0, 0}, + { XK_Return, XK_ANY_MOD, "\r", 0, 0}, + { XK_Insert, ShiftMask, "\033[4l", -1, 0}, + { XK_Insert, ShiftMask, "\033[2;2~", +1, 0}, + { XK_Insert, ControlMask, "\033[L", -1, 0}, + { XK_Insert, ControlMask, "\033[2;5~", +1, 0}, + { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, + { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, + { XK_Delete, ControlMask, "\033[M", -1, 0}, + { XK_Delete, ControlMask, "\033[3;5~", +1, 0}, + { XK_Delete, ShiftMask, "\033[2K", -1, 0}, + { XK_Delete, ShiftMask, "\033[3;2~", +1, 0}, + { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0}, + { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, + { XK_BackSpace, XK_NO_MOD, "\177", 0, 0}, + { XK_BackSpace, Mod1Mask, "\033\177", 0, 0}, + { XK_Home, ShiftMask, "\033[2J", 0, -1}, + { XK_Home, ShiftMask, "\033[1;2H", 0, +1}, + { XK_Home, XK_ANY_MOD, "\033[H", 0, -1}, + { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1}, + { XK_End, ControlMask, "\033[J", -1, 0}, + { XK_End, ControlMask, "\033[1;5F", +1, 0}, + { XK_End, ShiftMask, "\033[K", -1, 0}, + { XK_End, ShiftMask, "\033[1;2F", +1, 0}, + { XK_End, XK_ANY_MOD, "\033[4~", 0, 0}, + { XK_Prior, ControlMask, "\033[5;5~", 0, 0}, + { XK_Prior, ShiftMask, "\033[5;2~", 0, 0}, + { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, + { XK_Next, ControlMask, "\033[6;5~", 0, 0}, + { XK_Next, ShiftMask, "\033[6;2~", 0, 0}, + { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0}, + { XK_F1, XK_NO_MOD, "\033OP" , 0, 0}, + { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0}, + { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0}, + { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0}, + { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0}, + { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0}, + { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0}, + { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0}, + { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0}, + { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0}, + { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0}, + { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0}, + { XK_F3, XK_NO_MOD, "\033OR" , 0, 0}, + { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0}, + { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0}, + { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0}, + { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0}, + { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0}, + { XK_F4, XK_NO_MOD, "\033OS" , 0, 0}, + { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0}, + { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0}, + { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0}, + { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0}, + { XK_F5, XK_NO_MOD, "\033[15~", 0, 0}, + { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0}, + { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0}, + { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0}, + { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0}, + { XK_F6, XK_NO_MOD, "\033[17~", 0, 0}, + { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0}, + { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0}, + { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0}, + { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0}, + { XK_F7, XK_NO_MOD, "\033[18~", 0, 0}, + { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0}, + { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0}, + { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0}, + { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0}, + { XK_F8, XK_NO_MOD, "\033[19~", 0, 0}, + { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0}, + { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0}, + { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0}, + { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0}, + { XK_F9, XK_NO_MOD, "\033[20~", 0, 0}, + { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0}, + { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0}, + { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0}, + { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0}, + { XK_F10, XK_NO_MOD, "\033[21~", 0, 0}, + { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0}, + { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0}, + { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0}, + { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0}, + { XK_F11, XK_NO_MOD, "\033[23~", 0, 0}, + { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0}, + { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0}, + { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0}, + { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0}, + { XK_F12, XK_NO_MOD, "\033[24~", 0, 0}, + { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0}, + { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0}, + { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0}, + { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0}, + { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0}, + { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0}, + { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0}, + { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0}, + { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0}, + { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0}, + { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0}, + { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0}, + { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0}, + { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0}, + { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0}, + { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0}, + { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0}, + { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0}, + { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0}, + { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0}, + { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0}, + { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0}, + { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0}, + { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0}, + { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0}, + { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0}, + { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0}, +}; + +/* + * Selection types' masks. + * Use the same masks as usual. + * Button1Mask is always unset, to make masks match between ButtonPress. + * ButtonRelease and MotionNotify. + * If no match is found, regular selection is used. + */ +static uint selmasks[] = { + [SEL_RECTANGULAR] = Mod1Mask, +}; + +/* + * Printable characters in ASCII, used to estimate the advance width + * of single wide characters. + */ +static char ascii_printable[] = + " !\"#$%&'()*+,-./0123456789:;<=>?" + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" + "`abcdefghijklmnopqrstuvwxyz{|}~"; diff --git a/config.mk b/config.mk index 1e306f8..3e13e53 100644 --- a/config.mk +++ b/config.mk @@ -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 harfbuzz` LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \ `$(PKG_CONFIG) --libs fontconfig` \ - `$(PKG_CONFIG) --libs freetype2` + `$(PKG_CONFIG) --libs freetype2` \ + `$(PKG_CONFIG) --libs harfbuzz` # flags STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 diff --git a/hb.c b/hb.c new file mode 100644 index 0000000..99412c8 --- /dev/null +++ b/hb.c @@ -0,0 +1,125 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "st.h" +#include "hb.h" + +#define FEATURE(c1,c2,c3,c4) { .tag = HB_TAG(c1,c2,c3,c4), .value = 1, .start = HB_FEATURE_GLOBAL_START, .end = HB_FEATURE_GLOBAL_END } +#define BUFFER_STEP 256 + +hb_font_t *hbfindfont(XftFont *match); + +typedef struct { + XftFont *match; + hb_font_t *font; +} HbFontMatch; + +typedef struct { + size_t capacity; + HbFontMatch *fonts; +} HbFontCache; + +static HbFontCache hbfontcache = { 0, NULL }; + +typedef struct { + size_t capacity; + Rune *runes; +} RuneBuffer; + +static RuneBuffer hbrunebuffer = { 0, NULL }; + +/* + * Poplulate the array with a list of font features, wrapped in FEATURE macro, + * e. g. + * FEATURE('c', 'a', 'l', 't'), FEATURE('d', 'l', 'i', 'g') + */ +hb_feature_t features[] = { }; + +void +hbunloadfonts() +{ + for (int i = 0; i < hbfontcache.capacity; i++) { + hb_font_destroy(hbfontcache.fonts[i].font); + XftUnlockFace(hbfontcache.fonts[i].match); + } + + if (hbfontcache.fonts != NULL) { + free(hbfontcache.fonts); + hbfontcache.fonts = NULL; + } + hbfontcache.capacity = 0; +} + +hb_font_t * +hbfindfont(XftFont *match) +{ + for (int i = 0; i < hbfontcache.capacity; i++) { + if (hbfontcache.fonts[i].match == match) + return hbfontcache.fonts[i].font; + } + + /* Font not found in cache, caching it now. */ + hbfontcache.fonts = realloc(hbfontcache.fonts, sizeof(HbFontMatch) * (hbfontcache.capacity + 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.fonts[hbfontcache.capacity].match = match; + hbfontcache.fonts[hbfontcache.capacity].font = font; + hbfontcache.capacity += 1; + + return font; +} + +void hbtransform(HbTransformData *data, XftFont *xfont, const Glyph *glyphs, int start, int length) { + ushort mode = USHRT_MAX; + unsigned int glyph_count; + int rune_idx, glyph_idx, end = start + length; + + hb_font_t *font = hbfindfont(xfont); + if (font == NULL) + return; + + 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) { + hbrunebuffer.capacity = (length / BUFFER_STEP + 1) * BUFFER_STEP; + hbrunebuffer.runes = realloc(hbrunebuffer.runes, hbrunebuffer.capacity * sizeof(Rune)); + } + + /* Fill buffer with codepoints. */ + for (rune_idx = 0, glyph_idx = start; glyph_idx < end; glyph_idx++, rune_idx++) { + hbrunebuffer.runes[rune_idx] = glyphs[glyph_idx].u; + mode = glyphs[glyph_idx].mode; + if (mode & ATTR_WDUMMY) + hbrunebuffer.runes[rune_idx] = 0x0020; + } + hb_buffer_add_codepoints(buffer, hbrunebuffer.runes, length, 0, length); + + /* Shape the segment. */ + hb_shape(font, buffer, features, sizeof(features)/sizeof(hb_feature_t)); + + /* Get new glyph info. */ + hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buffer, &glyph_count); + hb_glyph_position_t *pos = hb_buffer_get_glyph_positions(buffer, &glyph_count); + + /* Fill the output. */ + data->buffer = buffer; + data->glyphs = info; + data->positions = pos; + data->count = glyph_count; +} + +void hbcleanup(HbTransformData *data) { + hb_buffer_destroy(data->buffer); + memset(data, 0, sizeof(HbTransformData)); +} diff --git a/hb.h b/hb.h new file mode 100644 index 0000000..3b0ef44 --- /dev/null +++ b/hb.h @@ -0,0 +1,14 @@ +#include +#include +#include + +typedef struct { + 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 b/st new file mode 100755 index 0000000000000000000000000000000000000000..7db6687a1ac5f3eb64aa5e2671fd322749a32818 GIT binary patch literal 110432 zcmeFaX?PS>8aCXWbV0y`Y9PT3ibPD50D*u+(?UZUI#7)XL>9%BB_t3HNldy~lqJxK zP?ilDSKLNW$6?eNBhDbALKa8@qSN38C=x)lnihzlA*}u0 _VsjmM+&$<2CA}Oqp3qe(pV5s~ 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%0AFK(zsLZ;#sGhf0sa94 z{APj2{WzXCs`2P`1OC0t?`Hp>CEYK+71*6Wdt!pu9e%I@{xk#pGy^<+Q?NVz^9=Ck z8{qv0_|*pZ8w~Jw8sPt8fZql@^`kwyarRXM{*QsD_I#MH$Flpyw+p-T!$G0Ps-4aA zQ@H-9g?;7Cu7~sD$z#lfiV-X_i#i|W_Um7XCvxj67 z;msJ_%43X2vJdk=_9pY=x;$-z1zx6Of3pnmMXcvJp6ArD(AkXN%>Ez8_;U^PXfX?H zy4DJHtzp5--D+#GoW<$#yXxG5pvzw!Y^Zi%5t=K2#YIkEb)CmoWA{`$gFZhNf`wW% ztbuCuxPmSx9=_<7qq-LQtL=Wjy|voq4f%YnsIHLXDx9X8klO9`su+$OunjfH2Dh$T;grzJ*G3(|5hkISo}Pz_oz;KHIG ztiub|hCCjb3N+gr0}j87cp7|7uAomsI}(n}i9$xKlxqr(&&sOKLV-yQM0_5P7HkX! zgZ3IN;PM2#_C|tUpT7ZiEpur>yhP98^Z5K=^J8I=%dfe8wN9)vgU$fTY#)}AP?Om(Z(yTSP1MV8P#|_g$-UfIZ3-BEET7wTO z*X)iUxuij?)pUfgTC9bN8VcC!Tv`j3TRLS;v{Y&PII+jeHt==e?wST=ykwQcSEPm?gqD9W9X(>*FE^BB6Z+|;YJ)T22CG+$#-tlAU_TI(1mxC zQ!u-H_meS@n34v3R&5$h_c zp;CRgT7seyy`p*5#&JRt!6pt>RT~tUdZ-;Elm!~?4ut)#vV;(c9MpVCw*w(x1P8?H zIEk*Z#nuKSX!w+p{+Qf(H`$}j1MSpyj=*vUMKpM zeQ6vX4Jhbph(n2bA>g^XAOD8D_2*~38Al{;TFlLwZI(+**&TS*VJi9RrrU!MQQU+{5ylu-S7WEJ0B1I~7N8N36KQ_c*_J{<%n&dVVt9%(TR5Xz zSD^JFkk(;#fC(B_=ktRRqEU(v+>8eluu>gk6bxd!F#w|l`x;TM+F%hP$}Acnsr^@A zfJ6x3HVT~%T1Z`8QytrqClbB|YuDWfcnI@xrjjRS`e3VAY%e_FLEU2sejOq=+Alg_ zY2i#U;!tN4a~C#)_}G=gjYJo%Mm+NXCTg^$UZ<-?%!Rb7IS7N&$<@_pAsqN+Wx%OH zAEZ%8nq*djwG7kVN*|>sJuA4GOE zSrb(zhqe|vISAm%1dLcb#lhsObI3s?EyZlP4zYv_E1#Vak6KWBv(qFbKDU{kP@rCG zsc~Ua4)Za-#?h;*YXSl80aTBrvpJ$Ehls(J8yo0_h*Vt$VMGy+u2faDdL5z}cETkP137H0^3*zoE-`B0j7Ngv=7i)oS*49rKjz=(!9YZbK^zqcTWc_C)@)V$H+L_;8JD1uQ*c!DMxqZ=_< zj`QR`nW9Q6Lj&`;X8WA(S~mqoJkMm@yo+3oLGdgJ8fRRUz>_|2t-CJ9{Z-O?oe`!= z^uh|nN!fYDjIZ1c^BXbo_Qy{IW;%|n&suSw6_+h~`CkbpFcNCr?R9DmEcswm@u)DjuCZb&nTZCDVnxTs6s^)aNaB6}!OS2N1 z5;k^4$?@45MKxV7qgWbO*qM$}8tkdk7IFZbDWV!TsdBUoni`T#nz+m$&*vOG!)!q#I{Kv2$OZ*h9TInWhT{6i#U-EKeh4KbYn6HMr;!hn5*=ZJ^5mnP_jJl~js({G6?m{FQRPjzJydp(|H(=wf{USuI53=tH}M*}ny zjXkIa4d-Zf65v#$2aiCB$x$YfnROUoGK1(!S|&wfF!@A9XS(Y7;tV}G)_EjFOHpR$LFTW7@L-;0-D!=+p zk%H+ghviyg)7x(c7Pn|S%dfs;q~KxPr=pF@NWN3@g9(Yvjh%|D^528&nzSjXzJnyO zQinkXM=~g=6YsQN;UCt?t96tLt`2jC3{?IKyGbXn*6%5Zjbrh&i{>OO1BDe(ff_(Sak&Ob|sSMvIM zj9?d=f~T;&PQ3GZ&x1OG^1DLQcifaNg(G-Xjl^Dv_1CeRo_B_Uys2JtUZE4v9g62l z^*GA!O1H$mp(E-JwZ%XXPVc|-mrBluRmE^2l)Qpv z11APGN)9zHD7uo1Jyx+p;Rr5a`SKGbb~M0x?5f?W@t5MGu82b5;cH}0ZXS;X5 (b) ? (b) : (x) -#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \ +#define ATTRCMP(a, b) (((a).mode & (~ATTR_WRAP)) != ((b).mode & (~ATTR_WRAP)) || \ + (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) diff --git a/st.o b/st.o new file mode 100644 index 0000000000000000000000000000000000000000..4f58252eb9a4a7092fc011f6d307640038692454 GIT binary patch literal 77920 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 literal 0 HcmV?d00001 diff --git a/win.h b/win.h index 6de960d..94679e4 100644 --- a/win.h +++ b/win.h @@ -25,7 +25,7 @@ enum win_mode { 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); diff --git a/x.c b/x.c index aa09997..59a12d6 100644 --- a/x.c +++ b/x.c @@ -19,6 +19,7 @@ char *argv0; #include "arg.h" #include "st.h" #include "win.h" +#include "hb.h" /* types used in config.h */ typedef struct { @@ -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, int); static void xdrawglyph(Glyph, int, int); static void xclear(int, int, int, int); static int xgeommasktogravity(int); @@ -757,7 +759,7 @@ xresize(int col, int row) xclear(0, 0, win.w, win.h); /* resize to new width */ - xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec)); + xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec) * 4); } ushort @@ -1062,6 +1064,9 @@ xunloadfont(Font *f) 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); @@ -1185,7 +1190,7 @@ xinit(int cols, int rows) XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); /* font spec buffer */ - xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec)); + xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec) * 4); /* Xft rendering context */ xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); @@ -1239,6 +1244,22 @@ xinit(int cols, int rows) xsel.xtarget = XA_STRING; } +void +xresetfontsettings(ushort mode, Font **font, int *frcflags) +{ + *font = &dc.font; + if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) { + *font = &dc.ibfont; + *frcflags = FRC_ITALICBOLD; + } else if (mode & ATTR_ITALIC) { + *font = &dc.ifont; + *frcflags = FRC_ITALIC; + } else if (mode & ATTR_BOLD) { + *font = &dc.bfont; + *frcflags = FRC_BOLD; + } +} + int xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) { @@ -1253,128 +1274,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; + HbTransformData shaped = { 0 }; + + /* Initial values. */ + mode = prevmode = glyphs[0].mode & ~ATTR_WRAP; + xresetfontsettings(mode, &font, &frcflags); for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) { - /* Fetch rune and mode for current glyph. */ - rune = glyphs[i].u; - mode = glyphs[i].mode; + mode = glyphs[i].mode & ~ATTR_WRAP; /* Skip dummy wide-character spacing. */ - if (mode == ATTR_WDUMMY) + if (mode & ATTR_WDUMMY && i < (len - 1)) continue; - /* Determine font for glyph if different from previous glyph. */ - if (prevmode != mode) { - prevmode = mode; - font = &dc.font; - frcflags = FRC_NORMAL; - runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f); - if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) { - font = &dc.ibfont; - frcflags = FRC_ITALICBOLD; - } else if (mode & ATTR_ITALIC) { - font = &dc.ifont; - frcflags = FRC_ITALIC; - } else if (mode & ATTR_BOLD) { - font = &dc.bfont; - frcflags = FRC_BOLD; - } - yp = winy + font->ascent; - } - - /* Lookup character index with default font. */ - glyphidx = XftCharIndex(xw.dpy, font->match, rune); - if (glyphidx) { - specs[numspecs].font = font->match; - specs[numspecs].glyph = glyphidx; - specs[numspecs].x = (short)xp; - specs[numspecs].y = (short)yp; - xp += runewidth; - 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); - /* Everything correct. */ - if (glyphidx && frc[f].flags == frcflags) - break; - /* We got a default font for a not found glyph. */ - if (!glyphidx && frc[f].flags == frcflags - && frc[f].unicodep == rune) { - break; - } - } - - /* 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; - - /* - * Nothing was found in the cache. Now use - * some dozen of Fontconfig calls to get the - * font for one single character. - * - * Xft and fontconfig are design failures. - */ - fcpattern = FcPatternDuplicate(font->pattern); - fccharset = FcCharSetCreate(); - - FcCharSetAddChar(fccharset, rune); - FcPatternAddCharSet(fcpattern, FC_CHARSET, - fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, 1); - - FcConfigSubstitute(0, fcpattern, - FcMatchPattern); - FcDefaultSubstitute(fcpattern); - - fontpattern = FcFontSetMatch(0, fcsets, 1, - fcpattern, &fcres); - - /* Allocate memory for the new cache entry. */ - if (frclen >= frccap) { - frccap += 16; - frc = xrealloc(frc, frccap * sizeof(Fontcache)); + if ( + prevmode != mode + || ATTRCMP(glyphs[start], glyphs[i]) + || selected(x + i, y) != selected(x + start, y) + || i == (len - 1) + ) { + /* Handle 1-character wide segments and end of line */ + length = i - start; + if (i == start) { + length = 1; + } else if (i == (len - 1)) { + length = (i - start + 1); } - frc[frclen].font = XftFontOpenPattern(xw.dpy, - fontpattern); - if (!frc[frclen].font) - die("XftFontOpenPattern failed seeking fallback font: %s\n", - strerror(errno)); - frc[frclen].flags = frcflags; - frc[frclen].unicodep = rune; + /* Shape the segment. */ + hbtransform(&shaped, font->match, glyphs, start, length); + runewidth = win.cw * ((glyphs[start].mode & ATTR_WIDE) ? 2.0f : 1.0f); + cluster_xp = xp; cluster_yp = yp; + for (int code_idx = 0; code_idx < shaped.count; code_idx++) { + int idx = shaped.glyphs[code_idx].cluster; - glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune); + if (glyphs[start + idx].mode & ATTR_WDUMMY) + continue; - f = frclen; - frclen++; + /* Advance the drawing cursor if we've moved to a new cluster */ + if (code_idx > 0 && idx != shaped.glyphs[code_idx - 1].cluster) { + xp += runewidth; + cluster_xp = xp; + cluster_yp = yp; + runewidth = win.cw * ((glyphs[start + idx].mode & ATTR_WIDE) ? 2.0f : 1.0f); + } - FcPatternDestroy(fcpattern); - FcCharSetDestroy(fccharset); + if (shaped.glyphs[code_idx].codepoint != 0) { + /* If symbol is found, put it into the specs. */ + specs[numspecs].font = font->match; + specs[numspecs].glyph = shaped.glyphs[code_idx].codepoint; + specs[numspecs].x = cluster_xp + (short)(shaped.positions[code_idx].x_offset / 64.); + specs[numspecs].y = cluster_yp - (short)(shaped.positions[code_idx].y_offset / 64.); + cluster_xp += shaped.positions[code_idx].x_advance / 64.; + cluster_yp += shaped.positions[code_idx].y_advance / 64.; + numspecs++; + } else { + /* If it's not found, try to fetch it through the font cache. */ + rune = glyphs[start + idx].u; + for (f = 0; f < frclen; f++) { + glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune); + /* Everything correct. */ + if (glyphidx && frc[f].flags == frcflags) + break; + /* We got a default font for a not found glyph. */ + if (!glyphidx && frc[f].flags == frcflags + && frc[f].unicodep == rune) { + break; + } + } + + /* 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; + + /* + * Nothing was found in the cache. Now use + * some dozen of Fontconfig calls to get the + * font for one single character. + * + * Xft and fontconfig are design failures. + */ + fcpattern = FcPatternDuplicate(font->pattern); + fccharset = FcCharSetCreate(); + + FcCharSetAddChar(fccharset, rune); + FcPatternAddCharSet(fcpattern, FC_CHARSET, + fccharset); + FcPatternAddBool(fcpattern, FC_SCALABLE, 1); + + FcConfigSubstitute(0, fcpattern, + FcMatchPattern); + FcDefaultSubstitute(fcpattern); + + fontpattern = FcFontSetMatch(0, fcsets, 1, + fcpattern, &fcres); + + /* Allocate memory for the new cache entry. */ + if (frclen >= frccap) { + frccap += 16; + frc = xrealloc(frc, frccap * sizeof(Fontcache)); + } + + frc[frclen].font = XftFontOpenPattern(xw.dpy, + fontpattern); + if (!frc[frclen].font) + die("XftFontOpenPattern failed seeking fallback font: %s\n", + strerror(errno)); + frc[frclen].flags = frcflags; + frc[frclen].unicodep = rune; + + glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune); + + f = frclen; + frclen++; + + FcPatternDestroy(fcpattern); + FcCharSetDestroy(fccharset); + } + + specs[numspecs].font = frc[f].font; + specs[numspecs].glyph = glyphidx; + specs[numspecs].x = (short)xp; + specs[numspecs].y = (short)yp; + numspecs++; + } + } + + /* Cleanup and get ready for next segment. */ + hbcleanup(&shaped); + start = i; + + /* Determine font for glyph if different from previous glyph. */ + if (prevmode != mode) { + prevmode = mode; + xresetfontsettings(mode, &font, &frcflags); + yp = winy + font->ascent; + } } - - specs[numspecs].font = frc[f].font; - specs[numspecs].glyph = glyphidx; - specs[numspecs].x = (short)xp; - specs[numspecs].y = (short)yp; - xp += runewidth; - numspecs++; } return numspecs; } 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; @@ -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 -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; @@ -1652,18 +1704,16 @@ xdrawline(Line line, int x1, int y1, int x2) 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++) { + for (x = x1; x < x2; 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; + if ((i > 0) && ATTRCMP(base, new)) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x - ox, ox, y1); + xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x - ox); i = 0; } if (i == 0) { @@ -1672,8 +1722,10 @@ xdrawline(Line line, int x1, int y1, int x2) } i++; } - if (i > 0) - xdrawglyphfontspecs(specs, base, i, ox, y1); + if (i > 0) { + numspecs = xmakeglyphfontspecs(specs, &line[ox], x2 - ox, ox, y1); + xdrawglyphfontspecs(specs, base, numspecs, ox, y1, x2 - ox); + } } void diff --git a/x.o b/x.o new file mode 100644 index 0000000000000000000000000000000000000000..428ec1bdc6c3969dc7e757233756e28c1d9b375b GIT binary patch literal 74760 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%0D2>?E+uT7DjF!cd< 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 literal 0 HcmV?d00001