wez / wezterm

A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust
https://wezfurlong.org/wezterm/
Other
17.36k stars 780 forks source link

GPOS-modified glyphs May be being cached inappropriately #6261

Open sh1boot opened 1 week ago

sh1boot commented 1 week ago

What Operating System(s) are you seeing this problem on?

Linux X11

Which Wayland compositor or X11 Window manager(s) are you using?

i3 4.23

WezTerm version

20241007_103614_ed430415

Did you try the latest nightly build to see if the issue is better (or worse!) than your current version?

Yes, and I updated the version box above to show the version of the nightly that I tried

Describe the bug

I'm experimenting with patching fonts to insert spaces for thousand separators by moving the glyphs slightly using GPOS font rules. What I'm observing is that when I use such a patched font, sometimes it will modify a glyph with GPOS but all instances of that glyph get modified regardless of where they are on screen.

I think this is the same issue as #1931, and I assume it's because the GPOS modification gets into the cache but without being a unique cache entry or having the position modification noted externally in the cache.

To Reproduce

Pick your favorite font and patch with this tool: https://github.com/sh1boot/digitgrouper/ Something like: python3 digitgrouper.py --monospace comicsansmono.ttf (producing output.ttf).

Configure it with harfbuzz_features={'+dgsp'}

Before enabling it, ensure that a string like 0xabcdef0123456789 is very near to the top of the screen so that those glyphs are rendered and cached before any other instances of those glyphs are rendered.

Configuration

freetype_interpreter_version=40
freetype_load_flags='DEFAULT'
freetype_load_target='Normal'
freetype_render_target='HorizontalLcd'
font_shaper='Harfbuzz'
font = { [...] harfbuzz_features={'+dgsp'} }

Expected Behavior

Decimal numbers of more than four digits would have small gaps every third digit, grouping them into powers of one thousand. Hexadecimal numbers string with 0x would be similarly grouped into four digits.

Logs

No response

Anything else?

I have an alternate version which creates a ton of extra glyphs duplicating all the digits but at different positions. That works, but I wanted to try GPOS instead of GSUB to see if it made things more efficient.

sh1boot commented 4 days ago

Here's an easier repro. Put the following in mangle.fea:

lookup mangle_stuff {
  lookupflag 0;
    pos \x [\zero \one \two \three \four \five \six \seven \eight \nine]'<-300 0 0 0>;
    pos \X [\zero \one \two \three \four \five \six \seven \eight \nine]'<300 0 0 0>;
    pos [\i \j \k] [\a - \z \A - \Z ]'<0 -300 0 0>;
    pos [\I \J \K] [\a - \z \A - \Z ]'<0 300 0 0>;
} mangle_stuff;

feature calt {
  lookup mangle_stuff;
} calt;

Then run the following and direct wezterm to use the output:

fonttools feaLib -o myFont.ttf mangle.fea your_font_here.ttf

Some letters should end up at weird positions. For example, my letter g dropped down low. This because the I was editing my wezterm config and one of the first things the cache saw was config, where g followed i, and the above font feature rule says that all letters following a lowercase i should be shifted down.

But in wezterm all instances of that letter got shifted down. Conversely, my c is not shifted down when it should be because the first occurence was not following an i.