From 8b42734d0058da7815bf93475445d4371fb38419 Mon Sep 17 00:00:00 2001 From: kay Date: Fri, 28 Aug 2026 19:38:25 +0900 Subject: [PATCH] Fixed underline and strikethrough not being drawn across spaces drawText() splits a line into runs of glyphs and runs of spaces. Glyph runs reach drawGlyph(), which draws the decoration; space runs are handled by a bare fillRect() that paints the background only. An underlined run containing a space is drawn with gaps, so ESC[4mA B C produces three separate underline segments where other terminals produce one. Factored the decoration into Screen::drawDecoration() and called it from both paths, so the y offsets are defined once and the two cannot drift apart again. Co-Authored-By: Claude Opus 5 (1M context) --- src/screen.cpp | 17 +++++++++++++++-- src/screen.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/screen.cpp b/src/screen.cpp index 954ad03..5a708eb 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -276,6 +276,7 @@ void Screen::drawText(u32 x, u32 y, u8 fc, u8 bc, u16 num, u16 *text, bool *dw, if (draw_space) { draw_space = false; fillRect(startx, y, x - startx, FH(1), bc); + drawDecoration(startx, y, x - startx, FH(1), fc, ul, st); } if (!draw_text) { @@ -294,9 +295,22 @@ void Screen::drawText(u32 x, u32 y, u8 fc, u8 bc, u16 num, u16 *text, bool *dw, drawGlyphs(startx, y, fc, bc, startnum - num, starttext, startdw, ul, st, it); } else if (draw_space) { fillRect(startx, y, x - startx, FH(1), bc); + drawDecoration(startx, y, x - startx, FH(1), fc, ul, st); } } +/* + * Underline / strikethrough for one run of cells. Kept in one place so that + * glyph runs and space runs cannot drift apart: drawText() splits a line into + * both kinds, and a space in the middle of an underlined run must still be + * underlined. + */ +void Screen::drawDecoration(u32 x, u32 y, u32 w, u32 h, u8 fc, bool ul, bool st) +{ + if (st) fillRect(x, y + h / 2, w, 1, fc); + if (ul) fillRect(x, y + h - 2, w, 1, fc); +} + void Screen::drawGlyphs(u32 x, u32 y, u8 fc, u8 bc, u16 num, u16 *text, bool *dw, bool ul, bool st, bool it) { for (; num--; text++, dw++) { @@ -393,8 +407,7 @@ void Screen::drawGlyph(u32 x, u32 y, u8 fc, u8 bc, u16 code, bool dw, bool ul, b (this->*draw)(x + mOffsetLeft, y + mOffsetTop, nwidth, fc, bc, pixmap); } - if (st) fillRect(cellx, celly + h / 2, w, 1, fc); // strikethrough - if (ul) fillRect(cellx, celly + h - 2, w, 1, fc); // underline + drawDecoration(cellx, celly, w, h, fc, ul, st); } void Screen::rotateRect(u32 &x, u32 &y, u32 &w, u32 &h) diff --git a/src/screen.h b/src/screen.h index 1cee8e7..cb6e9fa 100644 --- a/src/screen.h +++ b/src/screen.h @@ -102,6 +102,7 @@ public : void eraseMargin(bool top, u16 h); void drawGlyphs(u32 x, u32 y, u8 fc, u8 bc, u16 num, u16 *text, bool *dw, bool ul, bool st, bool it); void drawGlyph(u32 x, u32 y, u8 fc, u8 bc, u16 code, bool dw, bool ul, bool st, bool it); + void drawDecoration(u32 x, u32 y, u32 w, u32 h, u8 fc, bool ul, bool st); void adjustOffset(u32 &x, u32 &y); void initFillDraw();