refactor(render): the atlas is a declared fixed-cell grid, and staging checks it

The text pipeline stages a glyph's rect *origin* per instance and carries the
rect's *size* once per draw, so a backend whose glyphs have differing rect sizes
-- a TrueType packing trimmed to ink, which is Task 8's shape -- would have drawn
every glyph at whichever size it happened to be told, with nothing downstream
able to tell. Make that constraint structural rather than documented:

- TextBackend::cell_uv() declares the one cell size, and the contract (an atlas
  is a fixed-cell grid; a proportional face draws its glyphs *into* a uniform
  cell instead of trimming each rect to its ink, and why the pipeline needs it)
  is stated on the atlas accessors.
- glyph_is_cell() is the check; add_text()/set_cell() declare the cell from the
  backend, and the staging path asserts it for every glyph in a debug build.
  A release build draws on with the cell it was told, as before.
- Renderer::flush_text() takes u_glyph_uv from the backend, not from the batch,
  so the draw's one rect size can never come from whichever glyph was staged
  first.
This commit is contained in:
Martino Ferrari committed 2026-09-28 10:09:50 +02:00
1 parent e074f57ddf
commit ffc060d6ca
11 files changed
+364 -43

No files matched your search

+3 -3
View File
@@ -52,9 +52,9 @@ class TextProgram {
/// height -- a cell need not be square).
void set_px_range(Vec2 px) const noexcept;
/// `u_glyph_uv`: the glyph cell's size in the atlas, normalised. It is the
/// rect every staged glyph is read through, so it is one size per draw: a
/// batch stages glyphs from one atlas, and `TextBatch::glyph_cell_uv()` is
/// where it comes from.
/// rect every staged glyph is read through, so it is one size per draw -- and
/// it is the *backend's* (`TextBackend::cell_uv`), never a glyph's, because a
/// draw may stage glyphs whose origins differ even when their size cannot.
void set_glyph_uv(Vec2 uv) const noexcept;
/// `u_tex_size`: atlas size in texels.
void set_texture_size(Vec2 texels) const noexcept;