Skip to content

Switch GlyphString to logical glyph order#164

Merged
afishhh merged 7 commits intomasterfrom
logical-glyph-string
Apr 18, 2026
Merged

Switch GlyphString to logical glyph order#164
afishhh merged 7 commits intomasterfrom
logical-glyph-string

Conversation

@afishhh
Copy link
Copy Markdown
Owner

@afishhh afishhh commented Apr 9, 2026

Story time

So once upon a time a library called "HarfBuzz" was created. This library handled text shaping very well and many serious GUI programs started using it. Said library's main entrypoint is hb_shape which takes a buffer of codepoints along with an array of font features and outputs shaped glyphs in visual order. Here developers of users of HarfBuzz, like subrandr or Chromium, say "okay well I'll keep them in visual order". Unbeknownst to them, they have just fallen prey to impeccable bait laid out by HarfBuzz. In fact, a higher-level layout engine does not benefit from storing glyphs in visual order. The opposite happens: your code is now littered with isLtr() or !self.direction.is_reverse().

Line breaking: happens on the text in logical order.
Hanging white space: the white space at the logical end of a line is hanged.
Splitting the glyph string across spans: if done on logical order glyphs, it will be naturally mirrored on reverse strings.

So yeah just pay the cost of reversing the glyphs and avoid the cost of juggling iteration order later. Having things be clean and logical also ends up simplifying some cases.

Note

I am not the first to realize this, the first thing Firefox does is call hb_buffer_reverse if the direction was right to left.

In other news

Switched GlyphString to use a Vec since fighting with LinkedList without cursors is too much of a pain here, it's probably faster anyway. Also simplified shaping parameter flow and splitting of text across spans.

I'm going to go back to improving white space handling on top of this PR now (which will hopefully make it much simpler). Will finish this once I'm confident this is the right approach. Alternatively I might realize I'm wrong and somehow visual order is better but I doubt that.

@afishhh afishhh force-pushed the logical-glyph-string branch 3 times, most recently from 29cfa2f to 125e7c2 Compare April 10, 2026 11:26
@afishhh
Copy link
Copy Markdown
Owner Author

afishhh commented Apr 14, 2026

I'm going to go back to improving white space handling on top of this PR now (which will hopefully make it much simpler).

I have a proof-of-concept for white space hanging specifically. It's terrible and bad and horrible and bad but honestly the spec is bad and horrible so I'm not sure it can be made not-horrible. Either way I think storing things in logical order is worth it.

@afishhh afishhh force-pushed the logical-glyph-string branch 2 times, most recently from 6b64c23 to 4ad2d60 Compare April 15, 2026 17:46
@afishhh
Copy link
Copy Markdown
Owner Author

afishhh commented Apr 15, 2026

Maybe I should just merge this instead of being eternally uncertain. The main thing I dislike is that the shaping is slightly uglier but I'm probably overthinking it since this is an overall simplification.

@afishhh
Copy link
Copy Markdown
Owner Author

afishhh commented Apr 16, 2026

These shaping changes are bad and broken and bad, found some bugs. Need to find a clean way to do that before this can be merged.

@afishhh afishhh force-pushed the logical-glyph-string branch from 9b4ff35 to 072d62e Compare April 17, 2026 13:07
@afishhh
Copy link
Copy Markdown
Owner Author

afishhh commented Apr 17, 2026

These shaping changes are bad and broken and bad, found some bugs. Need to find a clean way to do that before this can be merged.

It's now less bad and not obviously broken, maybe not "clean" but at least clean-er. Will merge after more testing.

afishhh added 4 commits April 18, 2026 14:06
It's pretty big so probably shouldn't be allocated inline to keep the
enum smaller (though right now it's still huge due to `ComputedStyle`
being huge).
@afishhh afishhh force-pushed the logical-glyph-string branch from 072d62e to 0669a85 Compare April 18, 2026 12:09
@afishhh afishhh merged commit 0669a85 into master Apr 18, 2026
8 checks passed
@afishhh afishhh deleted the logical-glyph-string branch April 18, 2026 12:39
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.

1 participant