@@ -49,40 +49,44 @@ static int CommandScreen_scanAscii(InfoScreen* this, const char* p, size_t total
4949static int CommandScreen_scanWide (InfoScreen * this , const char * p , size_t total , char * line ) {
5050 mbstate_t state ;
5151 memset (& state , 0 , sizeof (state ));
52- int line_cols = 0 ;
53- int line_offset = 0 , line_size = 0 , last_spc_cols = 0 , last_spc_offset = -1 ;
52+ size_t bytes ;
53+ int line_cols = 0 , line_offset = 0 , line_size = 0 , width = 0 ;
54+ int last_spc_cols = -1 , last_spc_offset = -1 ;
5455 for (size_t i = 0 ; i < total ; ) {
5556 assert (line_offset >= 0 && (size_t )line_offset <= total );
56- wchar_t wc ;
57- size_t bytes = mbrtowc (& wc , p + i , total - i , & state );
58- int width = wcwidth (wc );
59- if (p [i ] == ' ' ) {
60- last_spc_offset = line_offset ;
61- last_spc_cols = line_cols ;
62- }
63-
64- if (bytes == (size_t )-1 || bytes == (size_t )-2 ) {
65- wc = L'\xFFFD' ;
66- bytes = 1 ;
57+ unsigned char c = (unsigned char )p [i ];
58+ if (c < 0x80 ) { // skip mbrtowc for ASCII characters
59+ if (c == ' ' ) {
60+ last_spc_offset = line_offset ;
61+ last_spc_cols = line_cols ;
62+ }
63+ bytes = width = 1 ;
64+ line [line_offset ] = c ;
65+ } else {
66+ wchar_t wc ;
67+ bytes = mbrtowc (& wc , p + i , total - i , & state );
68+ width = wcwidth (wc );
69+ if (bytes == (size_t )-1 || bytes == (size_t )-2 || width < 0 ) {
70+ bytes = width = 1 ;
71+ }
72+ memcpy (line + line_offset , p + i , bytes );
6773 }
6874
69- memcpy (line + line_offset , p + i , bytes );
7075 i += bytes ;
7176 line_offset += bytes ;
7277 line_cols += width ;
7378 if (line_cols < COLS ) {
7479 continue ;
7580 }
7681
77- if (last_spc_offset >= 0 ) {
82+ if (last_spc_offset >= 0 ) { // wrap by last space
7883 line_size = last_spc_offset ;
7984 line_cols -= last_spc_cols ;
80- last_spc_offset = -1 ;
81- last_spc_cols = 0 ;
82- } else if (line_cols > COLS ) {
85+ last_spc_offset = last_spc_cols = -1 ;
86+ } else if (line_cols > COLS ) { // wrap current wide char to next line
8387 line_size = line_offset - (int ) bytes ;
8488 line_cols = width ;
85- } else {
89+ } else { // wrap by current character
8690 line_size = line_offset ;
8791 line_cols = 0 ;
8892 }
0 commit comments