Changeset 331 for EcnlProtoTool/trunk/prototool/src/libbb/vi.c
- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/prototool/src/libbb/vi.c
r321 r331 210 210 # define Isprint(c) ((unsigned char)(c) >= ' ' && (c) != 0x7f && (unsigned char)(c) != 0x9b) 211 211 #else 212 #define MULTI_BYTE_MULTIPLE 3 212 213 bool Isprint(unsigned char c) 213 214 { … … 228 229 mbc_st--; 229 230 return true; 231 } 232 bool IsMultiByteChar(unsigned char c, int *bytes) 233 { 234 bool ret = false; 235 *bytes = 1; 236 if ((c & 0xE0) == 0xC0) { *bytes = 2; } 237 else if ((c & 0xF0) == 0xE0) { *bytes = 3; } 238 else if ((c & 0xF8) == 0xF0) { *bytes = 4; } 239 else if ((c & 0xFC) == 0xF8) { *bytes = 5; } 240 else if ((c & 0xFE) == 0xFC) { *bytes = 6; } 241 if (*bytes != 1) 242 ret = true; 243 return ret; 230 244 } 231 245 #endif … … 583 597 static int format_edit_status(void); // format file status on status line 584 598 static void redraw(int); // force a full screen refresh 599 #ifndef ENABLE_BASIC_MULTI_CHAR_CODE 585 600 static char* format_line(char* /*, int*/); 601 #else 602 static char* format_line(char* , int*, int*); 603 #endif 586 604 static void refresh(int); // update the terminal from screen[] 587 605 … … 1590 1608 char *tp; 1591 1609 int cnt, ro, co; 1610 #ifdef ENABLE_BASIC_MULTI_CHAR_CODE 1611 int last_code_size = 0; 1612 #endif 1592 1613 1593 1614 beg_cur = begin_line(d); // first char of cur line … … 1654 1675 co += (code_size > 1 ? 2 : code_size); 1655 1676 tp += code_size; 1677 last_code_size = code_size; 1656 1678 #endif 1657 1679 } … … 1674 1696 } 1675 1697 if (co >= columns + offset) { 1698 #ifndef ENABLE_BASIC_MULTI_CHAR_CODE 1676 1699 offset = co - columns + 1; 1700 #else 1701 offset = co - columns + (last_code_size > 1 ? 2 : 1); 1702 #endif 1677 1703 } 1678 1704 // if the first char of the line is a tab, and "dot" is sitting on it … … 1831 1857 break; 1832 1858 if (*p == '\t') { 1859 #ifndef ENABLE_BASIC_MULTI_CHAR_CODE 1833 1860 co = next_tabstop(co); 1861 #else 1862 co += tabstop; 1863 p++; 1864 #endif 1834 1865 } 1835 1866 #ifndef ENABLE_BASIC_MULTI_CHAR_CODE … … 1933 1964 { 1934 1965 int li; 1966 int internal_co = co; 1967 #ifdef ENABLE_BASIC_MULTI_CHAR_CODE 1968 internal_co *= MULTI_BYTE_MULTIPLE; 1969 #endif 1935 1970 1936 1971 free(screen); 1937 screensize = ro * co + 8;1972 screensize = ro * internal_co + 8; 1938 1973 screen = xmalloc(screensize); 1939 1974 // initialize the new screen. assume this will be a empty file. … … 1941 1976 // non-existent text[] lines start with a tilde (~). 1942 1977 for (li = 1; li < ro - 1; li++) { 1943 screen[(li * co) + 0] = '~';1978 screen[(li * internal_co) + 0] = '~'; 1944 1979 } 1945 1980 return screen; … … 3361 3396 } 3362 3397 3398 #ifdef ENABLE_BASIC_MULTI_CHAR_CODE 3399 //----- get screen column number of string --------------------- 3400 int get_view_col_from_bytes(char *st, char bytes, int max_size) 3401 { 3402 char *buf_end = st + max_size; 3403 int tmp_bytes = 0, tmp_total_bytes = 0, view_col = 0; 3404 while (tmp_total_bytes < bytes) { 3405 Utf8_to_Utf16(st, &tmp_bytes); 3406 tmp_total_bytes += tmp_bytes; 3407 view_col += tmp_bytes > 1 ? 2 : 1; 3408 st += tmp_bytes; 3409 if (st >= buf_end) 3410 break; 3411 } 3412 return view_col; 3413 } 3414 //----- get string bytes of screen column ---------------------- 3415 int get_bytes_from_view_col(char *st, int view_col, int max_size) 3416 { 3417 char *buf_end = st + max_size; 3418 int tmp_view_col = 0, bytes = 0, tmp_bytes; 3419 while (tmp_view_col < view_col) { 3420 Utf8_to_Utf16(st, &tmp_bytes); 3421 bytes += tmp_bytes; 3422 tmp_view_col += tmp_bytes > 1 ? 2 : 1; 3423 st += tmp_bytes; 3424 if (st >= buf_end) 3425 break; 3426 } 3427 return bytes; 3428 } 3429 #endif 3430 3363 3431 //----- Format a text[] line into a buffer --------------------- 3432 #ifndef ENABLE_BASIC_MULTI_CHAR_CODE 3364 3433 static char* format_line(char *src /*, int li*/) 3434 #else 3435 static char* format_line(char *src , int *bytes, int *view_co) 3436 #endif 3365 3437 { 3366 3438 unsigned char c; … … 3368 3440 int ofs = offset; 3369 3441 char *dest = scr_out_buf; // [MAX_SCR_COLS + MAX_TABSTOP * 2] 3442 #ifdef ENABLE_BASIC_MULTI_CHAR_CODE 3443 int tmp_bytes, tmp_columns_count, total_bytes = 0, view_columns = 0; 3444 memset(scr_out_buf, 0x00, sizeof(scr_out_buf)); 3445 #endif 3370 3446 3371 3447 c = '~'; // char in col 0 in non-existent lines is '~' 3372 3448 co = 0; 3449 #ifndef ENABLE_BASIC_MULTI_CHAR_CODE 3373 3450 while (co < columns + tabstop) { 3451 #else 3452 while (view_columns < columns + ofs/* + tabstop*/) { 3453 #endif 3374 3454 // have we gone past the end? 3375 3455 if (src < end) { … … 3386 3466 while ((co % tabstop) != (tabstop - 1)) { 3387 3467 dest[co++] = c; 3468 #ifdef ENABLE_BASIC_MULTI_CHAR_CODE 3469 total_bytes++; 3470 view_columns++; 3471 #endif 3388 3472 } 3389 3473 } else { … … 3397 3481 } 3398 3482 dest[co++] = c; 3483 #ifdef ENABLE_BASIC_MULTI_CHAR_CODE 3484 total_bytes++; 3485 view_columns++; 3486 if (IsMultiByteChar(c, &tmp_bytes)) { 3487 if (view_columns + 1 > columns + ofs) { 3488 dest[--co] = ' '; 3489 } 3490 else { 3491 view_columns++; 3492 int i; 3493 for (i = 0; i < tmp_bytes - 1; i++) { 3494 dest[co++] = *src++; 3495 total_bytes++; 3496 } 3497 } 3498 } 3499 #endif 3500 #ifndef ENABLE_BASIC_MULTI_CHAR_CODE 3399 3501 // discard scrolled-off-to-the-left portion, 3400 3502 // in tabstop-sized pieces … … 3404 3506 ofs -= tabstop; 3405 3507 } 3508 #endif 3406 3509 if (src >= end) 3407 3510 break; 3408 3511 } 3512 #ifndef ENABLE_BASIC_MULTI_CHAR_CODE 3409 3513 // check "short line, gigantic offset" case 3410 3514 if (co < ofs) … … 3416 3520 if (co < columns) 3417 3521 memset(&dest[co], ' ', columns - co); 3522 #else 3523 // check "short line, gigantic offset" case 3524 if (view_columns < ofs) 3525 ofs = view_columns; 3526 // discard last scrolled off part 3527 view_columns -= ofs; 3528 tmp_columns_count = 0; 3529 while (tmp_columns_count < ofs) { 3530 IsMultiByteChar(*dest, &tmp_bytes); 3531 dest += tmp_bytes; 3532 total_bytes -= tmp_bytes; 3533 tmp_columns_count += tmp_bytes > 1 ? 2 : 1; 3534 } 3535 // fill the rest with spaces 3536 if (view_columns < columns) { 3537 int ofs_bytes = get_bytes_from_view_col(scr_out_buf, ofs, co); 3538 memset(&dest[co - ofs_bytes], ' ', columns - view_columns); 3539 total_bytes = total_bytes + (columns - view_columns); 3540 } 3541 *bytes = total_bytes; 3542 *view_co = view_columns; 3543 #endif 3418 3544 return dest; 3419 3545 } … … 3430 3556 int li, changed; 3431 3557 char *tp, *sp; // pointer into text[] and screen[] 3558 #ifdef ENABLE_BASIC_MULTI_CHAR_CODE 3559 int bytes, view_co; 3560 #endif 3432 3561 3433 3562 if (ENABLE_FEATURE_VI_WIN_RESIZE IF_FEATURE_VI_ASK_TERMINAL(&& !G.get_rowcol_error) ) { … … 3444 3573 char *out_buf; 3445 3574 // format current text line 3575 #ifndef ENABLE_BASIC_MULTI_CHAR_CODE 3446 3576 out_buf = format_line(tp /*, li*/); 3577 #else 3578 out_buf = format_line(tp , &bytes, &view_co); 3579 #endif 3447 3580 3448 3581 // skip to the end of the current text[] line … … 3456 3589 changed = FALSE; // assume no change 3457 3590 cs = 0; 3591 #ifndef ENABLE_BASIC_MULTI_CHAR_CODE 3458 3592 ce = columns - 1; 3459 3593 int cursor_column = 0; 3460 3594 sp = &screen[li * columns]; // start of screen line 3595 #else 3596 ce = bytes - 1; 3597 int cursor_column = 0; 3598 sp = &screen[li * columns * MULTI_BYTE_MULTIPLE]; // start of screen line 3599 #endif 3461 3600 if (full_screen) { 3462 3601 // force re-draw of every single column from 0 - columns-1 … … 3494 3633 #else 3495 3634 while (ce >= cs) { 3496 int code_size = bs_char_count( sp, ce);3635 int code_size = bs_char_count(out_buf, ce); 3497 3636 if (memcmp(&out_buf[ce], &sp[ce], code_size)) { 3498 3637 changed = TRUE; // mark for redraw … … 3501 3640 ce -= code_size; 3502 3641 } 3642 if (view_co < columns - 1) 3643 ce = bytes; 3503 3644 #endif 3504 3645 // now, cs is index of first diff, and ce is index of last diff … … 3511 3652 3512 3653 // make a sanity check of columns indexes 3654 #ifndef ENABLE_BASIC_MULTI_CHAR_CODE 3513 3655 if (cs < 0) { cs = 0; cursor_column = 0; } 3514 3656 if (ce > columns - 1) ce = columns - 1; 3515 3657 if (cs > ce) { cs = 0; ce = columns - 1; cursor_column = 0; } 3658 #else 3659 if (cs < 0) { cs = 0; cursor_column = 0; } 3660 if (get_view_col_from_bytes(out_buf, ce, (columns * MULTI_BYTE_MULTIPLE)) > columns - 1) 3661 ce = get_bytes_from_view_col(out_buf, columns, (columns * MULTI_BYTE_MULTIPLE)) - 1; 3662 if (cs > ce) { 3663 cs = 0; 3664 ce = get_bytes_from_view_col(out_buf, columns, (columns * MULTI_BYTE_MULTIPLE)) - 1; 3665 cursor_column = 0; 3666 } 3667 #endif 3516 3668 // is there a change between virtual screen and out_buf 3517 3669 if (changed) {
Note:
See TracChangeset
for help on using the changeset viewer.