perf(ui): memoize the input-field caret prefix width (#128) #146
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!146
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "claude/issue-128"
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
For a focused, caret-visible field,
DrawInputFieldwalked the whole cursor prefix viaFont::GetLineWidthevery frame, even though onlycaretVisible(the blink) changes frame-to-frame.value,cursorPosandfontSizeare stable across the vast majority of frames, so the per-glyph UTF-8 decode + advance accumulation was repeated for no reason. (implementations/Crafter.Graphics-InputField.cpp:151-153)Fix
Memoize the measured prefix width on the
InputField, keyed on(prefix bytes, fontSize). A cheap byte compare of the cached prefix guards the expensiveGetLineWidthcall; on a hit the stored width is reused. The cache members aremutablesinceDrawInputFieldtakesconst InputField&.The absolute
caretXis deliberately not cached — it adds the layout-dependenttextX(rect.x + paddingX) each frame, so cachingcaretXwould hand a relocated field a stale caret. Caching only the width keeps the result correct regardless of where the field is drawn.Tests
Adds
tests/InputFieldCaretCache(registered inproject.cpp, pure CPU —DrawTextno-ops with a null atlas/renderer so only the bg + caret quads are emitted, no Vulkan device needed). It pins:GetLineWidthoracle across many(value, cursorPos, fontSize)states;value(byte-level, not just length),cursorPos, andfontSizechanges;caretVisibletoggle) never moves the caret;caretX, is cached);Full suite green:
24 passed.Resolves #128
🤖 Generated with Claude Code