DrawInputField re-measured the cursor prefix via Font::GetLineWidth on every frame of a focused field, even though only the blink (caretVisible) changes frame-to-frame — value, cursorPos and fontSize are stable across the vast majority of frames. Cache the measured prefix WIDTH on the InputField, keyed on (prefix bytes, fontSize). A cheap byte compare of the cached prefix guards the expensive per-glyph UTF-8 decode + advance accumulation. The cache is mutable so the const-ref draw fn can refresh it. The absolute caretX is deliberately NOT cached: it adds the layout- dependent textX (rect.x + paddingX) each frame, so caching it would give a relocated field a stale caret. Caching the width keeps that correct. Adds tests/InputFieldCaretCache pinning: the cached caret matches the uncached GetLineWidth oracle across states, a redraw (cache hit) is identical to the miss, the cache invalidates on value/cursorPos/fontSize changes, the blink never moves the caret, and a relocated field shifts the caret by exactly the rect delta. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
607 KiB
607 KiB