Merge pull request 'perf(ui): memoize the input-field caret prefix width (#128)' (#146) from claude/issue-128 into master

This commit is contained in:
catbot 2026-06-18 15:30:32 +02:00
commit 9cf972016c
5 changed files with 309 additions and 1 deletions

View file

@ -150,7 +150,21 @@ void Crafter::DrawInputField(UIBuffer& buf, const InputField& f, Rect rect,
if (f.focused && caretVisible && *buf.quadCount < buf.quadCap) {
std::string_view sub(f.value.data(), std::min(f.cursorPos, f.value.size()));
float caretX = textX + (sub.empty() ? 0.0f : static_cast<float>(font.GetLineWidth(sub, fontSize)));
// Memoise the prefix width (issue #128): only the blink changes between
// frames, so re-walking the prefix every frame is wasted work. A byte
// compare of the cached prefix (plus fontSize) is far cheaper than the
// per-glyph UTF-8 decode + advance accumulation GetLineWidth does.
float width;
if (f.caretCacheFontSize_ == fontSize && f.caretCachePrefix_ == sub) {
width = f.caretCacheWidth_;
} else {
width = sub.empty() ? 0.0f
: static_cast<float>(font.GetLineWidth(sub, fontSize));
f.caretCachePrefix_.assign(sub);
f.caretCacheFontSize_ = fontSize;
f.caretCacheWidth_ = width;
}
float caretX = textX + width;
float caretH = fontSize * 1.1f;
float caretY = rect.y + (rect.h - caretH) * 0.5f;
float caretW = std::max(1.0f, fontSize / 16.0f);