parley icon indicating copy to clipboard operation
parley copied to clipboard

Building for WebAssembly

Open waywardmonkeys opened this issue 1 year ago • 11 comments

Building for WebAssembly targets with default features (read: system) is broken as there isn't an implementation for WebAssembly.

  • Should crates using fontique build with no-default-features and then enable system on all but WebAssembly?
  • Should the null backend be enabled for WebAssembly for the system feature? (Seems like it goes against the idea of a system feature.)
  • Should system not be enabled by default and let consuming crates enable it?
  • Something else?

waywardmonkeys avatar May 31 '24 09:05 waywardmonkeys

system is the main point of fontique, so it being default makes sense, but that leads to the issue you describe. There is also the issue of how to make a useful collection at all in WebAssembly, which I think would probably involve a considerable amount of support from the JavaScript side, or inlining a font into the wasm module (not necessarily the greatest solution either).

xorgy avatar Jun 04 '24 21:06 xorgy

There is https://developer.mozilla.org/en-US/docs/Web/API/Local_Font_Access_API (only currently supported in Chrome and Edge 103 and later, but not Chrome for Android) ... but that would require having async APIs for WebAssembly.

waywardmonkeys avatar Jun 05 '24 00:06 waywardmonkeys

Well, may not require async APIs for wasm, but rather that the loader take care of that stuff before starting the module (or that calls for the system fonts involve waiting). I was not aware that the Local Fonts API had rolled out to any stable browsers!

xorgy avatar Jun 05 '24 14:06 xorgy

Looking into this, apparently it gives you the font data as Blob, which unfortunately can not be mapped zero-copy into wasm memory (at least, not explicitly); so probably the useful way to implement this would be some sort of limited font library selected by the host and copied into the wasm memory.

xorgy avatar Jun 05 '24 14:06 xorgy

Looking into it further, the Local Font Access API has to prompt for permission in a browser, and the message used is something about ‘creating high fidelity content’. If you're building something other than a graphics editor or a tech demo, then presumably a lot of people will click block on this and break your app.

xorgy avatar Jun 06 '24 12:06 xorgy

FWIW: Aside from Chrome, the promise of this working well in either Firefox or Safari is not particularly rosy: https://github.com/mozilla/standards-positions/issues/401#issuecomment-2139560235

torokati44 avatar Jun 12 '24 15:06 torokati44

Hi - can one integrate this library on the basis that WASM support is Planned? If so, do you have a rough ETA e.g., < 3 months, < 6 months, <12 months? Thanks. Also, 2 questions:

  1. Regarding your comments on browser fonts access, will WASM let one package their font assets directly in their crate?
  2. Is some multi-threading (e.g., wasm_bindgen_rayon ), or some parley equivalent planned, - not necessarily multi-threading (as I heard parley is GPU-focused), but essentially something that means a decent level of performance is expected.

Love your work.

Thanks

pbower avatar May 13 '25 14:05 pbower

@pbower As for packaging fonts with your app, you can use static bundling w/ the core::include_bytes macro, and it should work reasonably well if you know at build time what you need to support (but this will be a quite large bundle if you are including CJK fonts). As for rendering, Parley itself is not a renderer. Vello (GPU-focused renderer) is moving in a direction that will make it behave much better in WebGL 2 environments (with vello_hybrid), but you can also use existing software renderers like the one included in Swash (and as it becomes more ready, vello_cpu) if you aren't CPU constrained for text rendering in your application.

xorgy avatar May 13 '25 23:05 xorgy

@pbower As for packaging fonts with your app, you can use static bundling w/ the core::include_bytes macro, and it should work reasonably well if you know at build time what you need to support (but this will be a quite large bundle if you are including CJK fonts). As for rendering, Parley itself is not a renderer. Vello (GPU-focused renderer) is moving in a direction that will make it behave much better in WebGL 2 environments (with vello_hybrid), but you can also use existing software renderers like the one included in Swash (and as it becomes more ready, vello_cpu) if you aren't CPU constrained for text rendering in your application.

Thanks, that’s very helpful. And sorry to press the point - are you saying that it builds for wasm now no problem provided the renderer supports it ? I.e., is this issue font packaging related? Thanks.

pbower avatar May 13 '25 23:05 pbower

@pbower Yes, if you want to build for WASM, you have to disable the system feature, and that means you have to set up your FontContext manually, but it does work. The issue we're talking about in this thread is what a system collection implementation might look like on wasm, given that there is no consistent way that people would introduce fonts into their wasm program in a browser, and no meaningful source of fallback information.

xorgy avatar May 14 '25 20:05 xorgy

Obviously this also needs to consider #346. We seem to have decided on point 2 here.

DJMcNab avatar May 16 '25 12:05 DJMcNab