max / shop
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
1 file changed,
+20 insertions,
-14 deletions
| @@ -396,21 +396,27 @@ | |||
| 396 | 396 | push(slot, shaper, id, col, 0.0, 0.0, color); | |
| 397 | 397 | } | |
| 398 | 398 | CellText::Cluster(s) => { | |
| 399 | - | // The pen walks the cluster so a mark lands wherever the | |
| 400 | - | // font puts it: a combining mark carries no advance, so it | |
| 401 | - | // stacks on the base rather than following it. | |
| 402 | - | let mut pen_x = 0.0; | |
| 399 | + | // Every glyph is drawn from the SAME cell origin, and the | |
| 400 | + | // pen deliberately does not advance between them. | |
| 401 | + | // | |
| 402 | + | // A cluster is one grapheme by construction — a base and | |
| 403 | + | // the zero-width marks after it — so everything past the | |
| 404 | + | // first glyph is a mark belonging on top of that base, in | |
| 405 | + | // this cell. Walking the pen by each glyph's advance is | |
| 406 | + | // what a LINE of text wants and is wrong here: a monospace | |
| 407 | + | // font gives its combining glyphs a full cell of advance | |
| 408 | + | // (measured on the bundled Iosevka: the acute reports the | |
| 409 | + | // cell width, not zero), which would put every mark one | |
| 410 | + | // cell right, on top of the neighbour. | |
| 411 | + | // | |
| 412 | + | // The shaper's own offsets are still honoured, so a font | |
| 413 | + | // positioning marks by GPOS gets what it asked for: those | |
| 414 | + | // offsets are relative to the cluster origin, which is | |
| 415 | + | // exactly what this anchors to. Where the shaper composes | |
| 416 | + | // the pair into one precomposed glyph instead (Iosevka | |
| 417 | + | // does for e + acute), there is nothing left to stack. | |
| 403 | 418 | for g in shaper.shape(&s) { | |
| 404 | - | push( | |
| 405 | - | slot, | |
| 406 | - | shaper, | |
| 407 | - | g.id, | |
| 408 | - | col, | |
| 409 | - | pen_x + g.x_offset, | |
| 410 | - | g.y_offset, | |
| 411 | - | color, | |
| 412 | - | ); | |
| 413 | - | pen_x += g.advance; | |
| 419 | + | push(slot, shaper, g.id, col, g.x_offset, g.y_offset, color); | |
| 414 | 420 | } | |
| 415 | 421 | } | |
| 416 | 422 | } |