Skip to content

rioterm: shape attached combining marks with their base glyph - #1850

Closed
raphamorim wants to merge 1 commit into
mainfrom
shape-attached-marks
Closed

raphamorim wants to merge 1 commit into
mainfrom
shape-attached-marks

Conversation

@raphamorim

Copy link
Copy Markdown
Owner

Workstream 0c of the mode-2027 scoping — a standalone rendering bug fix that ships on its own.

The bug

build_row_fg hashes a cell's attached zerowidth codepoints into the run-cache key (so e+U+0301 and e+U+0302 don't alias) but never put them in the shaping buffer — only the base char was pushed. Every combining sequence in the grid renders as its bare base character: decomposed é draws as e, Devanagari conjuncts lose their matras, etc.

The fix

  • Attached marks are appended to the shaping buffer after their base on both platforms, so the shaper composes them (emit_preedit_cluster in rioterm: render the IME composition inline at the cursor #1849 already does this for IME text; this brings grid text to parity).
  • The glyph→cell mapping moves to explicit per-cell starts on both platforms. The swash path walked char_indices() assuming one char per cell — with marks in the buffer that cursor would misattribute every following glyph. macOS already used a cell-starts table; the two walks now share one implementation (run_cell_starts: UTF-16 units on macOS, byte offsets on swash — swash reports cluster.source.start as byte offsets).
  • VS15/VS16 stay excluded, mirroring hash_combining: presentation is already resolved into font_id, and feeding a variation selector to a text font's shaper only yields a notdef.
  • Kitty Unicode-placeholder cells are excluded from the mark push — their zerowidth encodes image-slice coordinates, not text.

Verification

174 rioterm tests pass (two new: shaping-buffer layout incl. selector skipping, and the cell-starts attribution walk). Clippy/fmt clean. The swash side compiles only on non-macOS — the ubuntu CI leg is the verifier for that path (local cross-checks are blocked by native build scripts). Visual check: echo -e 'éx' should render éx, not ex.

The emit loop hashed a cell's zerowidth codepoints into the run-cache
key but only ever pushed the base char into the shaping buffer, so a
combining sequence rendered as its bare base: e + U+0301 drew as e.
Marks now shape with their base on both platforms. The glyph-to-cell
walk moves to explicit per-cell starts everywhere (UTF-16 units on
macOS, byte offsets on swash) since the swash path's per-char cursor
assumed one char per cell. VS15/VS16 stay out of the buffer, matching
the hash: presentation is already resolved into font_id, and a
selector fed to a text font only produces a notdef. Kitty placeholder
cells are excluded; their zerowidth carries image-slice coordinates,
not text.
@raphamorim

Copy link
Copy Markdown
Owner Author

Folded into the consolidated unicode-foundation PR (all four workstream-0 pieces in one branch for testability, commits preserved).

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