Skip to content

Conversation

@simoncozens
Copy link
Contributor

This ports the Harfbuzz tracing messages protocol to Harfrust.

Because all the internal shaping guts deal in hb_buffer_ts, we pass a hb_buffer_t to the callback function. In a prefect world, the user would receive a UnicodeBuffer or GlyphBuffer depending on what stage of shaping we're at, but that requires something like wrapping the heterogenous types in an enum so that either kind of buffer can be passed to the same callback function, which is boring, and annotating every call to message! with what kind of buffer to return, which is intrusive.

So while this implementation is mildly inconvenient, I'm relying on the fact that the kind of person who is doing stuff with a messaging function is the kind of person who will be able to handle raw hb_buffer_t types (including, unfortunately, having to handle serialization themselves).

@simoncozens
Copy link
Contributor Author

Clippy fails are not my fails.

@dfrg
Copy link
Collaborator

dfrg commented Oct 15, 2025

So while this implementation is mildly inconvenient, I'm relying on the fact that the kind of person who is doing stuff with a messaging function is the kind of person who will be able to handle raw hb_buffer_t types (including, unfortunately, having to handle serialization themselves).

This is unfortunate (and I think it's what's causing the clippy failures). Behdad and I have discussed dropping the type state pattern around the buffer and just exposing a single Buffer type a la HB. I think we should consider that change before merging this because I'd prefer not to expose the internal type.

@behdad
Copy link
Member

behdad commented Oct 15, 2025

This would be great to have. +1 to removing the extra types.

@simoncozens
Copy link
Contributor Author

The wrapper types are quite helpful though, for avoiding confusion about what kind of buffer you've got. Another approach would be to add a couple of TryInto traits.

@khaledhosny khaledhosny linked an issue Oct 15, 2025 that may be closed by this pull request
@simoncozens
Copy link
Contributor Author

Argh, yes, this isn't going to work because the client can't current do anything with the hb_buffer_t type. It's all pub and everything, but the hb::buffer module isn't actually exported.

@simoncozens
Copy link
Contributor Author

Oh, another problem. Even if we do make a buffer available to the client, we can currently only pass simple functions. If we want to pass mutable closures (FnMut) - and we do - then we either have to make them <'static> (which means you can't get any information back out of the closure, which makes it kind of useless, or we scope the closure to the lifetime of the buffer, and that gets you into all kinds of lifetime problems.

@simoncozens
Copy link
Contributor Author

Making them static, consumers can do evil things with Rc<RefCell<>> if they want to get stuff back out of the closure.

@behdad
Copy link
Member

behdad commented Oct 16, 2025

This is so cool! I can even hook it up in hb-harfrust.

@nicoburns
Copy link
Collaborator

I feel like this ought to be feature flagged so that it completely compiles out when not in use. Skimming through this PR, this probably wouldn't be that hard to do?

@simoncozens
Copy link
Contributor Author

Agree but first we need a steer from Behdad and Chad about what to do with buffer types. My preference is for the messages to actually return an enum of GlyphBuffer and UnicodeBuffer. (And add getters to UnicodeBuffer.) But unifying the types is also an option.

@behdad
Copy link
Member

behdad commented Oct 26, 2025

That's up to Chad. I prefer a single-type solution closer to HB.

@dfrg dfrg mentioned this pull request Nov 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support HarfBuzz message callback

4 participants