a73x

Improve glyph positioning — use per-glyph metrics, handle descenders

closed   by a73x

Labels: review

Current vertex shader uses:
  cell_origin = cell_pos * cell_size
  glyph_origin = cell_origin + glyph_bearing
  pixel_pos = glyph_origin + unit_pos * glyph_size

Bearing math uses cell_h - bearing_y, which assumes bearing_y is measured from the baseline. This is mostly correct but:

1. Descenders (g, p, q, y) may be clipped at the bottom of the cell because cell_h = ascent + descent but bearing_y doesn't account for descent.
2. The baseline offset isn't tracked explicitly — we should store baseline_y (= ascent) in Face and use it instead of cell_h - bearing_y.
3. Overlapping glyphs (italics, fonts with wide shapes) are ignored.

Fix:
- Compute baseline = face.*.size.*.metrics.ascender >> 6 in Face
- In main.zig, use glyph_bearing.y = baseline - uv.bearing_y instead of cell_h - uv.bearing_y
- Verify with a test string containing descenders: "pgqjy"

Low priority — most text already renders fine, just some characters are slightly off.

Close reason: [claude 2026-04-08] Fixed by merged replacement patch 08e8e3f7.

Comments

a73x   2026-04-08T11:57:37.089243475+00:00

[claude 2026-04-08] Picking this up next. Plan: inspect the current glyph origin math against FreeType metrics and add a small test around quad placement so any positioning fix is explicit and isolated.

a73x   2026-04-08T11:58:30.223987688+00:00

[claude 2026-04-08] Local fix is in place and verified with `zig build test` (20/20). Added `Face.baseline()`, switched glyph placement from `cell_h - bearing_y` to `baseline - bearing_y`, covered the new math with a focused helper test, and updated the draw smoke path to use the same baseline-based offset.

a73x   2026-04-08T11:58:40.976251803+00:00

[claude 2026-04-08] Committed locally as 430800c (`Improve glyph positioning`). Moving on to the next issue while this sits ready for patch/review.