microsoft / terminal

The new Windows Terminal and the original Windows console host, all in the same place!
MIT License
94.35k stars 8.17k forks source link

Allow for the configuration of font fallback #2664

Closed onceSS closed 3 months ago

onceSS commented 4 years ago

I am a Chinese developer, sometimes I have to use Chinese, or my Chinese version system will display some prompts in Chinese.

However, this terminal cannot specify multiple fonts in setting, for example: "editor.fontFamily": "DejaVu Sans Mono, Noto Sans CJK SC"(an example from vscode).

I hope this terminal can support multiple fonts setting in the future, thank you.

phuclv90 commented 4 years ago

I don't think you need to specify different fonts. Regardless of any locale you use, Chinese characters can always be displayed properly because there are font substitution, font linking and font fallback behind the scenes

mdtauk commented 4 years ago

Fonts in the JSON file could be an array, like with CSS, where if a font is not available, or maybe even per glyph - it goes to the next font listed, and falls back.

DHowett-MSFT commented 4 years ago

This will be part of #1790.

mariusstrom commented 4 years ago

Adding the word fontFace in here to make it easier to find this issue.

mariusstrom commented 4 years ago

It would be nice if VS Code and Terminal were more consistent on configuration parameters as well. This is a bigger problem, but this is a good example: vscode uses fontFamily, Terminal uses fontFace as the configuration parameter.

tsukumijima commented 3 years ago

671

It's been over a year since this issue was opened. Is there any progress in implementing font fallback? Even for Japanese users like me, this feature is absolutely necessary.

For example, suppose you want to use Cascadia Code in Windows Terminal. For VS Code, you can specify an alternative font to display characters that Cascadia Code doesn't have. This is not possible with current Windows Terminal, and characters that are not in Cascadia Code are always displayed in the system font (Yu Gothic UI in Japanese). However, the design of the Yu Gothic UI is thin and condensed (see image), there is too much space between the letters, and the weights do not match. At least I find it hard to see on Windows Terminal.

There are not many fonts for coding that contain Japanese characters. If font fallback is possible, you can easily combine alphabet fonts and Japanese fonts, expanding your font choices. We hope that this feature will be implemented soon. Thank you.

zadjii-msft commented 3 years ago

Nope. We'll make sure to update this thread when there is. In the meantime, might I recommend the Subscribe button? image That way you'll be notified of any updates to this thread, without needlessly pinging everyone on this thread ☺️

guodong2005 commented 3 years ago

Is there any solution to this problem yet ? My temporary solution is to merge 2 ttf files.

SoyBison commented 2 years ago

This is sort of a strange use-case for this, but I often access a remote machine that uses Material Design Icons in their zsh prompt. I'd like to be able to render those in WinTerm instead of getting boxes.

Also I work for microsoft and I think it'd be cool to have the windows logo on my prompt.

yzlnew commented 2 years ago

This is sort of a strange use-case for this, but I often access a remote machine that uses Material Design Icons in their zsh prompt. I'd like to be able to render those in WinTerm instead of getting boxes.

Also I work for microsoft and I think it'd be cool to have the windows logo on my prompt.

Go ahead and grab Nerd Fonts for yourself.

trallnag commented 2 years ago

@yzlnew, there are pretty big issues with using Nerd Fonts. Take a close look and compare the patched version of Cascadia with the original variable TTF one as an example. Letters are taller in the patched font.

This is another use case for allowing multiple fonts at the same time. This way I could use the original variable TTF Cascadia Code as the author indented it and at the same time have a random font patched with Nerd Font as a fallback for the fancy albeit nerdy and mostly useless glyphs from packs like Font Awesome.

@guodong2005, can you elaborate how you merge TTF fonts? Also are we talking about variable or static TTF?

aleigood commented 2 years ago

https://github.com/aleigood/Hybrid-Font

ruifengx commented 2 years ago

https://github.com/aleigood/Hybrid-Font

Please, stop recommending such "font mixing" approaches. It is a well-known ugly hack, with well-known drawbacks (most notably, glitched display possibly due to wrong kerning etc.; besides, what should have been a n+m problem now becomes n*m). A quick search on GitHub with "hybrid font" gives tens of results, half of which seems abandoned after the first several commits. I think we all agree this is a problem to be solved by either the operating system or the software, and definitely not the end user. And to go a bit off-topic, such "mixed fonts" usually (as is the case in the repository linked above) fail to meet the license requirements of the original fonts, e.g., by not providing a copyright notice (or a license file) in the repository.

aleigood commented 2 years ago

https://github.com/aleigood/Hybrid-Font

Please, stop recommending such "font mixing" approaches. It is a well-known ugly hack, with well-known drawbacks (most notably, glitched display possibly due to wrong kerning etc.; besides, what should have been a n+m problem now becomes n*m). A quick search on GitHub with "hybrid font" gives tens of results, half of which seems abandoned after the first several commits. I think we all agree this is a problem to be solved by either the operating system or the software, and definitely not the end user. And to go a bit off-topic, such "mixed fonts" usually (as is the case in the repository linked above) fail to meet the license requirements of the original fonts, e.g., by not providing a copyright notice (or a license file) in the repository.

I agree with you very much. I'm not an expert in making fonts. After requesting Sublime Text support fallback font and waiting for years without results, I finally couldn't bear to spend time making this font and only give it to those who need it. At the same time, I hope terminal can support it as soon as possible.

zadjii-msft commented 2 years ago

FWIW, I think this is set up to be pretty easy to solve at this point.

Both engines are using static lists of fonts for fallback. It shouldn't be too hard to:

  1. Make those lists a member variable of the engine itself
  2. Add support to Terminal.Settings.Model for parsing a list of strings as fallback font names
  3. Plumb those through to the TermControl in the IControlSettings interface
  4. Have the Control tell the render engine about the fallback list on initialization and on hot-reload

EDIT

It was brought to my attention that I was totally off base here. Turns out those hardcoded lists are whole-font based fallbacks, when what we really want is a per-glyph fallback. That we don't have largely hooked up, so this is a lot harder to do than I originally thought. We'd need to construct a whole array of fonts internal to the render engines, and then when a glyph is missing in a font, check the next font too. Frankly, I'm not even sure that second bit is possible.

I'm gonna take off Easy Starter, but if someone wants to get ambitious, please go for it!

aplysia56108 commented 1 year ago

@zadjii-msft I am really curious about this issue. I would like to contribute if I could, but I could not even point out which is the involved code file becouse the whole project is too large to read. If you please, could you tell me the involved file name and give me a hint to solve this issue?

zadjii-msft commented 1 year ago

In all honesty, the renderer code is probably not my area of expertise. The best I could likely do is point you at DxEngine and AtlasEngine, which are the two different text renderers in the Terminal.

@lhecker might be able to point you to a more specific method to look at.

My uneducated guess is that there's some way to determine if a particular glyph isn't in a font, before we actually render that glyph. Probably some DX API, but that is not something I'm sufficiently experienced with. If we determine that there's nothing for that glyph in the current font, then we should use some list of fonts as "fallback" fonts to look for that glyph.

I'd personally start working with a hardcoded list of fonts to fallback to. If that works, then we can pretty easily hook up some parsing logic to pass in a list of font names. But that's the easy part. Figuring out the per-glyph fallback is the hard part.

aplysia56108 commented 1 year ago

@zadjii-msft I really appreciate your fast reply. I will begin with reading the renderer code.

SetsuikiHyoryu commented 1 year ago

@zadjii-msft I really appreciate your fast reply. I will begin with reading the renderer code.

I really hope you to solve this problem!

microhobby commented 1 year ago

This is the only issue that limits me from using Windows Terminal over other solutions now.

zadjii-msft commented 1 year ago

Note

Walkthrough

To do per-glyph (codepoint?) fallback you'd use IDWriteFontFallbackBuilder::AddMapping and use the resulting custom IDWriteFontFallback instead of the current one we get through IDWriteFactory2::GetSystemFontFallback. In other words, we can easily add per-codepoint fallback in the future!

From discussion on #14959, specifically this thread: https://github.com/microsoft/terminal/pull/14959#discussion_r1169113851

xd003 commented 9 months ago

Why is something as important as this not implemented since 4 yrs, please this is something very barebones on linux if you ask me. I am using a Mono font for my Terminal but i needed to add a secondary font for better glyph/icons support in my prompt which is not possible at the moment

Jaswir commented 9 months ago

@xd003

Can you maybe make a gif of how this works in Linux the font fallback thing? https://www.screentogif.com/

Having things in Gifs describing the issue helps me. Maybe it'll help get this solved faster:

Jaswir commented 9 months ago

@mdtauk @oncess @tsukumijima

So let me get this straight the normal font is Japanese (tsu) / Chinese (once) and it should fall back to English font if not available?

tsukumijima commented 9 months ago

@Jaswir No, it's preferable to initially set a beautiful monospace font for English console and programming tasks, and then render glyphs that are not implemented in that font, like Japanese hiragana and kanji, using a secondary monospace font that supports Japanese. This is because, unlike fonts for English alphabets, Japanese fonts have a vast number of glyphs, limiting the options available, especially for free fonts. Furthermore, the design of the English numerals and letters in Japanese fonts may not necessarily be suited for console environments. In other words, there's a need to "use a well-designed English font for English letters and numerals, and choose a Japanese font that stylistically matches that English font for hiragana and kanji". While fonts that combine reputable open-source English and Japanese fonts like HackGen are available, creating such a composite font oneself is considerably laborious and generally not realistic.

Jaswir commented 9 months ago

@tsukumijima

Okay, so you have two fonts. One for the English alphabet and numbers and one for the Japanese characters? With current terminal you cannot have two fonts?

PS: I can play around a bit with vs code and the fonts and check the differences

tsukumijima commented 9 months ago

@Jaswir What does it mean? English fonts are fonts such as Source Code Pro, while Japanese fonts (including half-width alphanumeric characters) are Kosugi, etc. "Kosugi" is a monospaced Japanese font that also includes alphanumeric characters. However, the alphanumeric characters in "Source Code Pro" look better on the terminal. Therefore, in this example, I think "Source Code Pro" should be used preferentially, and "Kosugi" should be used for the characters not included in "Source Code Pro".

xd003 commented 9 months ago

@xd003

Can you maybe make a gif of how this works in Linux the font fallback thing? https://www.screentogif.com/

Having things in Gifs describing the issue helps me. Maybe it'll help get this solved faster:

Sure i can do that, but i am didn't quite understood if you need the part where this feature is coded in all the terminal emulators on linux or where exactly is the font fallback defined ? if you need the code part, sorry you will have to find it yourself on their respective github repos as i am not familiar with their codebase. i am linking github for the most preferred/famous linux terminals here - Konsole, Alacritty, Kitty, wezterm, foot, st. Do note that some of these terminals have windows OS support but their development is majorly focused on catering linux users except maybe just wezterm, it works pretty fine on windows i have heard. If you were asking where is the font fallback defined by the user, each of the github repo i have linked has their own wiki section, it is defined in the respective config files used by the terminals. For example, kitty's font section here clearly shows how to define font fallback. Good Luck

newor0599 commented 7 months ago

You can try using a nerd font, it contains alot of unicode including chinese character!

janderssonse commented 7 months ago

You can try using a nerd font, it contains alot of unicode including chinese character!

I guess that is precisley one of the many reasons that this issue exists. We would like to be able to have fallback font options, as to avoid using hacks like nerd fonts that are patch on fonts, sometimes with great results. sometimes with alignment issues.

xd003 commented 7 months ago

You can try using a nerd font, it contains alot of unicode including chinese character!

I guess that is precisley one of the many reasons this issue exists. We wan't to be able to have fallback font as to avoid using hacks like nerd fonts that are patching a fonts, sometimes with great results. sometimes with alignment issues.

Moreover there are very limited number of fonts available within the Nerd Fonts apart from the occasional alignment issues, its not really a viable option as people think it to be

abceleung commented 5 months ago

+1 to this issue.

Since my choice of font (Sarasa Gothic) does not have a prepatched version with nerd font, I used font-patcher in the official nerd font repo to patch nerd font in manually.

Docker example: docker run --rm -v ./SarasaFixedSlabHC-TTF-1.0.5/:/in:Z -v ./out:/out:Z -e "PN=10" nerdfonts/patcher --adjust-line-height --careful --complete (Lower PN if you have a weak PC, otherwise it might use up all your RAM and freeze your computer)

Another option I have considered is to use Wezterm, which is cross platform, has tab support and has nerd font as fallback font by default (so you don't have to patch nerd font by yourself).

zadjii-msft commented 4 months ago

For the subset of this thread that has been following along because they want the Powerline glyphs in their prompt but don't have a font with those glyphs: #16729 added some support for the Terminal drawing some of those glyphs itself, rather than relying on the font. That's available in Canary builds, if folks want to give that a try 😄

(understanding though, that this thread is mostly not about powerline glyphs, and there's still a lot of work to do here)