Skip to content
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

C interface #119

Closed
spindlebink opened this issue Jul 7, 2022 · 6 comments
Closed

C interface #119

spindlebink opened this issue Jul 7, 2022 · 6 comments
Labels
enhancement New feature or request

Comments

@spindlebink
Copy link

I'm interested in using Fontdue in a non-Rust project. WGPU provides a C interface that makes binding to it from any language easy. Fontdue seems awesome, and it'd be great to be able to do the same--I'd love to be able to use it instead of something like freetype.

Are there any plans to provide a bindable C interface? If not, I'm happy to put some effort in that direction--in which case, is there anything you can think of that might make writing an interface tricky, or any other suggestions?

@mooman219
Copy link
Owner

I've never written a C interface in rust, and I'm unsure of the complexities involved with retro-fitting the library to support such an endeavor. I'm not sure I want to have to maintain a C interface as well. I'm open to the discussion though.

@mooman219 mooman219 added the enhancement New feature or request label Jul 7, 2022
@spindlebink
Copy link
Author

Generally it's not too complex, and involves wrapping trait functions around in C style: struct_type.trait_method in Rust-land becomes lib_struct_type_trait_method(target). It's more boilerplate than retrofitting or design work. As mentioned, I'm happy to give it a shot--if anything comes of it, I'll set up a different repository with the possibility of eventually combining later, if you'd like.

@spindlebink
Copy link
Author

Alright, did a little work on this and it's been pretty straightforward so far. You can keep up to date/see what's involved at the project repo.

@spindlebink
Copy link
Author

spindlebink commented Jul 8, 2022

Have run into an issue with struct privacy: part of writing a C interface is writing C-compatible structs which can be converted to and from library-side structs. This has been largely doable, since most of the private type info is in types that allocate and hence are probably best represented as opaque Box pointers.

The CharacterData struct is a container for a private bits: u8, but there's no way to read that information and no way to construct a CharacterData from a bits value. This means as far as I can tell it's functionally impossible to copy a CharacterData into a C-compatible version, which means I can't implement interface components involving CharacterData.

There are a couple of solutions that I can see, all of them library-side, if you wouldn't mind considering. Everything but the layout module is already working C-side, and I'd really love to be able to continue with the interface project, especially when the blockage is something so simple.

  1. Make bits public. This would make creating CharacterData structs from bits instead of via ::classify doable, and it'd make the field readable.
  2. Wrap that functionality with CharacterData::from_raw_bits and CharacterData.raw_bits() functions. This'd maintain the current API and privacy setup while allowing the interface to convert between C-compatible and Rust-side types.
  3. I wouldn't mind merging the C interface with the main repo and maintaining it if you're interested. This way interface-side code could be in submodules, gated behind a compile feature, and would have full internal access and be able to robustly represent stuff C-side.

Addendum: have discussed with another person about this and it looks like it is possible to make a flat opaque type based on a transmutation of the original struct data (+ the private bit field), which means progressing with the interface is possible irrespective of action on your part. Would still like to hear your thoughts on the issue though!

@spindlebink
Copy link
Author

I've worked around this issue via a flattened opaque type using transmute, so I'll close it.

The complete C interface can be found here.

@mooman219
Copy link
Owner

mooman219 commented Jul 13, 2022

Sorry I haven't replied sooner, real work has been eating my at home programming energy.

In general, I'm apprehensive to make internal state public because that's committing to supporting implementation details. That being said, this bitfield is kind of unnecessary and can probably be replaced with a couple of booleans. I'm fine if you want to submit a PR to replace the bitfield with a couple of public boolean fields for what's currently encoded.

If you plan on submitting a PR, please comment on #113 first. There's a license change in progress to a less restrictive triple license model.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
2 participants