linebender / skribo

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

Unique font id #8

Closed raphlinus closed 5 years ago

raphlinus commented 5 years ago

The font loader should have an "Id" type that efficiently impl's PartialEq and Hash, that is guaranteed (with reasonably high confidence) to be equal when the fonts are equal. Such an Id is necessary for caching of any resource associated with a font (rendered glyphs, HarfBuzz font and face objects, table data, coverage bitmaps). Currently font-kit tends to use PostScript name for this purpose, but it's easy to see how this might fail uniqueness (for example, when a web font stack contains a different version of a font already present in the system). It should also be cheap to compute, because we will need it for every typeface that comes back from a fallback query.

Skia's SkTypeface has a uniqueID method. Its implementation largely rests on using a cache - when going from a native font object (for example, a DirectWrite font) to an SkTypeface, there's a comparison procedure to compare equality with existing fonts in the cache. An example for DirectWrite shows a fairly complex set of heuristics - it starts with pointer equality and other checks based on the way the font is loaded, then compares a bunch of name strings.

I'm not at all convinced font-kit should be based on a cache the way Skia does it, but it might be useful as a reference.

In any case, we should export the type, then implementations can refine the tactics to compare equality efficiently and reliably, without breaking client code. This is one reason I agree with @pcwalton it should be a type and not a small integer. Another reason is so the Debug formatting is informative.

raphlinus commented 5 years ago

Ooooops, meant to file this against font-kit.