wez / wezterm

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

Inconsistent positioning of combining diacritical marks #3976

Open expipiplus1 opened 1 year ago

expipiplus1 commented 1 year ago

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

Linux X11

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

gnome-shell

WezTerm version

20230712-072601-f4abf8fd

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

Combining diacritical marks, for instance "Combining Circumflex Accent" U+0302 can be rendered at an incorrect height depending on the surrounding context.

To Reproduce

Open a new wezterm session, there is a persistent state involved here, so running the first step again can produce incorrect results.

  1. Run echo 'α\u0302 β\u0302'
  2. Observe that the hats are in the correct place
  3. Run echo 'β\u0302 α\u0302'
  4. Observe that the hats are in the incorrect position on both characters
  5. Run echo 'B\u0302 a\u0302 B\u0302'
  6. Observe that this doesn't happen with Roman characters

image

Configuration

This also happens with no config, however in that case the hat is always incorrect on beta, so there's clearly some interaction with the specific font here.

image

local wezterm = require 'wezterm';

return {
  font = wezterm.font_with_fallback{
    { family = "Iosevka Term"
    , weight = "Regular"
    , harfbuzz_features = {"calt=0", "dlig=0", "cv57=2", "cv36=1"} -- curly lambda λ <3
    }
    , "DejaVu Sans Mono Nerd Font Mono"
    , "DejaVu Sans Mono"
  };

  font_size = 8.5;
}

Expected Behavior

Combining characters are always rendered in the "correct" position with respect to their combinee glyph.

Logs

nothing relevant

Anything else?

No response

wez commented 1 year ago

wezterm really just asks the harfbuzz library how to shape the text, and it acts based on the font you selected.

You can use this to show the glyphs that the shaper decided to use, and which font(s) they were located in:

$ wezterm ls-fonts --text "$(echo 'α\u0302 β\u0302')"
LeftToRight
 0                   x_adv=8  cells=1  glyph=alpha,629  wezterm.font("JetBrains Mono", {weight="Regular", stretch="Normal", style="Normal"})
                                      /usr/share/fonts/jetbrains-mono-fonts/JetBrainsMono-Regular.otf, FontConfig
 0 α̂   \u{3b1}\u{302} x_adv=0  cells=0  glyph=uni0302,1646 wezterm.font("JetBrains Mono", {weight="Regular", stretch="Normal", style="Normal"})
                                      /usr/share/fonts/jetbrains-mono-fonts/JetBrainsMono-Regular.otf, FontConfig
 4      \u{20}       x_adv=8.328125 cells=1  glyph=space,2    wezterm.font("Operator Mono SSm Lig", {weight="DemiLight", stretch="Normal", style="Normal"})
                                      /home/wez/.fonts/OperatorMonoSSmLig-Medium.otf, FontDirs
LeftToRight
 0                   x_adv=8  cells=1  glyph=beta,630  wezterm.font("JetBrains Mono", {weight="Regular", stretch="Normal", style="Normal"})
                                      /usr/share/fonts/jetbrains-mono-fonts/JetBrainsMono-Regular.otf, FontConfig
 0 β̂   \u{3b2}\u{302} x_adv=0  cells=0  glyph=uni0302,1646 wezterm.font("JetBrains Mono", {weight="Regular", stretch="Normal", style="Normal"})
                                      /usr/share/fonts/jetbrains-mono-fonts/JetBrainsMono-Regular.otf, FontConfig

could you run that for each of the cases with the fonts you've selected and share the output?

You can then verify what harfbuzz itself would produce by using hb-view with the font it listed. So in my case from above:

$ hb-view /usr/share/fonts/jetbrains-mono-fonts/JetBrainsMono-Regular.otf "$(echo 'α\u0302 β\u0302')"

image

this will render an image directly into wezterm in more recent harfbuzz versions; in earlier versions you may need to output it to a file explicitly and then use wezterm imgcat to review it.

expipiplus1 commented 1 year ago

Thank you for the helpful reply!

Here's the output, it doesn't looks like there's anything overly suspicious such as different fonts or stylings

$ wezterm ls-fonts --text "$(echo 'α\u0302 β\u0302')"
LeftToRight
 0                   x_adv=6  cells=1  glyph=u03B1,861  wezterm.font("Iosevka Term", {weight="Regular", stretch="Normal", style="Normal"})
                                      /nix/store/j4ffnr15dbb09di4mx7vzr6b855my39f-sgr-iosevka-term-bin-22.1.2/share/fonts/truetype/sgr-iosevka-term-regular.ttc, FontConfig
 0 α̂   \u{3b1}\u{302} x_adv=0  cells=0  glyph=u0302.join-l,693  wezterm.font("Iosevka Term", {weight="Regular", stretch="Normal", style="Normal"})
                                      /nix/store/j4ffnr15dbb09di4mx7vzr6b855my39f-sgr-iosevka-term-bin-22.1.2/share/fonts/truetype/sgr-iosevka-term-regular.ttc, FontConfig
 4      \u{20}       x_adv=6  cells=1  glyph=space,3    wezterm.font("Iosevka Term", {weight="Regular", stretch="Normal", style="Normal"})
                                      /nix/store/j4ffnr15dbb09di4mx7vzr6b855my39f-sgr-iosevka-term-bin-22.1.2/share/fonts/truetype/sgr-iosevka-term-regular.ttc, FontConfig
LeftToRight
 0                   x_adv=6  cells=1  glyph=u03B2,862  wezterm.font("Iosevka Term", {weight="Regular", stretch="Normal", style="Normal"})
                                      /nix/store/j4ffnr15dbb09di4mx7vzr6b855my39f-sgr-iosevka-term-bin-22.1.2/share/fonts/truetype/sgr-iosevka-term-regular.ttc, FontConfig
 0 β̂   \u{3b2}\u{302} x_adv=0  cells=0  glyph=u0302.join-l,693  wezterm.font("Iosevka Term", {weight="Regular", stretch="Normal", style="Normal"})
                                      /nix/store/j4ffnr15dbb09di4mx7vzr6b855my39f-sgr-iosevka-term-bin-22.1.2/share/fonts/truetype/sgr-iosevka-term-regular.ttc, FontConfig

The full output, demonstrating the incorrect rending at the top and harfbuzz's correct rendering below.

image