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:
1 parent
e074f57ddf
commit
ffc060d6ca
11 files changed
+364
-43
No files matched your search
@@ -40,6 +40,13 @@ class BitmapFont final : public TextBackend {
|
||||
static constexpr u32 kAtlasRows = 7;
|
||||
static constexpr u32 kAtlasWidth = kAtlasCols * kGlyphPx; ///< 128 texels
|
||||
static constexpr u32 kAtlasHeight = kAtlasRows * kGlyphPx; ///< 56 texels
|
||||
|
||||
/// The atlas cell, normalised: one `kGlyphPx` square of the grid. Every glyph's
|
||||
/// rect is this, and `cell_uv()` reports it -- one number, derived from the same
|
||||
/// two constants `pack_atlas()` packs, so the grid the pipeline draws and the
|
||||
/// grid the ink was written into cannot disagree.
|
||||
static constexpr Vec2 kCellUV{static_cast<f32>(kGlyphPx) / static_cast<f32>(kAtlasWidth),
|
||||
static_cast<f32>(kGlyphPx) / static_cast<f32>(kAtlasHeight)};
|
||||
static_assert(kAtlasCols * kAtlasRows >= kGlyphCount, "atlas too small for the glyph set");
|
||||
|
||||
BitmapFont() noexcept = default;
|
||||
@@ -71,6 +78,9 @@ class BitmapFont final : public TextBackend {
|
||||
/// what a label outside the coverage set should show.
|
||||
const Glyph* glyph(u32 codepoint) const override;
|
||||
|
||||
/// `kCellUV`: the 8x8 cell every glyph occupies.
|
||||
Vec2 cell_uv() const override { return kCellUV; }
|
||||
|
||||
/// The packed atlas, as `TextBackend` sees it: the bytes `atlas_image()`
|
||||
/// returns, `kAtlasWidth` by `kAtlasHeight`, GL_R8-ready. Never null.
|
||||
const u8* atlas_pixels() const override;
|
||||
|
||||
Reference in new issue
Block a user