mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-07-11 17:04:01 +08:00
This PR partially addresses #4504 with a one-liner, all feedback is very welcome. ### AI disclaimer I used Claude Code to help navigate the various layers of the rendering stack, to instrument a ton of intermediate now-deleted log statements, and ultimately to identify and fix this bug. I directed it conversationally, gave it experiments to run, audited all of its work, threw most of it out, and finally landed on this extremely small and simple change that fixes the issue _for me_ but I think for a lot of other cases as well. The fix ended up being small, so hopefully it's easy to review and discuss. Details: # Fix horizontal glyph spacing on non-Retina displays On external monitors (1.0x scale, 72 DPI), text had excessive horizontal spacing between glyphs. The issue was less noticeable on Retina displays (2.0x scale, 144 DPI) due to higher pixel density, but the proportional spacing error was identical. ## Before Background is ghostty 1.2.3 from homebrew, foregreound is iTerm2: <img width="862" height="938" alt="Screenshot 2025-10-31 at 3 04 47 PM" src="https://github.com/user-attachments/assets/feff5279-05cc-4008-b2f5-8ea3b4d6d14b" /> ## After Background is ghostty tip + this change, foreground is iTerm2: <img width="659" height="774" alt="Screenshot 2025-10-31 at 3 00 42 PM" src="https://github.com/user-attachments/assets/702dc7f8-bb46-43ec-8156-f69d003e8a37" /> (my iTerm2 has some custom thickening / brightening you can see; that's not a part of this change) ## Root Cause The metrics calculation in Metrics.zig used `@ceil()` to round the cell width from CoreText's glyph measurements, which created a mismatch between cell width (which determines glyph positions) and the actual glyph advances. At 72 DPI with a 12pt font: - CoreText returns glyph advance: 7.224609375 pixels - Cell width was ceiled to: 8 pixels - Gap per character: 0.78 pixels (~10.8% error) At 144 DPI with the same font: - CoreText returns glyph advance: 14.44921875 pixels (exactly 2x) - Cell width was ceiled to: 15 pixels - Gap per character: 0.55 pixels (~3.8% error) The error at high DPI is much better than at low DPI, since the absolute error is always no more than 1px. ## Fix Changed `@ceil(face_width)` to `@round(face_width)`. This makes cell width match the glyph advances better, reducing the error to at most 0.5px: - 72 DPI: round(7.22) = 7 - 144 DPI: round(14.45) = 14 Height continues using `@ceil()` since vertical space can be slightly larger without visual issues, but... should it? I'm not sure; this is a good topic for discussion.