Expand description
Bidirectional-text index↔x mapping for gpui shaped lines.
§Why this exists
The platform shapers already do bidi correctly. Shape "سلام دنیا" and the
glyphs come back in visual order carrying logical byte indices —
for that string, indices 15, 13, 11, 9, 8, 6, 2, 0 as x ascends. That is
exactly what UAX #9 asks for, and it means RTL text renders right today.
What is wrong is how those glyphs get read back. gpui’s
LineLayout::x_for_index returns the first glyph whose index >= target,
which assumes byte index and x rise together. In an RTL line the first
glyph carries the highest index, so every offset in the line resolves to
the same glyph and the caret collapses onto x = 0. index_for_x and
closest_index_for_x fail the same way, and mixed content is worse: in
"hello سلام world" the four offsets 6, 8, 10, 12 all map to one x.
So this crate is mostly not an implementation of the bidi algorithm —
the shaper did that, and this reads its already-reordered glyph table
correctly. The one thing the glyph table cannot tell you is a glyph’s
embedding LEVEL: at the edge of an embedded run the glyph beside it belongs
to the other run and carries a misleading index, so direction inferred from
geometry is wrong exactly there. Those levels come from unicode-bidi,
given the text — see VisualMap::with_levels.
§Shape of the API
VisualMap is built from plain (logical byte index, x) pairs, so every
rule here is unit-testable without a window, a GPU, or a font. Hosts get
those pairs from a shaped line — see VisualMap::from_glyphs and the
gpui adapter in shaped.
§What a caller still owns
- Paragraph direction (which side a line starts on) is the host’s, from the first strong character. This crate only maps within a shaped line.
- Logical caret movement. Left/right arrows moving in logical order
needs nothing from here. For the visual movement platforms actually do
in bidi text, see
VisualMap::step_visual.
Modules§
- paragraph
- Logical-order line breaking for right-to-left paragraphs.
- shaped
- The gpui adapter: read a
VisualMapout of a shaped line.