uikit
uikit copied to clipboard
Generating MSDFs on the fly
troika text has quite an interesting approach. They generate the signed distance fields for each glyph on the fly, while also allowing its users to specify characters to preload or even provide already compiled SDFs. The latter would allow a dynamic and simple approach to enable multiple languages. Alternatively, one could generate the whole character set, but save for each glyph and have the current json text format just reference it to enable lazy loading.
AFAIK SDFs are the plan for v2, which will make this easier. In the meantime, we've built a MSDF generator and released it on npm here - https://www.npmjs.com/package/@zappar/msdf-generator (it powers https://pmndrs.github.io/uikit/docs/tutorials/custom-fonts#option-1:-web-based-tool ).
The cost of using this at runtime is ~1mb of wasm, and ~100ms generation time on most mobile devices. One could potentially build some loader/suspense component around it and generate on the fly.
Nice work, I was meaning to do the WASM port at some point! I am surprised you get around 1mb ... are you using Embind and only binding the core or also the extension? Yet to comment on the v2 roadmap, but I think we should be able to get this under 200kb, maybe even lower and lazy load it in UIKit as opposed to going for SDF.
Iirc the main chunk of the wasm is Skia PathOps which we use to fix overlaps.
Will see if I can open source the repo next week and get wider thoughts.
Got the wasm down to 300kB https://msdf-staging.zap.works/1.1.0-beta.4/index.html#stress
Mainly through replacing freetype with https://github.com/nothings/stb/blob/master/stb_truetype.h
On most of my devices I'm able to generate a font in 30-60ms.
Wohoo! We mostly use embind with Bazel to really control what parts to port and which dependencies to pull. Glad you found a big dependency to replace! Curious how you did the binding!
Without Bazel, I think one could define an api file with the bare minimum that needs to be bound. That way the compiler only pulls in what it needs (in most cases).
Bazel looks cool, It's currently more so the latter :) Shall update the thread once we have something on GitHub!
RFC here https://github.com/pmndrs/uikit/issues/231