wezterm icon indicating copy to clipboard operation
wezterm copied to clipboard

Font looks thin and spaced out compared to other terminals

Open Rojetto opened this issue 2 years ago • 21 comments

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

macOS

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

No response

WezTerm version

wezterm version: 20230524-062011-1cd340bb aarch64-apple-darwin

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

Not sure if this actually is a bug, but font rendering by default looks very different from other terminals I tried. Specifically, fonts look thinner and are more spaced out horizontally on WezTerm compared to Terminal.app, Alacritty and Kitty.

On default settings, here is what WezTerm looks like with Menlo 14pt:

image

And Alacritty for reference, Kitty looks the same:

image

I understand that font rendering is subjective, choices for anti-aliasing methods and such can be up to the user. I tried these tweaks and got pretty close to other terminals:

  • To get thicker looking strokes, switch to freetype_render_target = "HorizontalLcd"
  • To squeeze things horizontally, set cell_width = 0.9

The stroke thickness I understand might just be a different default choice, but the cell width feels like a bug to me. As far as I understand, it should choose the width of the monospace glyphs as defined in the font, which should be consistent across terminals, correct?

Here is the result after config tweaks in WezTerm:

image

Issue seems a bit similar to https://github.com/wez/wezterm/issues/689, but there wasn't really any result from that.

To Reproduce

No response

Configuration

config.font = wezterm.font('Menlo')
config.font_size = 14
config.freetype_load_target = "Light"
config.freetype_render_target = "HorizontalLcd"
config.cell_width = 0.9

Expected Behavior

No response

Logs

No response

Anything else?

No response

Rojetto avatar May 26 '23 06:05 Rojetto

it should choose the width of the monospace glyphs as defined in the font,

It may surprise you to learn that fonts only define their height, and that the width is a poorly defined concept! Every terminal uses slightly different heuristics to compute the cell width for a given font size (height).

I don't think that there is much or perhaps anything for me do here; font presentation is subjective. Some users think wezterm is bolder than other terminals, some perceive it as less bold.

At the end of the day, wezterm is just calling out to freetype to rasterize, and using either OpenGL or wgpu via your graphics drivers to put content on the screen. All possible controls are exposed to you to fine tune. The defaults are the defaults for the various libraries.

wez avatar May 29 '23 20:05 wez

Thanks for the explanation. I did try to look into it a bit further but quickly reached the limits of how much I actually understand about font details. Here's a small comparison I made anyway:

font_rendering_comparison

I cropped out the same string from the screenshots above and aligned them (without scaling).

Boldness: At least for this example, to me it's obvious that WezTerm is objectively thinner looking. You can count the 2 vs 3 pixels on the horizontal strokes of e, z and t. I do agree that this is a subjective choice though, so thank you for exposing the renderer config options.

Cell width: Yes, cell width might be heuristic based, but the horizontal spacing between letters when setting text normally is not. Using FontForge I looked up the spacing metrics for Menlo specifically, and since it's a monospaced font, every glyph has the same width (horizontal advance) of 1233. Comparing the screenshot from the metrics window in FontForge, that seems to be the same "width" Alacritty and other terminals use as well. Personally, it feels like that's what WezTerm should do too (and if it does already, seems like something small is going wrong)?

Anyway, maybe nothing needs to be fixed and luckily everything can be tweaked with the config. Just wanted to document in case this is not the intended behavior or other people have the same observation.

Rojetto avatar May 30 '23 16:05 Rojetto

Note that you can use wezterm ls-fonts --text "something" to have wezterm explain how it would render text. There's also a --rasterize-ascii flag to see that presented in the terminal.

wez avatar May 30 '23 16:05 wez

Thanks, using that command I could see that WezTerm attempts to use an advance width of 8. That made me curious how DPI comes into play (previous screenshots were on Retina display). I made another comparison, manually setting the DPI in the config to 72 and 144 (dragging between Retina and 1080p display yields the same result).

dpi_comparison_labeled

Seems like the width issue is DPI related. On "standard" DPI of 72 everything looks normal, exactly the same as other terminals. When scaling up to 144 by a factor of 2 however, there is some slight deformation. The height of the t becomes 19 px (should be 20 px), and the advance width is 17 px (should be 16 px). I'm pretty sure this is not supposed to happen, especially since the error is different in both dimensions, skewing the perceived "aspect ratio" of the font.

Rojetto avatar May 31 '23 04:05 Rojetto

I haven't had a chance to go deep on this yet, but wanted to note that wezterm uses fractional pixel values, rather than rounding them to integer pixels. What I suspect is the heart of the issue here is the font hinting logic in freetype not knowing about this. Hinting tries to line things up on pixel boundaries.

You could try turning it off to see if things look better:

config.freetype_load_flags = 'NO_HINTING'

wez avatar Jul 10 '23 20:07 wez

I think this has to do with sRGB and blending in linear space vs blending in gamma space. Im tried out kitty version 0.25 which is before https://github.com/kovidgoyal/kitty/pull/5423, and the font looks like wezterm's.

Font - SF Mono, Size - 15 kitty 0.25: image kitty now: image wezterm: image xcode: image

As you can see, kitty currently and xcode's letters are wider. I think it's related to https://github.com/wez/wezterm/issues/3616. However, I don't think there's a definite right way to blend colors. It's really up to preference, but I prefer how kitty does it, as it's closer to how macOS renders which I'm used to.

Also, I want to add that using "WebGpu" instead of "OpenGL" makes the colors sRGB compliant (using Digital Color Meter), but doesn't fix the font thinning.

williamhCode avatar Jul 18 '23 08:07 williamhCode

Zoomed in: image

williamhCode avatar Jul 18 '23 08:07 williamhCode

You could try turning it off to see if things look better:

config.freetype_load_flags = 'NO_HINTING'

Thank you so much for this tip. This fixed a vertical stretching issue that I've been experiencing with IBM Plex Mono Regular Size 16 on Mac OS (13.0.1 (22A400)) with (wezterm 20230712-072601-f4abf8fd).

Particularly the '5' was noticeably distorted (image below).

Now it looks crisp and lovely. Many compliments on WezTerm. Outstanding.

Screenshot 2023-11-03 at 01 10 57

zambetti avatar Nov 03 '23 00:11 zambetti

Thanks for that NO_HINTING hint.

This was driving me nuts for a while after I switched fonts in my terminal and noticed that text seemed to shift around randomly from time to time.

I just set this and so far, so good...

nerdo avatar Dec 12 '23 19:12 nerdo

Actually, on closer inspection, I still have similar issues.

After doing some more digging though, I switched set my front_end setting to OpenGL and that seems to have resolved it.

It's such a subtle issue that it's hard to say if that did it for sure, but if it is it might be an issue with how the front end is rendering things differently using the default WebGPU and/or one of the specific backends.

I tried to enable the debug overlay so I could see what backends I have available on my system and see if switching resolves it, but I only have one on my system:

> wezterm.gui.enumerate_gpus()
[
    {
        "backend": "Metal",
        "device": 0,
        "device_type": "IntegratedGpu",
        "name": "Apple M1 Max",
        "vendor": 0,
    },
]

At least I have a decent workaround (assuming this pans out).

I'm not sure what I'd be missing out on (performance?), if anything, by using OpenGL...

nerdo avatar Dec 15 '23 02:12 nerdo

@wez

Just switched to WezTerm and it's pretty great. Not sure if this is relevant but my Chinese characters looks thinner while other characters looks fine:

image

Configs below:

config.color_scheme = 'Catppuccin Mocha'

config.font = wezterm.font_with_fallback {
    'DejaVuSansM Nerd Font Mono', 'SF Mono'
}

config.font_size = 12

Compares to Alacritty using the same font and font size:

image

Really need this to be fixed. Thanks!

RoyRao2333 avatar Jan 26 '24 02:01 RoyRao2333

@RoyRao2333 if you haven't set your front_end to OpenGL, you should try that first. You may also want to explicitly add your preferred Chinese font to your font_with_fallback list in case what you are seeing is simply a different automatic choice of font for that text.

wez avatar Jan 26 '24 13:01 wez

@wez

if you haven't set your front_end to OpenGL, you should try that first.

Yes, I'm using nightly build. But already tried that with no luck.

explicitly add your preferred Chinese font

This solved the issue! But I wonder why DejaVuSansM Nerd Font Mono behaves normal in Terminal.app and Alactritty, but weird in WezTerm.

Anyway, I added a Chinese font to the fallback list and it now works like a charm. Thanks a lot!

RoyRao2333 avatar Jan 26 '24 16:01 RoyRao2333

I see that this thread is still alive...

I know I mentioned that setting the font renderer to opengl explicitly seemed to help, but it was a red herring.

I still have odd font rendering issues.

Here's a screenshot from a neovim editing session to illustrate:

Screenshot 2024-01-27 at 6 57 56 AM

Notice the ->'s on the lines where $factory->define is.

The first line renders correctly. I have a freely available font Caskaydia Cove Nerd Font Mono which has a ligature for -> to turn it into a connected arrow.

However, if you look at the other two instances of the same exact text, they are rendered incorrrectly. It appears as if the ligature is there, but it's not taking up the same space.

There are other font rendering errors here as well. Notice all of the fat arrows => are also ligatures, but they two characters making it up don't line up properly so there is a stair step effect.

Sometimes things like this happen. Sometimes _ underscores disappear. It's really quite random. I've tried several of these workarounds in the past, but none of them seem to solve it.

Here's my current wezterm.lua configuration for reference (https://github.com/nerdo/personal-settings/blob/8798c5a3d3238ca1770b33731c5cbb3f86d0e8ea/wezterm/wezterm.lua)

BTW, I really love wezterm but have been frustrated by the font rendering glitches. Regardless, it's still the best terminal emulator I've used, so I keep coming back to it - I just hope this odd font rendering behavior can be fixed, so I'm happy to provide more information to that end.

I'm currently on wezterm 20230712-072601-f4abf8fd btw.

nerdo avatar Jan 27 '24 12:01 nerdo

@nerdo please open a separate issue of your own, rather than hijacking this one

wez avatar Jan 27 '24 14:01 wez

Screenshot 2024-03-12 at 21 43 13

I have the same issue. iTerm2 on the left, Wezterm on the right. I installed same color schemes (tokyonight-storm for dark, and tokyonight-day for light). The same font settings both in wezterm and iTerm2.

And stil I get less sharp, less visible ~~and some things are using italic~~ on wezterm side.

I tried both with webgpu and opengl, with some options mentioned in this thread etc.

UPDATE: turns out it was tmux config that was leaking something causing difference with italics in wez/iterm2. So only sharpness issue remains but I will dig deeper

nazriel avatar Mar 12 '24 20:03 nazriel

@nazriel there really isn't anything Wezterm can do to fix this, it's just using a different technique to blend colors which makes characters appear thinner. I suggest using weight = "Medium" for ur font and it should look similar to iTerm2 (that's what i do actually).

Some things using italic is correct, I'm guessing iTerm2 isn't rendering italics properly. You should look into config options for your neovim colorscheme if you want to turn italics off.

williamhCode avatar Mar 12 '24 21:03 williamhCode

Would be nice to have the same customization option as Kitty's https://sw.kovidgoyal.net/kitty/conf/#opt-kitty.text_composition_strategy which could potentially resolve the issue for everyone.

mcchrish avatar Aug 13 '24 06:08 mcchrish

I was frustrated with the same issue, and thanks for all the hints. The following config has significantly improved the font rendering for me:

config.font_size = 16.0
config.front_end = 'OpenGL'
config.freetype_load_target = 'Light'
config.freetype_render_target = 'HorizontalLcd'
config.cell_width = 0.9

rohshall avatar Aug 16 '24 16:08 rohshall

Hi all, and thanks very much for Wezterm @wez! I have read this and linked discussions and so I understand that everything has been done to expose configuration options given the existing implementation, and that it's not at all obvious how to make progress here. I hope it's OK if I nevertheless add another screenshot to the discussion in the hope that it might help someone improve font appearance on MacOS. I use a white terminal background, and it looks like perhaps the problems are especially apparent there.

This is Monaco 14 Regular in Wezterm (left) and Alacritty (right).

wezterm-vs-alacritty-monaco-14-regular

I'd really love to recreate the same "solidness" / "boldness" that I see in Alacritty (and iTerm2), but the only way I've found to do that is to literally set the font weight to Bold in WezTerm, which of course isn't satisfying (too extreme, loses sharpness, loses ability to have distinct bold and non-bold text). cell_width helps a little bit (I like 0.95 but 0.90 distorts things too much for me) but doesn't solve the problem, and I didn't find that any of the other tweaks mentioned above changed apprearance (M2 Macbook, using builtin 16-inch (3456 × 2234) laptop screen).

dandavison avatar Aug 21 '24 11:08 dandavison

When using a font that mixes single-width and double-width characters (like GNU Unifont), the defaults select the widest character as the cell_width.

image

This can be fixed with an override of cell_width = 0.5

image

but then you'll need to comment it back out for fonts without double-width characters. As to whether or not this should be handled manually or automatically, I will leave to the philosophers.

BourgeoisBear avatar Aug 23 '24 16:08 BourgeoisBear

I suggest using weight = "Medium" for ur font and it should look similar to iTerm2 (that's what i do actually).

This fixed the issue for me. Setting weight = "Bold" made the rendering identical between Iterm2, kitty and wezterm.

tanzeeb avatar Sep 11 '24 02:09 tanzeeb