linebender / skribo

A Rust library for low-level text layout.
Apache License 2.0
327 stars 35 forks source link

Interaction with CSS font matching algorithm #22

Open SimonSapin opened 4 years ago

SimonSapin commented 4 years ago

https://drafts.csswg.org/css-fonts/#font-matching-algorithm specifies a fairly precise algorithm. font-kit has Source::select_best_match which claims part of it, but which takes no text or code point and only returns a single font.

Skribo’s input at the moment is a FontCollection which contains FontFamily’s which contains fonts. In CSS the input has an ordered list of family names (each a string, or one of the 5 generic categories). There is also special handing of @font-face fonts v.s. system fonts.

For the use case of implementing CSS, how much of this should be implemented in Skribo v.s. font-kit? How much should be left to the user?

CC @raphlinus, @pcwalton

raphlinus commented 4 years ago

This definitely needs more thought. Since we have things spread across multiple crates, there are serious questions about what logic should be where.

I unfortunately am too overloaded right now to dig into this, but I can imagine a few approaches. One is to build the entirety of the CSS font matching algorithm into skribo, relying on font-kit for raw data. Another is to figure out an API surface (possibly with extension points such as a match score callback) where skribo can provide enough capability to implement CSS. For example, I can definitely see skribo applying the cluster matching logic.

Basically, somebody needs to sit down and work out a design for this. Unfortunately it won't be me :/ But I'm open to guiding skribo to adapt to what's decided.

I did look at this in the context of DirectWrite; it's pretty clear that DWrite has lots of features to facilitate web work (such as async loading of fonts), but I don't think it quite does everything needed by CSS. In particular, I see "unicode-range" as a fly in the ointment, though I believe it's being de-emphasized for new work.

pcwalton commented 4 years ago

I'm not sure off the top of my head what the best place for this is. I think Source::select_best_match should be involved somehow, as I set it up to be useful for this purpose; it sounds like we should change font-kit's API to better match what CSS needs.