fix(ui): honour newlines in message text instead of overdrawing lines

A message containing a line break drew two words on top of each other in
the fullscreen reader. wrapLines() treated '\n' as an ordinary character:
it measured it via getCodepointWidth() -- which reports a full 6px cell
for it, since 0x0A sits below the font's first glyph -- and copied it into
the wrapped line. Both display drivers' print() then acts on '\n' by
resetting the cursor to x=0 and stepping down one row, so the tail of that
line was drawn straight over the following one.

wrapLines() now ends the line at '\n'/'\r' (CRLF counts as one break) and
consumes the byte rather than emitting it, preserving blank lines the
sender typed while still skipping degenerate empty wrap segments so the
loop can't stall. This covers the fullscreen view and the history list's
portrait bubbles, which share the function.

drawTextEllipsized() folds newlines into spaces for the same reason: it
draws one line clipped to max_width, and the compact one-line message
previews in the landscape list feed it raw message bodies. A space keeps
the words apart and measures the same, so the ellipsis maths is unchanged;
for names and labels it's a no-op.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-07-28 13:54:34 +02:00
co-authored by Claude Opus 5
parent 07c80cd548
commit b36cc7730b
3 changed files with 32 additions and 7 deletions
+9 -1
View File
@@ -324,7 +324,15 @@ public:
virtual void drawTextEllipsized(int x, int y, int max_width, const char* str) {
char temp_str[256]; // reasonable buffer size
translateUTF8ToBlocks(temp_str, str, sizeof(temp_str));
// Fold newlines into spaces: this draws ONE line clipped to max_width, but
// print() acts on '\n' by returning to x=0 one row down, which would spill
// the tail onto whatever is drawn below. Message bodies (the compact
// one-line previews in the history list) are the texts that carry them;
// for labels and names this is a no-op. A space keeps the words apart and
// measures the same, so the width/ellipsis maths below is unaffected.
for (char* q = temp_str; *q; q++) if (*q == '\n' || *q == '\r') *q = ' ';
if (getTextWidth(temp_str) <= max_width) {
setCursor(x, y);
print(temp_str);