wez / wezterm

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

Font looks thin and spaced out compared to other terminals #3774

Open Rojetto opened 1 year ago

Rojetto commented 1 year ago

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:

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

wez commented 1 year ago

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.

Rojetto commented 1 year ago

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.

wez commented 1 year ago

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.

Rojetto commented 1 year ago

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.

wez commented 12 months ago

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'
williamhCode commented 11 months ago

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 commented 11 months ago

Zoomed in:

image
zambetti commented 8 months ago

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

nerdo commented 6 months ago

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 commented 6 months ago

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...

RoyRao2333 commented 5 months ago

@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!

wez commented 5 months ago

@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.

RoyRao2333 commented 5 months ago

@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!

nerdo commented 5 months ago

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.

wez commented 5 months ago

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

nazriel commented 3 months ago

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

williamhCode commented 3 months ago

@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.