Support wide characters and combining characters

This commit is contained in:
Keith Winstein
2011-01-22 04:58:01 -05:00
parent d189b2af36
commit cfd279fa25
4 changed files with 37 additions and 11 deletions
-5
View File
@@ -64,11 +64,6 @@ int main( int argc __attribute__((unused)),
if ( child == 0 ) { if ( child == 0 ) {
/* child */ /* child */
if ( chdir( "/" ) < 0 ) {
perror( "chdir" );
exit( 1 );
}
char *my_argv[ 2 ]; char *my_argv[ 2 ];
my_argv[ 0 ] = strdup( "/bin/bash" ); my_argv[ 0 ] = strdup( "/bin/bash" );
assert( my_argv[ 0 ] ); assert( my_argv[ 0 ] );
+34 -5
View File
@@ -38,7 +38,7 @@ Emulator::Emulator( size_t s_width, size_t s_height )
cursor_col( 0 ), cursor_row( 0 ), cursor_col( 0 ), cursor_row( 0 ),
combining_char_col( 0 ), combining_char_row( 0 ), combining_char_col( 0 ), combining_char_row( 0 ),
rows( height, Row( width ) ), rows( height, Row( width ) ),
params(), dispatch_chars(), parsed_params() params(), dispatch_chars(), errors(), parsed_params()
{ {
} }
@@ -126,6 +126,8 @@ void Emulator::print( Parser::Print *act )
int chwidth = act->ch == L'\0' ? -1 : wcwidth( act->ch ); int chwidth = act->ch == L'\0' ? -1 : wcwidth( act->ch );
Cell *this_cell;
switch ( chwidth ) { switch ( chwidth ) {
case 1: /* normal character */ case 1: /* normal character */
case 2: /* wide character */ case 2: /* wide character */
@@ -136,13 +138,39 @@ void Emulator::print( Parser::Print *act )
autoscroll(); autoscroll();
rows[ cursor_row ].cells[ cursor_col ].contents.clear(); this_cell = &rows[ cursor_row ].cells[ cursor_col ];
rows[ cursor_row ].cells[ cursor_col ].contents.push_back( act->ch ); this_cell->contents.clear();
this_cell->contents.push_back( act->ch );
for ( std::vector<Cell *>::iterator i
= this_cell->overlapped_cells.begin();
i != this_cell->overlapped_cells.end();
i++ ) {
**i = Cell();
}
this_cell->overlapped_cells.clear();
newgrapheme(); newgrapheme();
cursor_col++;
if ( cursor_col < width - 1 ) {
Cell *next_cell = &rows[ cursor_row ].cells[ cursor_col + 1 ];
if ( chwidth == 2 ) {
this_cell->overlapped_cells.push_back( next_cell );
next_cell->overlapping_cell = this_cell;
} else {
next_cell->overlapping_cell = NULL;
}
}
cursor_col += chwidth;
break;
case 0: /* combining character */
if ( rows[ combining_char_row ].cells[ combining_char_col ].contents.size() < 16 ) { /* seems like a reasonable limit on combining character */
rows[ combining_char_row ].cells[ combining_char_col ].contents.push_back( act->ch );
}
case -1: /* unprintable character */
break; break;
default: default:
break; assert( false );
} }
} }
@@ -154,6 +182,7 @@ void Emulator::debug_printout( FILE *f )
for ( int x = 0; x < width; x++ ) { for ( int x = 0; x < width; x++ ) {
fprintf( f, "\033[%d;%dH", y + 1, x + 1 ); fprintf( f, "\033[%d;%dH", y + 1, x + 1 );
Cell *cell = &rows[ y ].cells[ x ]; Cell *cell = &rows[ y ].cells[ x ];
if ( cell->overlapping_cell ) continue;
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++ ) {
+2
View File
@@ -46,6 +46,8 @@ namespace Terminal {
std::string params; std::string params;
std::string dispatch_chars; std::string dispatch_chars;
std::string errors;
/* action methods */ /* action methods */
void print( Parser::Print *act ); void print( Parser::Print *act );
void execute( Parser::Execute *act ); void execute( Parser::Execute *act );
+1 -1
View File
@@ -45,7 +45,7 @@ void Emulator::CSI_cursormove( void )
if ( cursor_row < 0 ) cursor_row = 0; if ( cursor_row < 0 ) cursor_row = 0;
if ( cursor_row >= height ) cursor_row = height - 1; if ( cursor_row >= height ) cursor_row = height - 1;
if ( cursor_col < 0 ) cursor_col = 0; if ( cursor_col < 0 ) cursor_col = 0;
if ( cursor_col >= width ) cursor_col = width; if ( cursor_col >= width ) cursor_col = width - 1;
newgrapheme(); newgrapheme();
} }