Speed up back color erase -- no more loop over all cells
This commit is contained in:
+3
-3
@@ -49,7 +49,7 @@ void Emulator::print( Parser::Print *act )
|
||||
if ( fb.ds.auto_wrap_mode
|
||||
&& (chwidth == 2)
|
||||
&& (fb.ds.get_cursor_col() == fb.ds.get_width() - 1) ) {
|
||||
this_cell->reset();
|
||||
fb.reset_cell( this_cell );
|
||||
fb.get_row( -1 )->wrap = false;
|
||||
/* There doesn't seem to be a consistent way to get the
|
||||
downstream terminal emulator to set the wrap-around
|
||||
@@ -67,14 +67,14 @@ void Emulator::print( Parser::Print *act )
|
||||
|
||||
this_cell = fb.get_cell();
|
||||
|
||||
this_cell->reset();
|
||||
fb.reset_cell( this_cell );
|
||||
this_cell->contents.push_back( act->ch );
|
||||
this_cell->width = chwidth;
|
||||
fb.apply_renditions_to_current_cell();
|
||||
|
||||
if ( chwidth == 2 ) { /* erase overlapped cell */
|
||||
if ( fb.ds.get_cursor_col() + 1 < fb.ds.get_width() ) {
|
||||
fb.get_cell( fb.ds.get_cursor_row(), fb.ds.get_cursor_col() + 1 )->reset();
|
||||
fb.reset_cell( fb.get_cell( fb.ds.get_cursor_row(), fb.ds.get_cursor_col() + 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-5
@@ -10,10 +10,6 @@ std::string Display::new_frame( Framebuffer &f )
|
||||
{
|
||||
FrameState frame;
|
||||
|
||||
/* fill in background color on any cells that have been reset
|
||||
or created since last time */
|
||||
f.back_color_erase();
|
||||
|
||||
char tmp[ 64 ];
|
||||
|
||||
/* has window title changed? */
|
||||
@@ -77,7 +73,7 @@ std::string Display::new_frame( Framebuffer &f )
|
||||
&& (!f.get_row( frame.y )->wrap)
|
||||
&& (!initialized || last_frame.get_row( frame.y )->wrap) ) {
|
||||
frame.x = last_x;
|
||||
last_frame.get_cell( frame.y, frame.x )->reset();
|
||||
last_frame.reset_cell( last_frame.get_cell( frame.y, frame.x ) );
|
||||
|
||||
snprintf( tmp, 64, "\033[%d;%dH\033[K", frame.y + 1, frame.x + 1 );
|
||||
frame.append( tmp );
|
||||
|
||||
+23
-37
@@ -4,12 +4,12 @@
|
||||
|
||||
using namespace Terminal;
|
||||
|
||||
void Cell::reset( void )
|
||||
void Cell::reset( int background_color )
|
||||
{
|
||||
contents.clear();
|
||||
fallback = false;
|
||||
width = 1;
|
||||
renditions = Renditions();
|
||||
renditions = Renditions( background_color );
|
||||
}
|
||||
|
||||
DrawState::DrawState( int s_width, int s_height )
|
||||
@@ -17,7 +17,7 @@ DrawState::DrawState( int s_width, int s_height )
|
||||
cursor_col( 0 ), cursor_row( 0 ),
|
||||
combining_char_col( 0 ), combining_char_row( 0 ), tabs( s_width ),
|
||||
scrolling_region_top_row( 0 ), scrolling_region_bottom_row( height - 1 ),
|
||||
renditions(), save(),
|
||||
renditions( 0 ), save(),
|
||||
next_print_will_wrap( false ), origin_mode( false ), auto_wrap_mode( true ),
|
||||
insert_mode( false ), cursor_visible( true ), reverse_video( false ),
|
||||
application_mode_cursor_keys( false )
|
||||
@@ -28,7 +28,7 @@ DrawState::DrawState( int s_width, int s_height )
|
||||
}
|
||||
|
||||
Framebuffer::Framebuffer( int s_width, int s_height )
|
||||
: rows( s_height, Row( s_width ) ), window_title(), ds( s_width, s_height )
|
||||
: rows( s_height, Row( s_width, 0 ) ), window_title(), ds( s_width, s_height )
|
||||
{
|
||||
assert( s_height > 0 );
|
||||
assert( s_width > 0 );
|
||||
@@ -45,7 +45,7 @@ void Framebuffer::scroll( int N )
|
||||
N = -N;
|
||||
|
||||
for ( int i = 0; i < N; i++ ) {
|
||||
rows.insert( rows.begin() + ds.get_scrolling_region_top_row(), Row( ds.get_width() ) );
|
||||
rows.insert( rows.begin() + ds.get_scrolling_region_top_row(), newrow() );
|
||||
rows.erase( rows.begin() + ds.get_scrolling_region_bottom_row() + 1 );
|
||||
ds.move_row( 1, true );
|
||||
}
|
||||
@@ -204,7 +204,7 @@ void Framebuffer::apply_renditions_to_current_cell( void )
|
||||
|
||||
SavedCursor::SavedCursor()
|
||||
: cursor_col( 0 ), cursor_row( 0 ),
|
||||
renditions(),
|
||||
renditions( 0 ),
|
||||
auto_wrap_mode( true ),
|
||||
origin_mode( false )
|
||||
{}
|
||||
@@ -237,7 +237,7 @@ void Framebuffer::insert_line( int before_row )
|
||||
return;
|
||||
}
|
||||
|
||||
rows.insert( rows.begin() + before_row, Row( ds.get_width() ) );
|
||||
rows.insert( rows.begin() + before_row, newrow() );
|
||||
rows.erase( rows.begin() + ds.get_scrolling_region_bottom_row() + 1 );
|
||||
}
|
||||
|
||||
@@ -250,42 +250,42 @@ void Framebuffer::delete_line( int row )
|
||||
|
||||
int insertbefore = ds.get_scrolling_region_bottom_row() + 1;
|
||||
if ( insertbefore == ds.get_height() ) {
|
||||
rows.push_back( Row( ds.get_width() ) );
|
||||
rows.push_back( newrow() );
|
||||
} else {
|
||||
rows.insert( rows.begin() + insertbefore, Row( ds.get_width() ) );
|
||||
rows.insert( rows.begin() + insertbefore, newrow() );
|
||||
}
|
||||
|
||||
rows.erase( rows.begin() + row );
|
||||
}
|
||||
|
||||
void Row::insert_cell( int col )
|
||||
void Row::insert_cell( int col, int background_color )
|
||||
{
|
||||
cells.insert( cells.begin() + col, Cell() );
|
||||
cells.insert( cells.begin() + col, Cell( background_color ) );
|
||||
cells.pop_back();
|
||||
}
|
||||
|
||||
void Row::delete_cell( int col )
|
||||
void Row::delete_cell( int col, int background_color )
|
||||
{
|
||||
cells.push_back( Cell() );
|
||||
cells.push_back( Cell( background_color ) );
|
||||
cells.erase( cells.begin() + col );
|
||||
}
|
||||
|
||||
void Framebuffer::insert_cell( int row, int col )
|
||||
{
|
||||
rows[ row ].insert_cell( col );
|
||||
rows[ row ].insert_cell( col, ds.get_background_rendition() );
|
||||
}
|
||||
|
||||
void Framebuffer::delete_cell( int row, int col )
|
||||
{
|
||||
rows[ row ].delete_cell( col );
|
||||
rows[ row ].delete_cell( col, ds.get_background_rendition() );
|
||||
}
|
||||
|
||||
void Framebuffer::reset( void )
|
||||
{
|
||||
int width = ds.get_width(), height = ds.get_height();
|
||||
rows = std::deque<Row>( height, Row( width ) );
|
||||
window_title.clear();
|
||||
ds = DrawState( width, height );
|
||||
rows = std::deque<Row>( height, newrow() );
|
||||
window_title.clear();
|
||||
}
|
||||
|
||||
void Framebuffer::soft_reset( void )
|
||||
@@ -304,12 +304,12 @@ void Framebuffer::resize( int s_width, int s_height )
|
||||
assert( s_width > 0 );
|
||||
assert( s_height > 0 );
|
||||
|
||||
rows.resize( s_height, Row( ds.get_width() ) );
|
||||
rows.resize( s_height, newrow() );
|
||||
|
||||
for ( std::deque<Row>::iterator i = rows.begin();
|
||||
i != rows.end();
|
||||
i++ ) {
|
||||
(*i).cells.resize( s_width, Cell() );
|
||||
(*i).cells.resize( s_width, Cell( ds.get_background_rendition() ) );
|
||||
}
|
||||
|
||||
ds.resize( s_width, s_height );
|
||||
@@ -342,24 +342,10 @@ void DrawState::resize( int s_width, int s_height )
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::back_color_erase( void )
|
||||
{
|
||||
int bg_color = ds.get_background_rendition();
|
||||
|
||||
for ( int row = 0; row < ds.get_height(); row++ ) {
|
||||
for ( int col = 0; col < ds.get_width(); col++ ) {
|
||||
Cell *cell = get_cell( row, col );
|
||||
if ( cell->renditions.background_color == -1 ) {
|
||||
cell->renditions.background_color = bg_color == -1 ? 0 : bg_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Renditions::Renditions()
|
||||
Renditions::Renditions( int s_background )
|
||||
: bold( false ), underlined( false ), blink( false ),
|
||||
inverse( false ), invisible( false ), foreground_color( 0 ),
|
||||
background_color( -1 )
|
||||
background_color( s_background )
|
||||
{}
|
||||
|
||||
void Renditions::set_rendition( int num )
|
||||
@@ -412,11 +398,11 @@ std::string Renditions::sgr( void )
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Row::reset( void )
|
||||
void Row::reset( int background_color )
|
||||
{
|
||||
for ( std::vector<Cell>::iterator i = cells.begin();
|
||||
i != cells.end();
|
||||
i++ ) {
|
||||
i->reset();
|
||||
i->reset( background_color );
|
||||
}
|
||||
}
|
||||
|
||||
+13
-14
@@ -15,13 +15,9 @@ namespace Terminal {
|
||||
int foreground_color;
|
||||
int background_color;
|
||||
|
||||
Renditions();
|
||||
Renditions( int s_background );
|
||||
void set_rendition( int num );
|
||||
std::string sgr( void );
|
||||
void back_color_erase( int num )
|
||||
{
|
||||
if ( background_color == -1 ) background_color = num;
|
||||
}
|
||||
|
||||
bool operator==( const Renditions &x )
|
||||
{
|
||||
@@ -39,14 +35,14 @@ namespace Terminal {
|
||||
int width;
|
||||
Renditions renditions;
|
||||
|
||||
Cell()
|
||||
Cell( int background_color )
|
||||
: contents(),
|
||||
fallback( false ),
|
||||
width( 1 ),
|
||||
renditions()
|
||||
renditions( background_color )
|
||||
{}
|
||||
|
||||
void reset( void );
|
||||
void reset( int background_color );
|
||||
|
||||
inline bool operator==( const Cell &x )
|
||||
{
|
||||
@@ -62,14 +58,14 @@ namespace Terminal {
|
||||
std::vector<Cell> cells;
|
||||
bool wrap;
|
||||
|
||||
Row( size_t s_width )
|
||||
: cells( s_width ), wrap( false )
|
||||
Row( size_t s_width, int background_color )
|
||||
: cells( s_width, Cell( background_color ) ), wrap( false )
|
||||
{}
|
||||
|
||||
void insert_cell( int col );
|
||||
void delete_cell( int col );
|
||||
void insert_cell( int col, int background_color );
|
||||
void delete_cell( int col, int background_color );
|
||||
|
||||
void reset( void );
|
||||
void reset( int background_color );
|
||||
};
|
||||
|
||||
class SavedCursor {
|
||||
@@ -158,6 +154,8 @@ namespace Terminal {
|
||||
|
||||
void scroll( int N );
|
||||
|
||||
Row newrow( void ) { return Row( ds.get_width(), ds.get_background_rendition() ); }
|
||||
|
||||
public:
|
||||
Framebuffer( int s_width, int s_height );
|
||||
DrawState ds;
|
||||
@@ -202,7 +200,8 @@ namespace Terminal {
|
||||
|
||||
void resize( int s_width, int s_height );
|
||||
|
||||
void back_color_erase( void );
|
||||
void reset_cell( Cell *c ) { c->reset( ds.get_background_rendition() ); }
|
||||
void reset_row( Row *r ) { r->reset( ds.get_background_rendition() ); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+7
-15
@@ -12,7 +12,7 @@ using namespace Terminal;
|
||||
static void clearline( Framebuffer *fb, int row, int start, int end )
|
||||
{
|
||||
for ( int col = start; col <= end; col++ ) {
|
||||
fb->get_cell( row, col )->reset();
|
||||
fb->reset_cell( fb->get_cell( row, col ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ void CSI_EL( Framebuffer *fb, Dispatcher *dispatch )
|
||||
clearline( fb, -1, 0, fb->ds.get_cursor_col() );
|
||||
break;
|
||||
case 2: /* all of line */
|
||||
fb->get_row( -1 )->reset();
|
||||
fb->reset_row( fb->get_row( -1 ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -40,18 +40,18 @@ void CSI_ED( Framebuffer *fb, Dispatcher *dispatch ) {
|
||||
case 0: /* active position to end of screen, inclusive */
|
||||
clearline( fb, -1, fb->ds.get_cursor_col(), fb->ds.get_width() - 1 );
|
||||
for ( int y = fb->ds.get_cursor_row() + 1; y < fb->ds.get_height(); y++ ) {
|
||||
fb->get_row( y )->reset();
|
||||
fb->reset_row( fb->get_row( y ) );
|
||||
}
|
||||
break;
|
||||
case 1: /* start of screen to active position, inclusive */
|
||||
for ( int y = 0; y < fb->ds.get_cursor_row(); y++ ) {
|
||||
fb->get_row( y )->reset();
|
||||
fb->reset_row( fb->get_row( y ) );
|
||||
}
|
||||
clearline( fb, -1, 0, fb->ds.get_cursor_col() );
|
||||
break;
|
||||
case 2: /* entire screen */
|
||||
for ( int y = 0; y < fb->ds.get_height(); y++ ) {
|
||||
fb->get_row( y )->reset();
|
||||
fb->reset_row( fb->get_row( y ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -114,7 +114,7 @@ void Esc_DECALN( Framebuffer *fb, Dispatcher *dispatch __attribute((unused)) )
|
||||
{
|
||||
for ( int y = 0; y < fb->ds.get_height(); y++ ) {
|
||||
for ( int x = 0; x < fb->ds.get_width(); x++ ) {
|
||||
fb->get_cell( y, x )->reset();
|
||||
fb->reset_cell( fb->get_cell( y, x ) );
|
||||
fb->get_cell( y, x )->contents.push_back( L'E' );
|
||||
}
|
||||
}
|
||||
@@ -215,7 +215,7 @@ static bool *get_DEC_mode( int param, Framebuffer *fb ) {
|
||||
fb->ds.move_row( 0 );
|
||||
fb->ds.move_col( 0 );
|
||||
for ( int y = 0; y < fb->ds.get_height(); y++ ) {
|
||||
fb->get_row( y )->reset();
|
||||
fb->reset_row( fb->get_row( y ) );
|
||||
}
|
||||
return NULL;
|
||||
case 5: /* reverse video */
|
||||
@@ -312,16 +312,8 @@ static Function func_Ctrl_BEL( CONTROL, "\x07", Ctrl_BEL );
|
||||
/* select graphics rendition -- e.g., bold, blinking, etc. */
|
||||
void CSI_SGR( Framebuffer *fb, Dispatcher *dispatch )
|
||||
{
|
||||
bool bce = false;
|
||||
|
||||
for ( int i = 0; i < dispatch->param_count(); i++ ) {
|
||||
int rendition = dispatch->getparam( i, 0 );
|
||||
if ( (40 <= rendition) && (rendition <= 49) && (!bce) ) {
|
||||
/* we're changing the background color */
|
||||
fb->back_color_erase();
|
||||
bce = true;
|
||||
}
|
||||
|
||||
fb->ds.add_rendition( rendition );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user