Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better support for web fonts #1164

Closed
vincentwoo opened this issue Dec 22, 2017 · 10 comments
Closed

Better support for web fonts #1164

vincentwoo opened this issue Dec 22, 2017 · 10 comments
Assignees
Labels
help wanted type/enhancement Features or improvements to existing features

Comments

@vincentwoo
Copy link
Contributor

Playing with v3, it seems that on some browser hard refereshes, xterm doesn't seem to pick up the custom fontFamily I set and renders oddly:

screenshot 2017-12-21 18 04 02

On a normal refresh after:

screenshot 2017-12-21 18 04 35

Is there a recommended flow for loading xterm with webfonts?

@mofux
Copy link
Contributor

mofux commented Dec 22, 2017

@vincentwoo Good point. Since we use the canvas for rendering, there is no automatic swap-out of fonts anymore. In general you have to make sure that the font is available when your terminal creation code runs. To do that, make sure the terminal creation code is loaded in head or body after the stylesheet that loads the font (see https://stackoverflow.com/questions/9899372/pure-javascript-equivalent-of-jquerys-ready-how-to-call-a-function-when-t). You could also force xterm.js into refreshing its char atlas by setting the fontFamily on the theme once you know that the font is available:

term.setOption('theme', { fontFamily: 'YourFontFamily' })

@Tyriar Do you think we should handle this case automatically (refreshing the char atlas once the window finished loading)?

@mofux mofux added area/renderer type/enhancement Features or improvements to existing features labels Dec 22, 2017
@vincentwoo
Copy link
Contributor Author

It's tricky because even if your scripts occur at the end of <body> you're not guaranteed that all webfonts have loaded - the browser delays rendering until a character of a given font family is deemed needed. Ideally, xterm would use fallback fonts and refresh as necessary.

@Tyriar
Copy link
Member

Tyriar commented Dec 26, 2017

@vincentwoo I think you'll want to call open after the web fonts have finished loading, that would prevent flickering of a different font initially.

Anyone know if there an easy way to tell whether a font has been loaded/changed?

@vincentwoo
Copy link
Contributor Author

It might be useful to have xterm incorporate one of the polyfills mentioned here: https://stackoverflow.com/questions/5680013/how-to-be-notified-once-a-web-font-has-loaded. Right now, anyone who wants to use a webfont with xterm will have to go through something similar, so it might have good utility for users as an addon. I can look into it if you don't have the time.

@Tyriar
Copy link
Member

Tyriar commented Jan 29, 2018

I'd prefer this to be done at a higher level than xterm.js, https://github.com/bramstein/fontfaceobserver is a lot of code to ship to everyone. As for making it an addon, I think we should eventually move away from the current addon model once we have a more complete API as currently the maintenance burden for all addons is put on the xterm.js team.

I recommend using fontfaceobserver on your side and only calling Terminal.open after they're loaded.

@vincentwoo
Copy link
Contributor Author

Hm, even using fontfaceobserver to delay terminal creation, I sometimes see the wrong font loaded. Additionally, in Firefox, it appears to also cause some foreground text to render as black (on black). Has anyone spent a lot of time getting xterm 3.x working in production with webfonts?

@vincentwoo
Copy link
Contributor Author

Here's a more detailed use case that I think warrants examination by the team. Let's take a pretty plausible situation: You're a user of xterm.js who wants to use a custom webfont for just terminal display. xterm is the only consumer of your special monospace webfont on your website. You might think, plausibly, that importing the proper font family, waiting an acceptable amount of time for the load, and then instantiating xterm would be enough.

This works well enough in Chrome. Firefox, instead of merely lowering the priority of fonts that are unused on the page at load time actuals skips downloading those fonts altogether. In this case, you get a black screen. See this codepen for an example: https://codepen.io/anon/pen/wmPJrQ.

In that pen, you'll see a <span> that you can uncomment which will force the browser to actually load the font. In xterm 2.x this was less of an issue because xterm would render to the DOM, and the presence of those DOM nodes with the correct fontFamily attribute would cause the browser to load the appropriate font. In the new world, everything needs to be correctly loaded before xterm can render. That includes, for instance, the bold variant of the font and any other separate variations.

I think there is a lot of virtue in xterm rendering a hidden dummy span which triggers the loading of any font variants it may need for the chosen fontFamily it has been configured with, and then deferring (or refreshing) when those fonts have been loaded.

@Tyriar
Copy link
Member

Tyriar commented Mar 27, 2018

I can see value in an addon that does this and then forces a repaint and refresh of the texture atlas after things are finished. Open to PRs.

@Tyriar Tyriar reopened this Mar 27, 2018
@Tyriar Tyriar changed the title Webfont rendering on v3? Better support for web fonts Mar 27, 2018
@vincentwoo
Copy link
Contributor Author

vincentwoo commented Apr 3, 2018

@Tyriar these internals are a bit hard for me. Is there a golden path way to force a refresh of the texture atlas? It seems that _refreshCharAtlas calls acquireCharAtlas which appears to cache entries.

@Tyriar Tyriar added this to the 3.4.0 milestone Apr 4, 2018
@Tyriar Tyriar added type/feature type/enhancement Features or improvements to existing features and removed type/enhancement Features or improvements to existing features type/feature labels Apr 4, 2018
@Tyriar
Copy link
Member

Tyriar commented May 17, 2018

For anyone wanting this support @vincentwoo published an addon to make working with web fonts easy which you can grab at https://www.npmjs.com/package/xterm-webfont

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted type/enhancement Features or improvements to existing features
Projects
None yet
Development

No branches or pull requests

3 participants