RazrFalcon / rustybuzz

A complete harfbuzz's shaping algorithm port to Rust
MIT License
544 stars 34 forks source link

Expose UNSAFE_TO_BREAK flag in public API? #27

Closed glowcoil closed 3 years ago

glowcoil commented 3 years ago

It would be useful if the UNSAFE_TO_BREAK glyph flag were exposed in the public API so that layout algorithms can take it into account. From my understanding, it can enable line-breaking algorithms to avoid reshaping substrings multiple times or making simplifying incorrect assumptions such as that spaces do not participate in shaping.

It seems like the simplest approach would be to expose the mask field of GlyphInfo as a bitflags struct, but I wanted to check if this was a good approach before filing a pull request.

P.S. I'm very excited about this library; great work.

RazrFalcon commented 3 years ago

Looks like this is part of private API in harfbuzz too. I have no idea what this flag does, so I'm hesitating to make it public, especially without good documentation.

glowcoil commented 3 years ago

I believe HarfBuzz exposes it publicly via the hb_glyph_info_get_glyph_flags function, and there's also a brief explanation of it on the "getting started" documentation.

RazrFalcon commented 3 years ago

hb_glyph_info_get_glyph_flags returns a copy of flags. And the mask field marked as private.

glowcoil commented 3 years ago

So do you think that a method GlyphInfo::get_glyph_flags() that returns a GlyphFlags would make sense?

RazrFalcon commented 3 years ago

No, I think that this should stay private, just like in hb. Unless someone would be able to explain what this flag actually does.

glowcoil commented 3 years ago

But the hb_glyph_info_get_glyph_flags function and hb_glyph_flags_t are not private, just the mask field itself.

The HarfBuzz docs have an explanation that seems clear to me:

Indicates that if input text is broken at the beginning of the cluster this glyph is part of, then both sides need to be re-shaped, as the result might be different. On the flip side, it means that when this flag is not present, then it's safe to break the glyph-run at the beginning of this cluster, and the two sides represent the exact same result one would get if breaking input text at the beginning of this cluster and shaping the two sides separately. This can be used to optimize paragraph layout, by avoiding re-shaping of each line after line-breaking, or limiting the reshaping to a small piece around the breaking point only.

There is also discussion of the API design for this here.

RazrFalcon commented 3 years ago

Ok, so looks like this flag would be set by the shaper. I thought that the caller should set it before shaping. Then yes, we should simply expose it. I guess just as GlyphInfo::unsafe_to_break(&self) -> bool