mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-07-26 10:38:52 +00:00
Fix text color multiline handling (#3161)
This commit is contained in:
@@ -393,27 +393,56 @@ void Text::getAccessibilityText(std::string& result) {
|
||||
void Text::getWidgetName(std::string& result) {
|
||||
result = "Text";
|
||||
}
|
||||
|
||||
void Text::paint(Painter& painter) {
|
||||
const auto rect = screen_rect();
|
||||
auto s = has_focus() ? style().invert() : style();
|
||||
painter.fill_rectangle(rect, s.background);
|
||||
const int char_width = s.font.char_width();
|
||||
const int line_height = s.font.line_height();
|
||||
auto default_style = has_focus() ? style().invert() : style();
|
||||
painter.fill_rectangle(rect, default_style.background);
|
||||
const int char_width = default_style.font.char_width();
|
||||
const int line_height = default_style.font.line_height();
|
||||
if (char_width == 0 || line_height == 0) return;
|
||||
const size_t chars_per_line = rect.width() / char_width;
|
||||
if (chars_per_line == 0) return;
|
||||
size_t lines_capacity = rect.height() / line_height;
|
||||
if (lines_capacity == 0) lines_capacity = 1; // at least one line, even if it overflows vertically
|
||||
if (lines_capacity == 0) lines_capacity = 1;
|
||||
auto text_view = std::string_view{text};
|
||||
size_t current_offset = 0;
|
||||
// Track the active text color across line breaks
|
||||
Color active_color = default_style.foreground;
|
||||
for (size_t line_idx = 0; line_idx < lines_capacity; ++line_idx) {
|
||||
if (current_offset >= text_view.length()) break;
|
||||
size_t chunk_len = std::min(chars_per_line, text_view.length() - current_offset);
|
||||
size_t scan_offset = current_offset;
|
||||
size_t printable_count = 0;
|
||||
Color next_color = active_color; // This will hold the color state as we scan the current chunk
|
||||
// Scan forward to find chunk length AND track color changes
|
||||
while (scan_offset < text_view.length() && printable_count < chars_per_line) {
|
||||
if (text_view[scan_offset] == '\x1B') {
|
||||
scan_offset++;
|
||||
if (scan_offset < text_view.length()) {
|
||||
uint8_t color_idx = text_view[scan_offset];
|
||||
// Mirror the logic from Painter::draw_string
|
||||
if (color_idx < std::size(term_colors)) {
|
||||
next_color = term_colors[color_idx];
|
||||
} else {
|
||||
next_color = active_color;
|
||||
}
|
||||
scan_offset++;
|
||||
}
|
||||
} else {
|
||||
scan_offset++;
|
||||
printable_count++;
|
||||
}
|
||||
}
|
||||
size_t chunk_len = scan_offset - current_offset;
|
||||
// Create a temporary style for this line, initialized with the carried-over color
|
||||
Style line_style = {.font = default_style.font, .background = default_style.background, .foreground = active_color};
|
||||
painter.draw_string(
|
||||
rect.location() + Point(0, line_idx * line_height),
|
||||
s,
|
||||
line_style,
|
||||
text_view.substr(current_offset, chunk_len));
|
||||
current_offset += chunk_len;
|
||||
// Carry the final color state of this line into the start of the next line
|
||||
active_color = next_color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user