Repository navigation
fix(rioterm): render RTL runs (Arabic/Farsi/Hebrew) correctly - #1877
Open
saeidakbari wants to merge 1 commit into
Open
saeidakbari wants to merge 1 commit into
saeidakbari wants to merge 1 commit into
Conversation
RTL text rendered with every glyph crammed into one column, and after a naive reversal fix, with gaps before narrow glyphs (alef in آیا). Root cause: build_row_fg's cluster-to-cell walk was forward-only. Shapers (CoreText, HarfBuzz/swash) return RTL runs in visual order with monotonically decreasing clusters - glyph 0 is the logically-last character - so the cursor jumped to the run's last cell and pinned every glyph there. Fix: attribute_glyphs_to_cells() detects RTL via first.cluster > last.cluster and lays RTL runs out pen-relative: a pen advances by each glyph's real shaped advance from the run's left edge, the cell is floor(pen / cell_w), and the sub-cell remainder goes into the x bearing (renderers already add i16 pixel bearings to the cell origin). Tight packing eliminates the gaps; fg colour still follows the cluster's logical cell so selection/cursor semantics are unchanged. LTR runs take the identical code path as before (extra_x = 0). Tests: synthetic LTR/RTL/mark cases plus an end-to-end CoreText test shaping real Farsi (سلام) through the production shaping path.
saeidakbari
force-pushed
the
fix/rtl-text-rendering
branch
from
August 16, 2026 10:21
3167b50 to
05159dc
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
RTL text (Arabic, Farsi, Hebrew) rendered with every glyph crammed into one column. After a naive per-cell reversal, narrow glyphs (alef) still showed gaps inside words like آیا.
Root cause
build_row_fg's cluster→cell walk was forward-only:Shapers (CoreText, HarfBuzz/swash) return RTL runs in visual order with monotonically decreasing clusters — glyph 0 is the logically-last character. So the cursor jumped to the run's last cell on glyph 0 and stayed pinned: every glyph was emitted at the same
grid_pos.Additionally, snapping proportional Arabic glyphs to monospace cell origins leaves whitespace before narrow glyphs.
Fix
attribute_glyphs_to_cells()detects RTL viafirst.cluster > last.cluster(the documented shaper convention) and lays RTL runs out pen-relative:floor(pen / cell_w)bearings[0](renderers already add i16 pixel bearings to the cell origin — no renderer changes needed)Tight packing eliminates the gaps. Fg colour still follows the cluster's logical cell so selection/cursor semantics are unchanged. LTR runs take an identical code path as before (
extra_x = 0).Testing
سلام) through the productionshape_text_utf16path, asserting each glyph reconstructs its pen positionriotermsuite: 211/211 passKnown limitation
Pure-RTL runs only. Mixed Latin-inside-RTL lines need full UAX#9 bidi reordering.