summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
authorAnotherTest <ali.mpfard@gmail.com>2020-05-10 12:11:03 +0430
committerAndreas Kling <kling@serenityos.org>2020-05-10 10:23:05 +0200
commit8487806ec01cd44e808cfc18ca7ee51aaecae533 (patch)
tree977424f79f3b9b82e0e1d4acf936783425d82354 /Libraries
parentccdef5a675e2a16485b530d96cd24f7ea02f17f4 (diff)
downloadserenity-8487806ec01cd44e808cfc18ca7ee51aaecae533.zip
LibVT: Support RGB colors (\x1b[38;2;<r>;<g>;<b>m)
Diffstat (limited to 'Libraries')
-rw-r--r--Libraries/LibVT/Terminal.cpp42
-rw-r--r--Libraries/LibVT/Terminal.h12
-rw-r--r--Libraries/LibVT/TerminalWidget.cpp14
-rw-r--r--Libraries/LibVT/XtermColors.h2
4 files changed, 48 insertions, 22 deletions
diff --git a/Libraries/LibVT/Terminal.cpp b/Libraries/LibVT/Terminal.cpp
index ae6679a392..4770c98032 100644
--- a/Libraries/LibVT/Terminal.cpp
+++ b/Libraries/LibVT/Terminal.cpp
@@ -174,13 +174,37 @@ void Terminal::SGR(const ParamVector& params)
m_current_attribute.reset();
return;
}
- if (params.size() == 3 && params[1] == 5) {
- if (params[0] == 38) {
- m_current_attribute.foreground_color = params[2];
- return;
- } else if (params[0] == 48) {
- m_current_attribute.background_color = params[2];
- return;
+ if (params.size() >= 3) {
+ bool should_set = true;
+ auto kind = params[1];
+ u32 color = 0;
+ switch (kind) {
+ case 5: // 8-bit
+ color = xterm_colors[params[2]];
+ break;
+ case 2: // 24-bit
+ for (size_t i = 0; i < 3; ++i) {
+ u8 component = 0;
+ if (params.size() - 2 > i) {
+ component = params[i + 2];
+ }
+ color <<= 8;
+ color |= component;
+ }
+ break;
+ default:
+ should_set = false;
+ break;
+ }
+
+ if (should_set) {
+ if (params[0] == 38) {
+ m_current_attribute.foreground_color = color;
+ return;
+ } else if (params[0] == 48) {
+ m_current_attribute.background_color = color;
+ return;
+ }
}
}
for (auto param : params) {
@@ -230,7 +254,7 @@ void Terminal::SGR(const ParamVector& params)
// Foreground color
if (m_current_attribute.flags & Attribute::Bold)
param += 8;
- m_current_attribute.foreground_color = param - 30;
+ m_current_attribute.foreground_color = xterm_colors[param - 30];
break;
case 39:
// reset foreground
@@ -247,7 +271,7 @@ void Terminal::SGR(const ParamVector& params)
// Background color
if (m_current_attribute.flags & Attribute::Bold)
param += 8;
- m_current_attribute.background_color = param - 40;
+ m_current_attribute.background_color = xterm_colors[param - 40];
break;
case 49:
// reset background
diff --git a/Libraries/LibVT/Terminal.h b/Libraries/LibVT/Terminal.h
index b73f9cf2f8..85d148e4bc 100644
--- a/Libraries/LibVT/Terminal.h
+++ b/Libraries/LibVT/Terminal.h
@@ -31,12 +31,13 @@
#include <AK/String.h>
#include <AK/Vector.h>
#include <LibVT/Position.h>
+#include <LibVT/XtermColors.h>
namespace VT {
class TerminalClient {
public:
- virtual ~TerminalClient() {}
+ virtual ~TerminalClient() { }
virtual void beep() = 0;
virtual void set_window_title(const StringView&) = 0;
@@ -48,8 +49,8 @@ public:
struct Attribute {
Attribute() { reset(); }
- static const u8 default_foreground_color = 7;
- static const u8 default_background_color = 0;
+ static const u32 default_foreground_color = xterm_colors[7];
+ static const u32 default_background_color = xterm_colors[0];
void reset()
{
@@ -57,8 +58,8 @@ struct Attribute {
background_color = default_background_color;
flags = Flags::NoAttributes;
}
- u8 foreground_color;
- u8 background_color;
+ u32 foreground_color;
+ u32 background_color;
String href;
String href_id;
@@ -110,6 +111,7 @@ public:
struct Line {
AK_MAKE_NONCOPYABLE(Line);
AK_MAKE_NONMOVABLE(Line);
+
public:
explicit Line(u16 columns);
~Line();
diff --git a/Libraries/LibVT/TerminalWidget.cpp b/Libraries/LibVT/TerminalWidget.cpp
index 74d891eeae..6f4eca20e1 100644
--- a/Libraries/LibVT/TerminalWidget.cpp
+++ b/Libraries/LibVT/TerminalWidget.cpp
@@ -146,9 +146,9 @@ TerminalWidget::~TerminalWidget()
{
}
-static inline Color lookup_color(unsigned color)
+static inline Color color_from_rgb(unsigned color)
{
- return Color::from_rgb(xterm_colors[color]);
+ return Color::from_rgb(color);
}
Gfx::Rect TerminalWidget::glyph_rect(u16 row, u16 column)
@@ -349,7 +349,7 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event)
if (m_visual_beep_timer->is_active())
painter.clear_rect(row_rect, Color::Red);
else if (has_only_one_background_color)
- painter.clear_rect(row_rect, lookup_color(line.attributes[0].background_color).with_alpha(m_opacity));
+ painter.clear_rect(row_rect, color_from_rgb(line.attributes[0].background_color).with_alpha(m_opacity));
// The terminal insists on thinking characters and
// bytes are the same thing. We want to still draw
@@ -385,14 +385,14 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event)
auto character_rect = glyph_rect(row, column);
auto cell_rect = character_rect.inflated(0, m_line_spacing);
if (!has_only_one_background_color || should_reverse_fill_for_cursor_or_selection) {
- painter.clear_rect(cell_rect, lookup_color(should_reverse_fill_for_cursor_or_selection ? attribute.foreground_color : attribute.background_color).with_alpha(m_opacity));
+ painter.clear_rect(cell_rect, color_from_rgb(should_reverse_fill_for_cursor_or_selection ? attribute.foreground_color : attribute.background_color).with_alpha(m_opacity));
}
bool should_paint_underline = attribute.flags & VT::Attribute::Underline
|| (!m_hovered_href.is_empty() && m_hovered_href_id == attribute.href_id);
if (should_paint_underline)
- painter.draw_line(cell_rect.bottom_left(), cell_rect.bottom_right(), lookup_color(should_reverse_fill_for_cursor_or_selection ? attribute.background_color : attribute.foreground_color));
+ painter.draw_line(cell_rect.bottom_left(), cell_rect.bottom_right(), color_from_rgb(should_reverse_fill_for_cursor_or_selection ? attribute.background_color : attribute.foreground_color));
}
if (codepoint == ' ')
@@ -405,7 +405,7 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event)
character_rect.location(),
codepoint,
attribute.flags & VT::Attribute::Bold ? bold_font() : font(),
- lookup_color(should_reverse_fill_for_cursor_or_selection ? attribute.background_color : attribute.foreground_color));
+ color_from_rgb(should_reverse_fill_for_cursor_or_selection ? attribute.background_color : attribute.foreground_color));
}
}
@@ -413,7 +413,7 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event)
auto& cursor_line = line_for_visual_row(row_with_cursor);
if (m_terminal.cursor_row() < (m_terminal.rows() - rows_from_history)) {
auto cell_rect = glyph_rect(row_with_cursor, m_terminal.cursor_column()).inflated(0, m_line_spacing);
- painter.draw_rect(cell_rect, lookup_color(cursor_line.attributes[m_terminal.cursor_column()].foreground_color));
+ painter.draw_rect(cell_rect, color_from_rgb(cursor_line.attributes[m_terminal.cursor_column()].foreground_color));
}
}
}
diff --git a/Libraries/LibVT/XtermColors.h b/Libraries/LibVT/XtermColors.h
index 2af29745d2..513fb75292 100644
--- a/Libraries/LibVT/XtermColors.h
+++ b/Libraries/LibVT/XtermColors.h
@@ -26,7 +26,7 @@
#pragma once
-static const unsigned xterm_colors[256] = {
+static constexpr unsigned xterm_colors[256] = {
0x000000,
0xcc0000,
0x3e9a06,