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

Font fallback handling #294

Open
elwinar opened this issue Apr 19, 2024 · 2 comments
Open

Font fallback handling #294

elwinar opened this issue Apr 19, 2024 · 2 comments

Comments

@elwinar
Copy link

elwinar commented Apr 19, 2024

Hey there.

First of all, thanks for your continued work with this library.

I've been doing a bit of text rendering, and I've come across the classic "this font doesn't handle X glyph". Most systems handle this using a fallback font that have more codepoints mapped, but I didn't see an option to do it with this lib. Have I missed the option ? If it is not implemented I'm willing to do it if you give me some pointers to help get started.

@tdewolff
Copy link
Owner

Hi Romain, thank you for the kind words. What you describe is indeed lacking from this library, but unfortunately involves quite a lot of work. First of all, we'd need to be able to define a list of fallback fonts. Second, the font shaping should pick the first font that contains the given glyph. As far as I can see, there needs to be some refactoring to separate instances where font face is bound to text spans and not to glyphs. I'll have to take a deeper look to give you some useful pointer to be honest...

@tdewolff
Copy link
Owner

tdewolff commented Apr 20, 2024

I think we should add type FontFamilies []*FontFamily as a list of fallback font families, as well as type Fonts []*Font. Both should have Face method (like Font and FontFamily) that creates a usable font face. FontFace should keep a list of *Font instead of a single one.

We should probably write a general function Shape(fonts []*Font, text string, ppem uint16, direction text.Direction, script text.Script, language string) []text.Glyph which uses fonts as a list of fonts with the primary first and fallback fonts the rest in order. This would be used in RichText.ToText and NewTextLine. Each glyph uses the first font that provides it. This should split TextSpan at places where the used font changes.

It would be nice if the *SystemFont functions could accept a comma-separated list of system fonts to load, but not sure how to add something similar for loading from font files or from memory.

That's probably it, what do you think?

NB: the shaper uses HarfBuzz, which makes it a bit harder since it's an external dependency. Additionally, it requires to reparse the SFNT fonts which is really inefficient. We can either create our own HarfBuzz port (a lot of duplicate work) or use the Font implementation from typesetting everywhere. A couple of features (including this one?) might not be compatible with that library though (crucially, font subsetting for PDFs).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants