Commit Graph
2 Commits
Author SHA1 Message Date
DanSandClaude Opus 5.5 3f13d79ccb perf(ui): memoize the node-status banner ellipsis
While the node-status banner shows, its detail line was fitted every
frame by popping one character at a time and re-measuring the whole
"·  " + detail + "…" string: O(L^2) per frame in the detail length L,
which adds up on the ~1.5 KB Windows crash report. The pop also left a
dangling UTF-8 lead byte before the "…", so a cut in non-ASCII text drew
replacement characters in place of the ellipsis.

- util::textfit::ellipsizeTail builds the same string in O(L + m log m),
  m being the length of the line the cut lands in: ImGui measures
  multi-line text as its widest line, so the old loop could only stop
  inside the first line that overflows on its own. Byte-identical for
  ASCII; the cut now lands on a code-point boundary.
- EllipsisFitCache keeps the result until the detail, budget, font size,
  font (by FontId) or rasterizer density changes, so an unchanged frame
  costs one string compare.
- When ImGui would draw a line wider than the per-line split predicts
  (a malformed byte joined with the following newline, as in CP-1252
  output from the Windows daemon), the old whole-string loop is used for
  that text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 09:50:03 -05:00
DanSandClaude Opus 5.5 8c0a22b7bc fix(ui): cut ellipsis truncation on UTF-8 code-point boundaries
TruncateToWidth, the middle "front...back" ellipsis for addresses, pool
URLs, paths, labels and the status bar, cut at byte offsets: a
multi-byte character at either cut was split into invalid UTF-8 and
drawn as replacement characters (e.g. a translated Cyrillic or CJK
status). It also tried front lengths from n/2 down until one fit,
building and measuring a new string for each: up to O(n^2) per
truncated label per frame.

util::textfit::middleEllipsis keeps the same contract and is
byte-identical for ASCII, but snaps the front cut down and the back cut
up to code-point boundaries, and finds the largest fitting front length
by bisection into one reused buffer: O(log n) measures for single-line
text. Text containing a newline keeps the linear scan, because its
measured width (the widest line) does not grow steadily with the cut.

text_fit.h also gains largestFittingPrefix, a bisection over code-point
boundaries; its first caller is the node-status banner in a following
change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 09:50:03 -05:00