Reduce amount of SGR escapes emitted by tracking the active face
This commit is contained in:
parent
63310370f8
commit
b0dcb07540
|
@ -179,29 +179,53 @@ void TerminalUI::Window::draw(DisplayCoord pos,
|
||||||
lines[(int)pos.line].append({}, size.column - pos.column, default_face);
|
lines[(int)pos.line].append({}, size.column - pos.column, default_face);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TerminalUI::Screen::set_face(const Face& face)
|
||||||
|
{
|
||||||
|
static constexpr int fg_table[]{ 39, 30, 31, 32, 33, 34, 35, 36, 37, 90, 91, 92, 93, 94, 95, 96, 97 };
|
||||||
|
static constexpr int bg_table[]{ 49, 40, 41, 42, 43, 44, 45, 46, 47, 100, 101, 102, 103, 104, 105, 106, 107 };
|
||||||
|
static constexpr int attr_table[]{ 0, 4, 7, 5, 1, 2, 3 };
|
||||||
|
|
||||||
|
auto set_color = [](bool fg, const Color& color, bool join) {
|
||||||
|
if (join)
|
||||||
|
fputs(";", stdout);
|
||||||
|
if (color.isRGB())
|
||||||
|
printf("%d;2;%d;%d;%d", fg ? 38 : 48, color.r, color.g, color.b);
|
||||||
|
else
|
||||||
|
printf("%d", (fg ? fg_table : bg_table)[(int)(char)color.color]);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (m_active_face == face)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fputs("\033[", stdout);
|
||||||
|
bool join = false;
|
||||||
|
if (face.attributes != m_active_face.attributes)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < sizeof(attr_table) / sizeof(int); ++i)
|
||||||
|
{
|
||||||
|
if (face.attributes & (Attribute)(1 << i))
|
||||||
|
printf(";%d", attr_table[i]);
|
||||||
|
}
|
||||||
|
m_active_face = Face{{}, {}, face.attributes};
|
||||||
|
join = true;
|
||||||
|
}
|
||||||
|
if (m_active_face.fg != face.fg)
|
||||||
|
{
|
||||||
|
set_color(true, face.fg, join);
|
||||||
|
join = true;
|
||||||
|
}
|
||||||
|
if (m_active_face.bg != face.bg)
|
||||||
|
set_color(false, face.bg, join);
|
||||||
|
fputs("m", stdout);
|
||||||
|
|
||||||
|
m_active_face = face;
|
||||||
|
}
|
||||||
|
|
||||||
void TerminalUI::Screen::output(bool force)
|
void TerminalUI::Screen::output(bool force)
|
||||||
{
|
{
|
||||||
if (lines.empty())
|
if (lines.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
static constexpr int fg_table[]{ 39, 30, 31, 32, 33, 34, 35, 36, 37, 90, 91, 92, 93, 94, 95, 96, 97 };
|
|
||||||
static constexpr int bg_table[]{ 49, 40, 41, 42, 43, 44, 45, 46, 47, 100, 101, 102, 103, 104, 105, 106, 107 };
|
|
||||||
static constexpr int attr_table[]{ 0, 4, 7, 5, 1, 2, 3 };
|
|
||||||
auto set_color = [](bool fg, const Color& color) {
|
|
||||||
if (color.isRGB())
|
|
||||||
printf(";%d;2;%d;%d;%d", fg ? 38 : 48, color.r, color.g, color.b);
|
|
||||||
else
|
|
||||||
printf(";%d", (fg ? fg_table : bg_table)[(int)(char)color.color]);
|
|
||||||
};
|
|
||||||
|
|
||||||
auto set_attributes = [](const Attribute& attributes) {
|
|
||||||
for (int i = 0; i < sizeof(attr_table) / sizeof(int); ++i)
|
|
||||||
{
|
|
||||||
if (attributes & (Attribute)(1 << i))
|
|
||||||
printf(";%d", attr_table[i]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Change { int keep; int add; int del; };
|
struct Change { int keep; int add; int del; };
|
||||||
Vector<Change> changes{Change{}};
|
Vector<Change> changes{Change{}};
|
||||||
auto new_hashes = lines | transform([](auto& line) { return hash_value(line.atoms); }) | gather<Vector>();
|
auto new_hashes = lines | transform([](auto& line) { return hash_value(line.atoms); }) | gather<Vector>();
|
||||||
|
@ -254,11 +278,7 @@ void TerminalUI::Screen::output(bool force)
|
||||||
printf("\033[%dC", (int)pending_move);
|
printf("\033[%dC", (int)pending_move);
|
||||||
pending_move = 0;
|
pending_move = 0;
|
||||||
}
|
}
|
||||||
fputs("\033[", stdout);
|
set_face(atom.face);
|
||||||
set_attributes(atom.face.attributes);
|
|
||||||
set_color(true, atom.face.fg);
|
|
||||||
set_color(false, atom.face.bg);
|
|
||||||
fputs("m", stdout);
|
|
||||||
fputs(atom.text.c_str(), stdout);
|
fputs(atom.text.c_str(), stdout);
|
||||||
if (atom.skip > 0)
|
if (atom.skip > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -89,7 +89,10 @@ private:
|
||||||
struct Screen : Window
|
struct Screen : Window
|
||||||
{
|
{
|
||||||
void output(bool force);
|
void output(bool force);
|
||||||
|
void set_face(const Face& face);
|
||||||
|
|
||||||
Vector<size_t> hashes;
|
Vector<size_t> hashes;
|
||||||
|
Face m_active_face;
|
||||||
};
|
};
|
||||||
|
|
||||||
Window m_window;
|
Window m_window;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user