Skip to content

Conversation

@jacobsandlund
Copy link
Contributor

This PR simplifies and corrects the logic for placing a glyph vertically, by using the position.y from CoreText directly, instead of using an offset from the cell's starting y. The logic was incorrect from the beginning, always treating the first glyph of a cell as being at y of zero. We only need to be subtracting the cell's starting x to align the glyphs to the cell grid.

Enabling the commented out logging, I found no instances of position.y differs from old offset.y lines with JetBrains Mono with ligatures turned on, but running ttylang (printing the Universal Declaration of Human Rights in various languages) revealed 676 instances of this, with many only slightly off.

An example log from some Tai Tham text is the following, and this PR adds a test based on this:

...pos=(0.00,-8.21) run_offset=(69.41,-8.21) cell_offset=(69.41,-8.21) old offset.y=0.00 cps = \u{1a49}\u{1a60} \u{1a3f}▸\u{1a69} \u{1a2f} → ᩉ᩠ᨿᩩᨯ

Browsers display this as:

ᩉ᩠ᨿᩩ

main is printing:

CleanShot 2026-01-05 at 10 28 17@2x

this PR prints:

CleanShot 2026-01-05 at 10 29 07@2x

Since this is a ligature of two different grapheme clusters, Ghostty ends up subtracting too much of the x value with the cell_offset.x (starting x), so neither of the screenshots above are correct, but the second is closer and gets the y value right.

AI disclaimer: I didn't use AI for the code, but did ask it about this Tai Tham text and why it wasn't a single grapheme cluster: https://ampcode.com/threads/T-019b8ea2-1822-75bb-a8eb-55a9ddb9f7ea

@jacobsandlund jacobsandlund requested a review from a team as a code owner January 5, 2026 15:34
Copy link
Contributor

@mitchellh mitchellh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good pending CI

@mitchellh
Copy link
Contributor

Thanks again for the diligence in following up with this <3

@mitchellh mitchellh added this to the 1.3.0 milestone Jan 5, 2026
@mitchellh mitchellh merged commit dda27d4 into ghostty-org:main Jan 5, 2026
53 checks passed
mitchellh added a commit that referenced this pull request Jan 15, 2026
… glyphs incorrectly (#10295)

This PR implements a heuristic for detecting ligatures that then
prevents resetting to the cell grid prematurely, avoiding position
errors from glyphs that follow ligatures. The inspiration for this was
the example from #10179 that
was off.

See the giant comment for an explanation of the heuristic.

The tests for this are the following:

### Tai Tham
The Tai Tham example from
#10179 got updated since now
the marking glyph is attached to the ligature cell correctly.

Browser:
ᩉ᩠ᨿᩩ

Before:
<img width="970" height="110" alt="CleanShot 2026-01-12 at 10 02 42@2x"
src="https://github.com/user-attachments/assets/1315bbeb-0541-420a-91a1-bac39897efe3"
/>

After:
<img width="962" height="122" alt="CleanShot 2026-01-12 at 10 02 57@2x"
src="https://github.com/user-attachments/assets/ca2b3e1d-0785-462f-993c-f482d875a1e9"
/>

### Javanese

Browser:
ꦤ꧀ꦲꦸ

Before:
<img width="962" height="98" alt="CleanShot 2026-01-12 at 10 05 43@2x"
src="https://github.com/user-attachments/assets/74002334-7140-4646-806e-2194457e56c5"
/>

After:
<img width="962" height="110" alt="CleanShot 2026-01-12 at 10 05 23@2x"
src="https://github.com/user-attachments/assets/49c08ac9-98af-409c-9b0e-49a34da93597"
/>

There does seem to be a small maybe single pixel difference here, and I
didn't investigate why.

### Chakma

Browser:
𑄝𑄖𑄳𑄠𑄬

Before:
<img width="1406" height="104" alt="CleanShot 2026-01-12 at 10 07 52@2x"
src="https://github.com/user-attachments/assets/3ba7a9d8-d2a2-4e47-976a-8c7702462a49"
/>

After:
<img width="1408" height="104" alt="CleanShot 2026-01-12 at 10 08 08@2x"
src="https://github.com/user-attachments/assets/c25c4a41-b651-4109-8ded-69983fc77267"
/>

### Bengali

Browser:
রাষ্ট্রে

Before:
<img width="1370" height="84" alt="CleanShot 2026-01-12 at 10 10 42@2x"
src="https://github.com/user-attachments/assets/c59e5fc9-0e9e-4c8f-b937-025ad28866d2"
/>

After:
<img width="1370" height="96" alt="CleanShot 2026-01-12 at 10 11 00@2x"
src="https://github.com/user-attachments/assets/d108dcda-b0b5-4824-b3e4-d1e2ddb6d6de"
/>

This one doesn't match the browser, but it seems like a CoreText or font
issue.

### Log output

I've got a `log.txt` with 15k lines from "cell_offset.cluster differs
from cluster (potential ligature detected)" logs when I run
[ttylang](https://github.com/jacobsandlund/ttylang) (printing the
Universal Declaration of Human Rights in various languages).

But right now when I try to create a gist with it, I get:

<img width="1554" height="584" alt="CleanShot 2026-01-12 at 10 15 29@2x"
src="https://github.com/user-attachments/assets/b8a5dd0c-c034-45f6-a2fb-80c67f93f26f"
/>
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.

2 participants