diff --git a/Base/res/terminal-colors/Default.ini b/Base/res/terminal-colors/Default.ini index e5a9b73860..f71538de2f 100644 --- a/Base/res/terminal-colors/Default.ini +++ b/Base/res/terminal-colors/Default.ini @@ -1,7 +1,14 @@ +[Options] +; Specifies whether bold text is displayed using bright colors. +ShowBoldTextAsBright=true + +; Default text and background colors [Primary] Background=#000000 Foreground=#ffffff +; Normal named colors +; These correspond to ANSI colors 0-7. [Normal] Black=#000000 Red=#cc0000 @@ -12,6 +19,8 @@ Magenta=#75507b Cyan=#06989a White=#eeeec +; Bright named colors +; These correspond to ANSI colors 8-15. [Bright] Black=#555753 Red=#ef2929 diff --git a/Userland/Libraries/LibVT/Color.h b/Userland/Libraries/LibVT/Color.h index a180965933..5e8a6b4b94 100644 --- a/Userland/Libraries/LibVT/Color.h +++ b/Userland/Libraries/LibVT/Color.h @@ -83,6 +83,18 @@ public: return m_value.as_named; } + constexpr Color to_bright() const + { + if (is_named()) { + auto numeric_value = static_cast(as_named()); + if (numeric_value < 8) + return Color::named(static_cast(numeric_value + 8)); + return *this; + } else { + return *this; + } + } + constexpr bool operator==(const Color& other) const { if (m_kind != other.kind()) diff --git a/Userland/Libraries/LibVT/Terminal.cpp b/Userland/Libraries/LibVT/Terminal.cpp index e6229857f2..214b979e9b 100644 --- a/Userland/Libraries/LibVT/Terminal.cpp +++ b/Userland/Libraries/LibVT/Terminal.cpp @@ -267,9 +267,7 @@ void Terminal::SGR(Parameters params) case 36: case 37: // Foreground color - if (m_current_state.attribute.flags & Attribute::Bold) - param += 8; - m_current_state.attribute.foreground_color = Color::named((Color::ANSIColor)(param - 30)); + m_current_state.attribute.foreground_color = Color::named(static_cast(param - 30)); break; case 39: // reset foreground @@ -284,14 +282,34 @@ void Terminal::SGR(Parameters params) case 46: case 47: // Background color - if (m_current_state.attribute.flags & Attribute::Bold) - param += 8; - m_current_state.attribute.background_color = Color::named((Color::ANSIColor)(param - 40)); + m_current_state.attribute.background_color = Color::named(static_cast(param - 40)); break; case 49: // reset background m_current_state.attribute.background_color = Attribute::default_background_color; break; + case 90: + case 91: + case 92: + case 93: + case 94: + case 95: + case 96: + case 97: + // Bright foreground color + m_current_state.attribute.foreground_color = Color::named(static_cast(8 + param - 90)); + break; + case 100: + case 101: + case 102: + case 103: + case 104: + case 105: + case 106: + case 107: + // Bright background color + m_current_state.attribute.background_color = Color::named(static_cast(8 + param - 100)); + break; default: dbgln("FIXME: SGR: p: {}", param); } diff --git a/Userland/Libraries/LibVT/TerminalWidget.cpp b/Userland/Libraries/LibVT/TerminalWidget.cpp index f010e8ed69..520855ce6e 100644 --- a/Userland/Libraries/LibVT/TerminalWidget.cpp +++ b/Userland/Libraries/LibVT/TerminalWidget.cpp @@ -277,7 +277,7 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event) if (visual_beep_active) painter.clear_rect(frame_inner_rect(), terminal_color_to_rgb(VT::Color::named(VT::Color::ANSIColor::Red))); else - painter.clear_rect(frame_inner_rect(), terminal_color_to_rgb(VT::Color::named(VT::Color::ANSIColor::Black)).with_alpha(m_opacity)); + painter.clear_rect(frame_inner_rect(), terminal_color_to_rgb(VT::Color::named(VT::Color::ANSIColor::DefaultBackground)).with_alpha(m_opacity)); invalidate_cursor(); int rows_from_history = 0; @@ -334,7 +334,8 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event) auto attribute = line.attribute_at(column); auto character_rect = glyph_rect(visual_row, column); auto cell_rect = character_rect.inflated(0, m_line_spacing); - auto text_color = terminal_color_to_rgb(should_reverse_fill_for_cursor_or_selection ? attribute.effective_background_color() : attribute.effective_foreground_color()); + auto text_color_before_bold_change = should_reverse_fill_for_cursor_or_selection ? attribute.effective_background_color() : attribute.effective_foreground_color(); + auto text_color = terminal_color_to_rgb(m_show_bold_text_as_bright ? text_color_before_bold_change.to_bright() : text_color_before_bold_change); if ((!visual_beep_active && !has_only_one_background_color) || should_reverse_fill_for_cursor_or_selection) painter.clear_rect(cell_rect, terminal_color_to_rgb(should_reverse_fill_for_cursor_or_selection ? attribute.effective_foreground_color() : attribute.effective_background_color())); @@ -360,6 +361,7 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event) if (underline_style == UnderlineStyle::Solid) { if (attribute.href_id == m_active_href_id && m_hovered_href_id == m_active_href_id) text_color = palette().active_link(); + painter.draw_line(cell_rect.bottom_left(), cell_rect.bottom_right(), text_color); } else if (underline_style == UnderlineStyle::Dotted) { auto dotted_line_color = text_color.darkened(0.6f); @@ -398,7 +400,8 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event) && visual_row == row_with_cursor && column == m_terminal.cursor_column(); should_reverse_fill_for_cursor_or_selection |= selection_contains({ first_row_from_history + visual_row, (int)column }); - auto text_color = terminal_color_to_rgb(should_reverse_fill_for_cursor_or_selection ? attribute.effective_background_color() : attribute.effective_foreground_color()); + auto text_color_before_bold_change = should_reverse_fill_for_cursor_or_selection ? attribute.effective_background_color() : attribute.effective_foreground_color(); + auto text_color = terminal_color_to_rgb(m_show_bold_text_as_bright ? text_color_before_bold_change.to_bright() : text_color_before_bold_change); u32 code_point = line.code_point(column); if (code_point == ' ') @@ -1162,6 +1165,8 @@ void TerminalWidget::set_color_scheme(const StringView& name) auto color_config = Core::ConfigFile::open(String::formatted("/res/terminal-colors/{}.ini", name)); + m_show_bold_text_as_bright = color_config->read_bool_entry("Options", "ShowBoldTextAsBright", true); + auto default_background = Gfx::Color::from_string(color_config->read_entry("Primary", "Background")); if (default_background.has_value()) m_default_background_color = default_background.value(); @@ -1196,7 +1201,7 @@ Gfx::IntSize TerminalWidget::widget_size_for_font(const Gfx::Font& font) const }; } -Gfx::Color TerminalWidget::terminal_color_to_rgb(VT::Color color) +constexpr Gfx::Color TerminalWidget::terminal_color_to_rgb(VT::Color color) const { switch (color.kind()) { case VT::Color::Kind::RGB: @@ -1253,5 +1258,4 @@ void TerminalWidget::send_non_user_input(const ReadonlyBytes& bytes) VERIFY_NOT_REACHED(); } } - } diff --git a/Userland/Libraries/LibVT/TerminalWidget.h b/Userland/Libraries/LibVT/TerminalWidget.h index 5d4307e651..73ef382d69 100644 --- a/Userland/Libraries/LibVT/TerminalWidget.h +++ b/Userland/Libraries/LibVT/TerminalWidget.h @@ -89,7 +89,7 @@ public: GUI::Menu& context_menu() { return *m_context_menu; } - Gfx::Color terminal_color_to_rgb(VT::Color); + constexpr Gfx::Color terminal_color_to_rgb(VT::Color) const; void set_font_and_resize_to_fit(const Gfx::Font&); @@ -164,6 +164,7 @@ private: unsigned m_colors[256]; Gfx::Color m_default_foreground_color; Gfx::Color m_default_background_color; + bool m_show_bold_text_as_bright { true }; String m_color_scheme_name;