kas-gui / kas-text

Rich text processing
Apache License 2.0
58 stars 2 forks source link

Font fallbacks: lists and per-char selection #47

Closed dhardy closed 3 years ago

dhardy commented 3 years ago

This (roughly) implements font fallbacks.

But: on my system it resolves "Noto Sans" as the default font, however does not resolve international variants: my system includes "Noto Sans CJK HK", "Noto Sans CJK JP", "Noto Sans Sinhala", ...

@RazrFalcon may I ask, is there some way of resolving these variants from the base family name, "Noto Sans"? I cannot simply use starts_with since that would include "Noto Sans Black", "Noto Sans Mono" etc, thus I don't see a way from the information available in fontdb (attached). Or is it expected that the font-config list all variants of "Noto Sans"?

CSS font style matching step 4 must happen once per font (e.g. "Noto Sans CJK HK"), so e.g. "Noto Sans Black" must be excluded.

Also @RazrFalcon do you see some of this logic moving to fontdb? find_best_match is copied from there and something like FontSelector::select could be added as something like Database::query_multiple. The set_serif_family etc. methods are not useful here since "serif" may resolve to multiple fonts.

RazrFalcon commented 3 years ago

Yes, multi-language font queries are not supported. Mainly because I have no idea how exactly it should be done. CSS spec doesn't mentions this, afaik.

Also, you cannot detect a font language by Family Name. It's stored separately, if stored at all (can't remember where). fontconfig support this for sure.

The set_serif_family etc. methods are not useful here since "serif" may resolve to multiple fonts.

Is it? I think at least font-config doesn't support this. Not sure about Windows and macOS.

PS: currently, fontdb is a bare-minimum pure-rust font-kit alternative. It's good enough for resvg, but it general very primitive. I'm open for new additions, but I would prefer if they follow some spec or something. Or at least replicate the common behaviour of typical system libraries. So we could explain why fontdb works in a way it works.

dhardy commented 3 years ago

My guess is that eventually we (the Rust ecosystem) will need some way of reading fontconfig files and similar for other platforms. /etc/fonts/conf.d contains a lot of aliases, both generic ones (like to serif) and specific ones (like Calibri == Carlito), plus more specific matching rules (and some rendering rules). Parsing this shouldn't be too hard after figuring out the rules. But for now I'll just hard-code font families.

I'm also not quite sure if font matching should use the font lang tag. It looks like CSS doesn't.

dhardy commented 3 years ago

Closes #40: rustybuzz support is merged here.

KAS can now do font fallback and shaping without extra C library dependencies:

fallback-and-shaping

RazrFalcon commented 3 years ago

My guess is that eventually we (the Rust ecosystem) will need some way of reading fontconfig files and similar for other platforms.

I've tried to do this, but it's basically undocumented. It would take a lot of time to implement. There is https://github.com/fschutt/rust-fontconfig that tries to do this, but it's extremely primitive.