mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 21:07:36 +00:00
Kernel+LibVT: Add function for deleting a range of characters
Previously, this was done by telling the client to put a space at each character in the range. This was inefficient, because a large number of function calls took place and incorrect, as the ANSI standard dictates that character attributes should be cleared as well. The newly added `clear_in_line` function solves this issue. It performs just one bounds check when it's called and can be implemented as a pretty tight loop.
This commit is contained in:
parent
8f8fd9c5a8
commit
7419569a2b
7 changed files with 60 additions and 53 deletions
|
@ -32,7 +32,7 @@ void Terminal::clear()
|
|||
{
|
||||
dbgln_if(TERMINAL_DEBUG, "Clear the entire screen");
|
||||
for (size_t i = 0; i < rows(); ++i)
|
||||
active_buffer()[i].clear(Attribute());
|
||||
active_buffer()[i].clear();
|
||||
set_cursor(0, 0);
|
||||
}
|
||||
|
||||
|
@ -559,9 +559,7 @@ void Terminal::ECH(Parameters params)
|
|||
// Clear num characters from the right of the cursor.
|
||||
auto clear_end = min<unsigned>(m_columns, cursor_column() + num - 1);
|
||||
dbgln_if(TERMINAL_DEBUG, "Erase characters {}-{} on line {}", cursor_column(), clear_end, cursor_row());
|
||||
for (unsigned i = cursor_column(); i <= clear_end; ++i) {
|
||||
put_character_at(cursor_row(), i, ' ');
|
||||
}
|
||||
clear_in_line(cursor_row(), cursor_column(), clear_end);
|
||||
}
|
||||
|
||||
void Terminal::EL(Parameters params)
|
||||
|
@ -572,21 +570,15 @@ void Terminal::EL(Parameters params)
|
|||
switch (mode) {
|
||||
case 0:
|
||||
dbgln_if(TERMINAL_DEBUG, "Clear line {} from cursor column ({}) to the end", cursor_row(), cursor_column());
|
||||
for (int i = cursor_column(); i < m_columns; ++i) {
|
||||
put_character_at(cursor_row(), i, ' ');
|
||||
}
|
||||
clear_in_line(cursor_row(), cursor_column(), m_columns - 1);
|
||||
break;
|
||||
case 1:
|
||||
dbgln_if(TERMINAL_DEBUG, "Clear line {} from the start to cursor column ({})", cursor_row(), cursor_column());
|
||||
for (int i = 0; i <= cursor_column(); ++i) {
|
||||
put_character_at(cursor_row(), i, ' ');
|
||||
}
|
||||
clear_in_line(cursor_row(), 0, cursor_column());
|
||||
break;
|
||||
case 2:
|
||||
dbgln_if(TERMINAL_DEBUG, "Clear line {} completely", cursor_row());
|
||||
for (int i = 0; i < m_columns; ++i) {
|
||||
put_character_at(cursor_row(), i, ' ');
|
||||
}
|
||||
clear_in_line(cursor_row(), 0, m_columns - 1);
|
||||
break;
|
||||
default:
|
||||
unimplemented_csi_sequence(params, {}, 'K');
|
||||
|
@ -602,23 +594,15 @@ void Terminal::ED(Parameters params)
|
|||
switch (mode) {
|
||||
case 0:
|
||||
dbgln_if(TERMINAL_DEBUG, "Clear from cursor ({},{}) to end of screen", cursor_row(), cursor_column());
|
||||
for (int i = cursor_column(); i < m_columns; ++i)
|
||||
put_character_at(cursor_row(), i, ' ');
|
||||
for (int row = cursor_row() + 1; row < m_rows; ++row) {
|
||||
for (int column = 0; column < m_columns; ++column) {
|
||||
put_character_at(row, column, ' ');
|
||||
}
|
||||
}
|
||||
clear_in_line(cursor_row(), cursor_column(), m_columns - 1);
|
||||
for (int row = cursor_row() + 1; row < m_rows; ++row)
|
||||
clear_in_line(row, 0, m_columns - 1);
|
||||
break;
|
||||
case 1:
|
||||
dbgln_if(TERMINAL_DEBUG, "Clear from beginning of screen to cursor ({},{})", cursor_row(), cursor_column());
|
||||
for (int i = cursor_column(); i >= 0; --i)
|
||||
put_character_at(cursor_row(), i, ' ');
|
||||
for (int row = cursor_row() - 1; row >= 0; --row) {
|
||||
for (int column = 0; column < m_columns; ++column) {
|
||||
put_character_at(row, column, ' ');
|
||||
}
|
||||
}
|
||||
clear_in_line(cursor_row(), 0, cursor_column());
|
||||
for (int row = cursor_row() - 1; row >= 0; --row)
|
||||
clear_in_line(row, 0, m_columns - 1);
|
||||
break;
|
||||
case 2:
|
||||
clear();
|
||||
|
@ -789,7 +773,7 @@ void Terminal::scroll_up(u16 region_top, u16 region_bottom, size_t count)
|
|||
} else {
|
||||
// The new lines haven't been moved and we don't want to leak memory.
|
||||
for (u16 row = region_bottom + 1 - count; row <= region_bottom; ++row)
|
||||
active_buffer()[row].clear(Attribute());
|
||||
active_buffer()[row].clear();
|
||||
}
|
||||
// Set dirty flag on swapped lines.
|
||||
// The other lines have implicitly been set dirty by being cleared.
|
||||
|
@ -816,7 +800,7 @@ void Terminal::scroll_down(u16 region_top, u16 region_bottom, size_t count)
|
|||
swap(active_buffer().ptr_at(row), active_buffer().ptr_at(row - count));
|
||||
// Clear the 'new' lines at the top.
|
||||
for (u16 row = region_top; row < region_top + count; ++row)
|
||||
active_buffer()[row].clear(Attribute());
|
||||
active_buffer()[row].clear();
|
||||
// Set dirty flag on swapped lines.
|
||||
// The other lines have implicitly been set dirty by being cleared.
|
||||
for (u16 row = region_top + count; row <= region_bottom; ++row)
|
||||
|
@ -835,6 +819,12 @@ void Terminal::put_character_at(unsigned row, unsigned column, u32 code_point)
|
|||
|
||||
m_last_code_point = code_point;
|
||||
}
|
||||
|
||||
void Terminal::clear_in_line(u16 row, u16 first_column, u16 last_column)
|
||||
{
|
||||
VERIFY(row < rows());
|
||||
active_buffer()[row].clear_range(first_column, last_column);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Terminal::set_cursor(unsigned a_row, unsigned a_column, bool skip_debug)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue