-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft implementation of wasm shaper #122
Conversation
How exactly do they depend on it? We indeed don't have scale, so no scale should be applied (or basically a "scale" of 1). |
Or rather, scale of UPEM in HB terms. |
I haven't actually looked through the code , but this example uses optical size to render the glyphs. |
This is nice, particularly because wasmtime seems to have a "fuel" concept to limit CPU usage: https://github.com/bytecodealliance/wasmtime/blob/main/examples/fuel.rs It generally looks like a better runtime than wasm-micro-runtime, which has several problems as a library. |
So I should just return the upem and be done with it? This leaves the issue of how to deal with pointers :D |
Yes. UPEM works I think. No idea re pointers I'm afraid. |
Just ignore it.
Me neither. I never worked with WASM. |
Gave more flesh to a few functions. Left plenty of For dealing with pointers and wasm memory I got thankfully some pointers (hehe) from @CryZe at the Rust Community Server. |
A smaller wasm dependency is for sure preferable. |
src/hb/shape_wasm.rs
Outdated
unsafe impl bytemuck::Pod for CBufferContents {} | ||
|
||
#[cfg(test)] | ||
mod wasm_tests { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move tests to the tests directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. But I am not sure if that's better for the Ruqaa test, as it now doesn't distinguish between the wasm code failing and faulty output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How so? Can you elaborate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not a very well formed thought, but the wasm shaper can fail in two ways (categories of ways, rather). Either shape_with_wasm
returns with bad output, or it returns None
, because of some wasm failure. Since the tests in the tests folder only test the public API instead of private functions, they always return, as they fall back to the regular shaper. So one might not be able to tell if the wasm module crashed or not.
@asibahi this is very exciting! As a quick note, please don't hesitate to reach out to us in the Bytecode Alliance for any help we might be able to provide with Wasmtime. The Wasmtime maintainers are very responsive on our Zulip.
Incidentally, we're working on both of those! There's an RFC for adding an interpreter, and recently parts of the runtime gained support for We also have minimal embeddings getting the size of Wasmtime down to about 2MB right now, with a clear path towards the hundreds of kilobytes range if needed. Having said all this, |
Hi, I have just been made aware of this topic by @tschneidereit 's mention of me and haven't read everything (no time to do so rn). I am happy to help. Either solution, Wasmtime or Wasmi, should work fine since both mostly share the same API surface. It could even be possible to use both solutions simultaneously for their different strengths. |
src/hb/shape.rs
Outdated
@@ -20,7 +20,16 @@ pub fn shape(face: &hb_font_t, features: &[Feature], mut buffer: UnicodeBuffer) | |||
buffer.0.language.as_ref(), | |||
features, | |||
); | |||
shape_with_plan(face, &plan, buffer) | |||
#[cfg(not(feature = "wasm-shaper"))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we check for the Wasm
table here? I.e. this should be a runtime decision, not compile-time one.
If we have Wasm
table, try shape_with_wasm
, otherwise shape_with_plan
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what this code does. The Wasm
table is the first thing shape_with_wasm
checks for, and if it is not there it returns None
. The compile time check here is for the featuree as shape_with_wasm
does not exist then.
ِEdit: I moved it to inside shape_with_plan
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But if there is no Wasm
table you exit the shaping immediately, instead of calling the regular shaper. No?
I would expect something like:
if has_wasm_table and run_wasm_shaper():
return
run_regular_shaper()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah shape_with_wasm
fails if there is no "Wasm"
table. The fallback to regular shaper happens in shape_with_plan
here. You can see the regular tests pass just fine with the feature turned on.
Fixed the bug and now the Ruqaa Font tests works if we do not compare clusters. That'll teach me to read the standard library's documentation. |
One thing I learned about recently: Is Also re: |
Once again, there is no scale in rustybuzz. It was removed during porting. It should always be 1.
In harfbuzz terminology this is still the |
It should be always units_per_em. And it's NOT related to pixels_per_em. |
So I think this is done. The full defined API in the design document is not implemented, but only the ones used by the examples. Edit: should you merge this could you make it a squish merge 😁 |
Thanks! Will be released soon. Will see how it will go. |
Hello.
working on this
So I started a basic structure of the
wasm
runner and how to export functions to thewasm
module. I am using thewasmtime
crate.The general workflow is this :
Wasm
table. If it is there : run it.shape_with
exported function should just always direct toshape_with_plan
Wasm
table is not there or is malformed , useshape_with_plan
. instead like normal.I already hit a couple of things I do not understand:
wasmtime
APIs to "link" functions with pointers is giving me compiler errors. You can see what the compiler points are by uncommenting the marked lines. Something about traits?This is a draft PR hoping for some feedback and help.
Final edit I swear:
The two places where I am looking at the functions and how they're used are :
harfbuzz-wasm
crate. (yes that's the entire crate.)The C++ implementation of the
wasm
api is here But C++ is black magic to me.