Separate out state for new_frame() into a local variable

This commit is contained in:
Keith Winstein
2011-02-10 20:11:17 -05:00
parent 61251bf0bf
commit 0fb343292a
2 changed files with 57 additions and 48 deletions
+45 -43
View File
@@ -8,26 +8,27 @@ using namespace Terminal;
std::string Display::new_frame( Framebuffer &f ) std::string Display::new_frame( Framebuffer &f )
{ {
FrameState frame;
/* fill in background color on any cells that have been reset /* fill in background color on any cells that have been reset
or created since last time */ or created since last time */
f.back_color_erase(); f.back_color_erase();
str.clear();
char tmp[ 64 ]; char tmp[ 64 ];
/* has window title changed? */ /* has window title changed? */
if ( (!initialized) if ( (!initialized)
|| (f.get_window_title() != last_frame.get_window_title()) ) { || (f.get_window_title() != last_frame.get_window_title()) ) {
/* set window title */ /* set window title */
str.append( "\033]0;[rtm] " ); frame.append( "\033]0;[rtm] " );
std::vector<wchar_t> window_title = f.get_window_title(); std::vector<wchar_t> window_title = f.get_window_title();
for ( std::vector<wchar_t>::iterator i = window_title.begin(); for ( std::vector<wchar_t>::iterator i = window_title.begin();
i != window_title.end(); i != window_title.end();
i++ ) { i++ ) {
snprintf( tmp, 64, "%lc", *i ); snprintf( tmp, 64, "%lc", *i );
str.append( tmp ); frame.append( tmp );
} }
str.append( "\033\\" ); frame.append( "\033\\" );
} }
/* has reverse video state changed? */ /* has reverse video state changed? */
@@ -35,7 +36,7 @@ std::string Display::new_frame( Framebuffer &f )
|| (f.ds.reverse_video != last_frame.ds.reverse_video) ) { || (f.ds.reverse_video != last_frame.ds.reverse_video) ) {
/* set reverse video */ /* set reverse video */
snprintf( tmp, 64, "\033[?5%c", (f.ds.reverse_video ? 'h' : 'l') ); snprintf( tmp, 64, "\033[?5%c", (f.ds.reverse_video ? 'h' : 'l') );
str.append( tmp ); frame.append( tmp );
} }
/* has size changed? */ /* has size changed? */
@@ -43,27 +44,28 @@ std::string Display::new_frame( Framebuffer &f )
|| (f.ds.get_width() != last_frame.ds.get_width()) || (f.ds.get_width() != last_frame.ds.get_width())
|| (f.ds.get_height() != last_frame.ds.get_height()) ) { || (f.ds.get_height() != last_frame.ds.get_height()) ) {
/* clear screen */ /* clear screen */
str.append( "\033[0m\033[H\033[2J" ); frame.append( "\033[0m\033[H\033[2J" );
initialized = false; initialized = false;
cursor_x = cursor_y = 0; cursor_x = cursor_y = 0;
current_rendition_string = "\033[0m"; current_rendition_string = "\033[0m";
} }
/* iterate for every cell */ /* iterate for every cell */
for ( y = 0; y < f.ds.get_height(); y++ ) { for ( frame.y = 0; frame.y < f.ds.get_height(); frame.y++ ) {
int last_x = 0; int last_x = 0;
for ( x = 0; x < f.ds.get_width(); /* let charwidth handle advance */ ) { for ( frame.x = 0;
last_x = x; frame.x < f.ds.get_width(); /* let put_cell() handle advance */ ) {
put_cell( f ); last_x = frame.x;
put_cell( frame, f );
/* To hint that a word-select should group the end of one line /* To hint that a word-select should group the end of one line
with the beginning of the next, we let the real cursor with the beginning of the next, we let the real cursor
actually wrap around in cases where it wrapped around for us. */ actually wrap around in cases where it wrapped around for us. */
if ( (cursor_x >= f.ds.get_width()) if ( (cursor_x >= f.ds.get_width())
&& (y < f.ds.get_height() - 1) && (frame.y < f.ds.get_height() - 1)
&& f.get_row( y )->wrap && f.get_row( frame.y )->wrap
&& (!initialized || !last_frame.get_row( y )->wrap) ) { && (!initialized || !last_frame.get_row( frame.y )->wrap) ) {
/* next write will wrap */ /* next write will wrap */
cursor_x = 0; cursor_x = 0;
cursor_y++; cursor_y++;
@@ -71,17 +73,17 @@ std::string Display::new_frame( Framebuffer &f )
} }
/* Turn off wrap */ /* Turn off wrap */
if ( (y < f.ds.get_height() - 1) if ( (frame.y < f.ds.get_height() - 1)
&& (!f.get_row( y )->wrap) && (!f.get_row( frame.y )->wrap)
&& (!initialized || last_frame.get_row( y )->wrap) ) { && (!initialized || last_frame.get_row( frame.y )->wrap) ) {
x = last_x; frame.x = last_x;
last_frame.get_cell( y, x )->reset(); last_frame.get_cell( frame.y, frame.x )->reset();
snprintf( tmp, 64, "\033[%d;%dH\033[K", y + 1, x + 1 ); snprintf( tmp, 64, "\033[%d;%dH\033[K", frame.y + 1, frame.x + 1 );
str.append( tmp ); frame.append( tmp );
cursor_x = x; cursor_x = frame.x;
put_cell( f ); put_cell( frame, f );
} }
} }
@@ -91,7 +93,7 @@ std::string Display::new_frame( Framebuffer &f )
|| (f.ds.get_cursor_col() != cursor_x) ) { || (f.ds.get_cursor_col() != cursor_x) ) {
snprintf( tmp, 64, "\033[%d;%dH", f.ds.get_cursor_row() + 1, snprintf( tmp, 64, "\033[%d;%dH", f.ds.get_cursor_row() + 1,
f.ds.get_cursor_col() + 1 ); f.ds.get_cursor_col() + 1 );
str.append( tmp ); frame.append( tmp );
cursor_x = f.ds.get_cursor_col(); cursor_x = f.ds.get_cursor_col();
cursor_y = f.ds.get_cursor_row(); cursor_y = f.ds.get_cursor_row();
} }
@@ -100,51 +102,51 @@ std::string Display::new_frame( Framebuffer &f )
if ( (!initialized) if ( (!initialized)
|| (f.ds.cursor_visible != last_frame.ds.cursor_visible) ) { || (f.ds.cursor_visible != last_frame.ds.cursor_visible) ) {
if ( f.ds.cursor_visible ) { if ( f.ds.cursor_visible ) {
str.append( "\033[?25h" ); frame.append( "\033[?25h" );
} else { } else {
str.append( "\033[?25l" ); frame.append( "\033[?25l" );
} }
} }
last_frame = f; last_frame = f;
initialized = true; initialized = true;
return str; return frame.str;
} }
void Display::put_cell( Framebuffer &f ) void Display::put_cell( FrameState &frame, Framebuffer &f )
{ {
char tmp[ 64 ]; char tmp[ 64 ];
Cell *cell = f.get_cell( y, x ); Cell *cell = f.get_cell( frame.y, frame.x );
Cell *last_cell = last_frame.get_cell( y, x ); Cell *last_cell = last_frame.get_cell( frame.y, frame.x );
if ( initialized if ( initialized
&& ( *cell == *last_cell ) ) { && ( *cell == *last_cell ) ) {
x += cell->width; frame.x += cell->width;
return; return;
} }
if ( (x != cursor_x) || (y != cursor_y) ) { if ( (frame.x != cursor_x) || (frame.y != cursor_y) ) {
snprintf( tmp, 64, "\033[%d;%dH", y + 1, x + 1 ); snprintf( tmp, 64, "\033[%d;%dH", frame.y + 1, frame.x + 1 );
str.append( tmp ); frame.append( tmp );
cursor_x = x; cursor_x = frame.x;
cursor_y = y; cursor_y = frame.y;
} }
std::string rendition_str = cell->renditions.sgr(); std::string rendition_str = cell->renditions.sgr();
if ( current_rendition_string != rendition_str ) { if ( current_rendition_string != rendition_str ) {
/* print renditions */ /* print renditions */
str.append( rendition_str ); frame.append( rendition_str );
current_rendition_string = rendition_str; current_rendition_string = rendition_str;
} }
if ( cell->contents.empty() ) { if ( cell->contents.empty() ) {
/* see how far we can stretch a clear */ /* see how far we can stretch a clear */
int clear_count = 0; int clear_count = 0;
for ( int col = x; col < f.ds.get_width(); col++ ) { for ( int col = frame.x; col < f.ds.get_width(); col++ ) {
Cell *other_cell = f.get_cell( y, col ); Cell *other_cell = f.get_cell( frame.y, col );
if ( (cell->renditions == other_cell->renditions) if ( (cell->renditions == other_cell->renditions)
&& (other_cell->contents.empty()) ) { && (other_cell->contents.empty()) ) {
clear_count++; clear_count++;
@@ -153,25 +155,25 @@ void Display::put_cell( Framebuffer &f )
} }
} }
snprintf( tmp, 64, "\033[%dX", clear_count ); snprintf( tmp, 64, "\033[%dX", clear_count );
str.append( tmp ); frame.append( tmp );
x += clear_count; frame.x += clear_count;
return; return;
} }
/* cells that begin with combining character get combiner attached to no-break space */ /* cells that begin with combining character get combiner attached to no-break space */
if ( cell->fallback ) { if ( cell->fallback ) {
snprintf( tmp, 64, "%lc", 0xA0 ); snprintf( tmp, 64, "%lc", 0xA0 );
str.append( tmp ); frame.append( tmp );
} }
for ( std::vector<wchar_t>::iterator i = cell->contents.begin(); for ( std::vector<wchar_t>::iterator i = cell->contents.begin();
i != cell->contents.end(); i != cell->contents.end();
i++ ) { i++ ) {
snprintf( tmp, 64, "%lc", *i ); snprintf( tmp, 64, "%lc", *i );
str.append( tmp ); frame.append( tmp );
} }
x += cell->width; frame.x += cell->width;
cursor_x += cell->width; cursor_x += cell->width;
} }
+12 -5
View File
@@ -4,22 +4,29 @@
#include "terminalframebuffer.hpp" #include "terminalframebuffer.hpp"
namespace Terminal { namespace Terminal {
/* variables used within a new_frame */
class FrameState {
public:
int x, y;
std::string str;
FrameState() : x(0), y(0), str() {}
void append( std::string s ) { str.append( s ); }
};
class Display { class Display {
private: private:
bool initialized; bool initialized;
Framebuffer last_frame; Framebuffer last_frame;
std::string current_rendition_string; std::string current_rendition_string;
int cursor_x, cursor_y; int cursor_x, cursor_y;
int x, y;
std::string str;
void put_cell( Framebuffer &f ); void put_cell( FrameState &frame, Framebuffer &f );
public: public:
Display( int width, int height ) Display( int width, int height )
: initialized( false ), last_frame( width, height ), : initialized( false ), last_frame( width, height ),
current_rendition_string(), cursor_x( -1 ), cursor_y( -1 ), current_rendition_string(), cursor_x( -1 ), cursor_y( -1 )
x( 0 ), y( 0 ), str( "" )
{} {}
std::string new_frame( Framebuffer &f ); std::string new_frame( Framebuffer &f );