perf(font): cache per-codepoint advances in font units (#57) #92
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Catcrafts/Crafter.Graphics!92
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "claude/issue-57"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Font::GetLineWidthcalledstbtt_GetCodepointHMetricsfor every glyph on every call, with no caching.InputField_HitTestCursorrescans the whole field once per character, so caret hit-testing is O(n²) in HMetrics lookups — duplicating the advance work the FontAtlas already pays inEnsureAndGet.Fix
Per-
Fontcodepoint → advance cache (Font::AdvanceUnits): ASCII in a flat 128-entry array (the common caret path), everything else in a map.Correctness: advances are cached in unscaled font units and rescaled per call.
Glyph::advancein the FontAtlas is baked atkBaseSizeand is wrong at any otherfontSize, so it cannot be reused — the cache stores units and multiplies byScaleForPixelHeight(size)per call. The per-glyph(int)truncation inGetLineWidthis preserved exactly.Tests
New CPU-only
FontAdvanceCacheregression test (no Vulkan device —Fontonly touches stb_truetype):AdvanceUnitsis size-independent (proves units, not pixels, are stored)GetLineWidth== sum of per-glyph(int)(units * scale)at every sizecrafter-build test→ 8 passed (run with--jobs=1; the parallel run hits a pre-existing concurrent-git pullrace on the shared Vulkan-Headers external-dep cache, unrelated to this change).Resolves #57