Fit a glyph that a fallback face draws wider than its cells #10

Merged
natsukium merged 1 commit from fix/fit-overwide-glyphs into main 2026-10-03 11:50:52 +09:00
Owner

An East Asian Ambiguous character such as ※ is one cell wide, but a CJK fallback face draws it full-width, so a run of them overlapped into an unreadable smear. Text-presentation emoji from the color face (☺) overflowed the same way.

A glyph whose advance overruns the block it is placed in (its grid width or OSC 66 w, times the cell width, times s) is now rasterized at the size where its ink fits the block, and centred in it. Sizing by the ink rather than the advance keeps a fitted ※ about as large as in kitty and WezTerm. Primary-face text keeps its size at every OSC 66 scale. Multi-codepoint clusters are tracked in #17.

An East Asian Ambiguous character such as `※` is one cell wide, but a CJK fallback face draws it full-width, so a run of them overlapped into an unreadable smear. Text-presentation emoji from the color face (`☺`) overflowed the same way. A glyph whose advance overruns the block it is placed in (its grid width or OSC 66 `w`, times the cell width, times `s`) is now rasterized at the size where its ink fits the block, and centred in it. Sizing by the ink rather than the advance keeps a fitted `※` about as large as in kitty and WezTerm. Primary-face text keeps its size at every OSC 66 scale. Multi-codepoint clusters are tracked in #17.
render: shrink a glyph whose advance overruns its cells
All checks were successful
darwin / detect relevant changes (pull_request) Successful in 9s
darwin / darwin docs-only no-op (pull_request) Has been skipped
windows / detect relevant changes (pull_request) Successful in 33s
windows / windows docs-only no-op (pull_request) Has been skipped
darwin / build felis (aarch64-darwin) (pull_request) Successful in 1m5s
windows / cargo nextest (Windows) (pull_request) Successful in 4m35s
windows / frontend smoke (Windows) (pull_request) Successful in 44s
windows / package felis (x86_64-pc-windows-msvc) (pull_request) Has been skipped
pr / nix flake check (pull_request) Successful in 2m26s
pr / cargo build / clippy / test / deny (pull_request) Successful in 2m11s
pr / wire schema is compatible with the base (pull_request) Successful in 3s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 38s
windows / cargo clippy (Windows cross) (pull_request) Successful in 46s
5e89f771fc
An East Asian Ambiguous character such as U+203B (※) is one cell wide
in the grid, but when the primary face lacks it the CJK fallback face
draws it full-width, so every ※ covered half of its right neighbour and
a run of them rendered as an unreadable smear. Text-presentation emoji
resolved to the color face (☺) overflowed the same way.

The per-char raster path now compares the face's advance with the block
the renderer places the glyph in (grid width or OSC 66 `w`, times the
cell width, times the integer scale `s`) and, when the advance overruns
it, rasterizes at the size that makes it fit. This follows kitty, keyed
on the advance rather than the ink box.

The allowed overrun is `s` pixels, not a fixed one: the cell width
rounds the primary advance, so a primary glyph already overruns by up to
half a pixel times `s`, and a fixed pixel shrank sized ASCII from s=3.
A fixed symbol table (ghostty's `isSymbol`) was not taken because the
advance already identifies the glyphs that overrun, on whatever fallback
faces the host installs.

The fitting test runs on the pinned test font set, so CI exercises a
real fallback overrun instead of skipping on hosts without a CJK face.

Assisted-by: Claude Code
natsukium changed title from Shrink a glyph that a fallback face draws wider than its cells to Fit a glyph that a fallback face draws wider than its cells 2026-10-02 22:14:17 +09:00
natsukium force-pushed fix/fit-overwide-glyphs from 5e89f771fc
All checks were successful
darwin / detect relevant changes (pull_request) Successful in 9s
darwin / darwin docs-only no-op (pull_request) Has been skipped
windows / detect relevant changes (pull_request) Successful in 33s
windows / windows docs-only no-op (pull_request) Has been skipped
darwin / build felis (aarch64-darwin) (pull_request) Successful in 1m5s
windows / cargo nextest (Windows) (pull_request) Successful in 4m35s
windows / frontend smoke (Windows) (pull_request) Successful in 44s
windows / package felis (x86_64-pc-windows-msvc) (pull_request) Has been skipped
pr / nix flake check (pull_request) Successful in 2m26s
pr / cargo build / clippy / test / deny (pull_request) Successful in 2m11s
pr / wire schema is compatible with the base (pull_request) Successful in 3s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 38s
windows / cargo clippy (Windows cross) (pull_request) Successful in 46s
to 7a7ea401ef
Some checks failed
pr / nix flake check (pull_request) Successful in 24m27s
pr / cargo build / clippy / test / deny (pull_request) Successful in 13m29s
pr / wire schema is compatible with the base (pull_request) Successful in 11m38s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 13m46s
darwin / detect relevant changes (pull_request) Successful in 8s
darwin / darwin docs-only no-op (pull_request) Has been skipped
windows / cargo clippy (Windows cross) (pull_request) Successful in 13s
windows / detect relevant changes (pull_request) Successful in 14s
windows / windows docs-only no-op (pull_request) Has been skipped
darwin / build felis (aarch64-darwin) (pull_request) Successful in 1m3s
windows / frontend smoke (Windows) (pull_request) Has been cancelled
windows / package felis (x86_64-pc-windows-msvc) (pull_request) Has been cancelled
windows / cargo nextest (Windows) (pull_request) Has been cancelled
2026-10-02 22:14:17 +09:00
Compare
natsukium force-pushed fix/fit-overwide-glyphs from 7a7ea401ef
Some checks failed
pr / nix flake check (pull_request) Successful in 24m27s
pr / cargo build / clippy / test / deny (pull_request) Successful in 13m29s
pr / wire schema is compatible with the base (pull_request) Successful in 11m38s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 13m46s
darwin / detect relevant changes (pull_request) Successful in 8s
darwin / darwin docs-only no-op (pull_request) Has been skipped
windows / cargo clippy (Windows cross) (pull_request) Successful in 13s
windows / detect relevant changes (pull_request) Successful in 14s
windows / windows docs-only no-op (pull_request) Has been skipped
darwin / build felis (aarch64-darwin) (pull_request) Successful in 1m3s
windows / frontend smoke (Windows) (pull_request) Has been cancelled
windows / package felis (x86_64-pc-windows-msvc) (pull_request) Has been cancelled
windows / cargo nextest (Windows) (pull_request) Has been cancelled
to eb346f34d0
Some checks failed
darwin / detect relevant changes (pull_request) Successful in 8s
pr / nix flake check (pull_request) Successful in 9s
darwin / darwin docs-only no-op (pull_request) Has been skipped
windows / detect relevant changes (pull_request) Successful in 8s
windows / windows docs-only no-op (pull_request) Has been skipped
darwin / build felis (aarch64-darwin) (pull_request) Successful in 59s
pr / wire schema is compatible with the base (pull_request) Has been cancelled
pr / frontend smoke (x86_64-linux) (pull_request) Has been cancelled
windows / cargo clippy (Windows cross) (pull_request) Has been cancelled
windows / frontend smoke (Windows) (pull_request) Has been cancelled
windows / package felis (x86_64-pc-windows-msvc) (pull_request) Has been cancelled
pr / cargo build / clippy / test / deny (pull_request) Has been cancelled
windows / cargo nextest (Windows) (pull_request) Has been cancelled
2026-10-03 00:54:43 +09:00
Compare
natsukium force-pushed fix/fit-overwide-glyphs from eb346f34d0
Some checks failed
darwin / detect relevant changes (pull_request) Successful in 8s
pr / nix flake check (pull_request) Successful in 9s
darwin / darwin docs-only no-op (pull_request) Has been skipped
windows / detect relevant changes (pull_request) Successful in 8s
windows / windows docs-only no-op (pull_request) Has been skipped
darwin / build felis (aarch64-darwin) (pull_request) Successful in 59s
pr / wire schema is compatible with the base (pull_request) Has been cancelled
pr / frontend smoke (x86_64-linux) (pull_request) Has been cancelled
windows / cargo clippy (Windows cross) (pull_request) Has been cancelled
windows / frontend smoke (Windows) (pull_request) Has been cancelled
windows / package felis (x86_64-pc-windows-msvc) (pull_request) Has been cancelled
pr / cargo build / clippy / test / deny (pull_request) Has been cancelled
windows / cargo nextest (Windows) (pull_request) Has been cancelled
to fc37243bd5
All checks were successful
pr / nix flake check (pull_request) Successful in 8s
darwin / detect relevant changes (pull_request) Successful in 7s
darwin / darwin docs-only no-op (pull_request) Has been skipped
windows / detect relevant changes (pull_request) Successful in 8s
windows / windows docs-only no-op (pull_request) Has been skipped
darwin / build felis (aarch64-darwin) (pull_request) Successful in 1m4s
pr / cargo build / clippy / test / deny (pull_request) Successful in 3m9s
pr / wire schema is compatible with the base (pull_request) Successful in 4s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 54s
windows / cargo clippy (Windows cross) (pull_request) Successful in 30s
windows / cargo nextest (Windows) (pull_request) Successful in 5m44s
windows / frontend smoke (Windows) (pull_request) Successful in 1m5s
windows / package felis (x86_64-pc-windows-msvc) (pull_request) Has been skipped
2026-10-03 00:56:27 +09:00
Compare
natsukium deleted branch fix/fit-overwide-glyphs 2026-10-03 11:50:52 +09:00
Sign in to join this conversation.
No reviewers
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
felis-terminal/felis!10
No description provided.