Closed laurmaedje closed 3 years ago
Nice! Can you explain in more details why we need Box<dyn Any>
?
Also, what's your plans on AAT? I would say that the kerx
branch has like 50% done, so it should take a few days to finish.
The Box<dyn Any>
is needed because each complex shaper has custom data and that needs to be stored in the shape plan somehow. The C++ version used a void pointer for that and a create
and destroy
function pointer. I guess we could also use a big enum that can handle every shaper's data, that would save the allocation.
Is the kerx
branch somehow tested? If it's a lot of untested code I fear that it might be hard to debug (if some tests fail, otherwise great). And what's the relation of that code to the kerning code in ttf_parser
?
Oh, I see. Yes, the enum is a more common way to do this. But I guess we can do refactoring later.
AAT is partly tested. Not as well as OpenType. You can target the current tests. We'll see what to do with tests that use licensed fonts later. Having a pure Rust hb implementation is far more important.
As for ttf_parser
, you should basically ignore its kern
implementation. The kerx
module already has kern
table copy-pasted from ttf_parser
.
By the way, if you have any refactoring ideas - feel free to send a pull request. Right now, as you know, a lot of internals are not very idiomatic, because of the incremental porting process.
It'd be nice to have this fully in Rust, but I don't really want to spend time on AAT right now since its rather niche. I think featuring-gating it for now is a reasonable way forward. I'm not sure what to do with kern
. Either we also feature-gate it or move at least that over from ttf-parser.
I see. Then I will work on it in my spare time.
This ports the main shaping logic, including the map, shape plan and complex shaper data structures. Basically, the only things that remain in C++ are AAT and kerning.
Notes:
rb_shape_plan_t
andrb_ot_shape_plan_t
into a single thing because the shape plan was just a thin wrapper around the OpenType shape plan.aat
module, but that's just a thin layer between Rust and C++. The AAT-Map is stack allocated in the shape plan on the Rust side and accessed on the C++ side. I took care that both sides have the same memory size, but I don't know if there are any pitfalls with doing it this way.Box<dyn Any>
. This means that the data has to be'static
. This was mostly not a problem, except for the indic shape plan that had a reference to some lookups in theot_map
. Because the data and map are both stored in the global shape plan, this didn't work anymore (in safe Rust, without pinning or some other trickery), so I replaced the lookup slice with aRange<usize>
.ot
module into the root module because from what I saw in the shaping logic they didn't seem to beot
-specific.coords
vector inFace
wasn't needed anymore since I can now usettfp_face.variation_coordinates()
.pub(crate)
that was spread onto everything that touches aBuffer
. Since theBuffer
is not re-exported, normalpub
is fine I think.rb_buffer_...
functions are probably not needed anymore, but I kept them for now.