diff options
author | mongo <mongo@iomega> | 2016-04-13 21:48:13 -0300 |
---|---|---|
committer | mongo <mongo@iomega> | 2016-04-13 21:48:13 -0300 |
commit | c1694653c24cf93f3c99761bb0dbf18669fa31e3 (patch) | |
tree | 24529a830f0523a0dfaa2b63b3df0d052ae3a096 | |
parent | 3f4d8e82fce225cec78f00652b775960e9946942 (diff) |
Various fixes to support full width chars (japanese and chinese alphabets)
-rwxr-xr-x | src.scim2/cmds.c | 1 | ||||
-rwxr-xr-x | src.scim2/cmds.h | 1 | ||||
-rwxr-xr-x | src.scim2/cmds_command.c | 11 | ||||
-rwxr-xr-x | src.scim2/cmds_insert.c | 46 | ||||
-rwxr-xr-x | src.scim2/main.c | 4 | ||||
-rwxr-xr-x | src.scim2/screen.c | 57 | ||||
-rwxr-xr-x | src.scim2/screen.h | 2 | ||||
-rwxr-xr-x | src.scim2/utils/string.h | 3 |
8 files changed, 87 insertions, 38 deletions
diff --git a/src.scim2/cmds.c b/src.scim2/cmds.c index 1deec97..3b46186 100755 --- a/src.scim2/cmds.c +++ b/src.scim2/cmds.c @@ -943,6 +943,7 @@ void insert_or_edit_cell() { inputline[0] = L'\0'; inputline_pos = 0; + real_inputline_pos = 0; chg_mode('.'); clr_header(input_win, 0); diff --git a/src.scim2/cmds.h b/src.scim2/cmds.h index 101c0e9..8819623 100755 --- a/src.scim2/cmds.h +++ b/src.scim2/cmds.h @@ -5,6 +5,7 @@ extern char insert_edit_submode; // insert or edit submode extern WINDOW * main_win; extern wchar_t inputline[BUFFERSIZE]; extern int inputline_pos; +extern int real_inputline_pos; extern struct block * lastcmd_buffer; void ins_in_line(wint_t d); diff --git a/src.scim2/cmds_command.c b/src.scim2/cmds_command.c index 788ea1d..cc6aa83 100755 --- a/src.scim2/cmds_command.c +++ b/src.scim2/cmds_command.c @@ -35,7 +35,9 @@ extern struct dictionary * user_conf_d; wchar_t inputline[BUFFERSIZE]; wchar_t interp_line[BUFFERSIZE]; -int inputline_pos; +int inputline_pos; // This is the position in window. Some chars has 2 chars width + // \-> https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms +int real_inputline_pos; // This is the real position in inputline static wchar_t * valid_commands[] = { L"!", @@ -661,7 +663,10 @@ void do_commandmode(struct block * sb) { void ins_in_line(wint_t d) { //DEBUG //sc_info("3: %d %lc", d, d); - - add_wchar(inputline, (wchar_t) d, inputline_pos++); + int real = get_real_inputline_pos(); + add_wchar(inputline, (wchar_t) d, real); + //add_wchar(inputline, (wchar_t) d, real_inputline_pos); + real_inputline_pos++; + inputline_pos += wcwidth((wchar_t) d); return; } diff --git a/src.scim2/cmds_insert.c b/src.scim2/cmds_insert.c index 6cd2ee2..638abf9 100755 --- a/src.scim2/cmds_insert.c +++ b/src.scim2/cmds_insert.c @@ -3,13 +3,23 @@ #include "screen.h" #include <string.h> #include <wchar.h> -//#include <ctype.h> // for isprint() +#include <stdlib.h> #include "buffer.h" #include "sc.h" // for rescol #include "utils/string.h" #include "marks.h" #include "cmds_visual.h" +// used for wchar_t that has more than 1 column width +int get_real_inputline_pos() { + int pos; + int sum = 0; + for (pos = 0; pos < wcslen(inputline) && sum < inputline_pos; pos++) { + sum += wcwidth(inputline[pos]); + } + return pos; +} + void do_insertmode(struct block * sb) { if (sb->value == ctl('v') ) { // VISUAL SUBMODE @@ -19,21 +29,33 @@ void do_insertmode(struct block * sb) { return; } else if (sb->value == OKEY_LEFT) { // LEFT - if (inputline_pos) inputline_pos--; - show_header(input_win); + if (inputline_pos) { + int l = wcwidth(inputline[real_inputline_pos-1]); + real_inputline_pos--; + inputline_pos -= l; + show_header(input_win); + } } else if (sb->value == OKEY_RIGHT) { // RIGHT - if (inputline_pos < wcslen(inputline)) inputline_pos++; + int max = wcswidth(inputline, wcslen(inputline)); + int l = wcwidth(inputline[real_inputline_pos++]); + if (inputline_pos <= max) inputline_pos += l; show_header(input_win); } else if (sb->value == OKEY_BS) { // BS - if ( ! wcslen(inputline) || ! inputline_pos ) return; - del_wchar(inputline, --inputline_pos); + if ( ! wcslen(inputline) ) return; + + int l = wcwidth(inputline[real_inputline_pos - 1]); + real_inputline_pos--; + del_wchar(inputline, real_inputline_pos); + inputline_pos -= l; + show_header(input_win); } else if (sb->value == OKEY_DEL) { // DEL - if (inputline_pos > wcslen(inputline)) return; - del_wchar(inputline, inputline_pos); + int max = wcswidth(inputline, wcslen(inputline)); + if (inputline_pos > max) return; + del_wchar(inputline, real_inputline_pos); show_header(input_win); } else if (sb->value == OKEY_TAB) { // TAB @@ -44,7 +66,7 @@ void do_insertmode(struct block * sb) { insert_or_edit_cell(); // Write new char !! - } else if ( wcslen(inputline) < (COLS - 14) && sc_isprint(sb->value)) { + } else if ( wcslen(inputline) < (COLS - 16) && sc_isprint(sb->value)) { //DEBUG sc_info("2: %d %lc", sb->value, sb->value); ins_in_line(sb->value); show_header(input_win); @@ -62,9 +84,9 @@ void do_insertmode(struct block * sb) { for(i = 0; i < strlen(cline); i++) ins_in_line(cline[i]); show_header(input_win); - } else { - move(0, rescol + inputline_pos + 1); - show_header(input_win); +// } else { +// move(0, rescol + inputline_pos + 1); +// show_header(input_win); } return; diff --git a/src.scim2/main.c b/src.scim2/main.c index 95d7492..65a37e6 100755 --- a/src.scim2/main.c +++ b/src.scim2/main.c @@ -385,7 +385,7 @@ void signals() { void nopipe(); void winchg(); - //signal(SIGINT, sig_int); // FIXME - sig. Commented to reduce annoyance while testing + signal(SIGINT, sig_int); signal(SIGABRT, sig_abrt); signal(SIGTERM, sig_term); // kill signal(SIGPIPE, nopipe); @@ -398,7 +398,7 @@ void signals() { void sig_int() { - sc_error("Got SIGINT. Press «:q<Enter>» to quit Scim"); + sc_error("Got SIGINT. Press «:q<Enter>» to quit SC-IM"); } diff --git a/src.scim2/screen.c b/src.scim2/screen.c index 1628e80..b86d64f 100755 --- a/src.scim2/screen.c +++ b/src.scim2/screen.c @@ -477,7 +477,7 @@ void show_content(WINDOW * win, int mxrow, int mxcol) { char num [FBUFLEN] = ""; char text[FBUFLEN] = ""; - char out [FBUFLEN] = ""; + wchar_t out [FBUFLEN] = L""; char formated_s[FBUFLEN] = ""; int res = -1; int align = 1; @@ -540,8 +540,8 @@ void show_content(WINDOW * win, int mxrow, int mxcol) { // we print text and number } else { - pad_and_align (text, num, fwidth[col], align, (*p)->pad, out); - mvwprintw(win, row + 1 - offscr_sc_rows - q_row_hidden, c, "%s", out); + pad_and_align(text, num, fwidth[col], align, (*p)->pad, out); + mvwprintw(win, row + 1 - offscr_sc_rows - q_row_hidden, c, "%ls", out); wclrtoeol(win); } @@ -773,50 +773,67 @@ int scstrlen(char * s) { // this function aligns text of a cell (align = 0 center, align = 1 right, align = -1 left) // and adds padding between cells. // returns resulting string to be printed in screen. -void pad_and_align (char * str_value, char * numeric_value, int col_width, int align, int padding, char * str_out) { - int str_len = scstrlen(str_value); - int num_len = scstrlen(numeric_value); - str_out[0] = '\0'; +void pad_and_align (char * str_value, char * numeric_value, int col_width, int align, int padding, wchar_t * str_out) { + int str_len = 0; + int num_len = strlen(numeric_value); + str_out[0] = L'\0'; + + wchar_t wcs_value[BUFFERSIZE] = { L'\0' }; + mbstate_t state; + size_t result; + const char * mbsptr; + mbsptr = str_value; + + + // create wcs string based on multibyte string.. + memset( &state, '\0', sizeof state ); + result = mbsrtowcs(wcs_value, &mbsptr, BUFFERSIZE, &state); + if ( result != (size_t)-1 ) + str_len = wcswidth(wcs_value, wcslen(wcs_value)); // If padding exceedes column width, returns n number of '-' needed to fill column width if (padding >= col_width ) { - sprintf(str_out, "%*s", col_width, ""); + wmemset(str_out + wcslen(str_out), L'#', col_width); return; } // If content exceedes column width, outputs n number of '*' needed to fill column width if (str_len + num_len + padding > col_width ) { - if (padding) sprintf(str_out, "%*s", padding, ""); - memset(str_out + strlen(str_out), '*', col_width - padding); + if (padding) wmemset(str_out + wcslen(str_out), L'#', padding); + wmemset(str_out + wcslen(str_out), L'*', col_width - padding); return; } // padding - if (padding) sprintf(str_out, "%*s", padding, ""); + if (padding) swprintf(str_out, BUFFERSIZE, L"%*ls", padding, L""); // left spaces int left_spaces = 0; if (align == 0 && str_len) { // center align left_spaces = (col_width - padding - str_len) / 2; + if (num_len > left_spaces) left_spaces = col_width - padding - str_len - num_len; } else if (align == 1 && str_len && ! num_len) { // right align left_spaces = col_width - padding - str_len; } - while (left_spaces-- > 0) add_char(str_out, ' ', strlen(str_out)); + while (left_spaces-- > 0) add_wchar(str_out, L' ', wcslen(str_out)); // add text if (align != 1 || ! num_len) - strcat(str_out, str_value); + swprintf(str_out + wcslen(str_out), BUFFERSIZE, L"%s", str_value); // spaces after string value - int spaces = col_width - scstrlen(str_out) - num_len; - while (spaces-- > 0) add_char(str_out, ' ', strlen(str_out)); + int spaces = col_width - padding - str_len - num_len; + if (align == 1) spaces += str_len; + if (align == 0) spaces -= (col_width - padding - str_len) / 2; + while (spaces-- > 0) add_wchar(str_out, L' ', wcslen(str_out)); // add number - int fill_with_number = col_width - scstrlen(str_out); - if (num_len && num_len >= fill_with_number) - strncat(str_out, & numeric_value[num_len - fill_with_number], fill_with_number); - else if (num_len) - strcat(str_out, numeric_value); + int fill_with_number = col_width - str_len - padding; + if (num_len && num_len >= fill_with_number) { + swprintf(str_out + wcslen(str_out), BUFFERSIZE, L"%.*s", fill_with_number, & numeric_value[num_len - fill_with_number]); + } else if (num_len) { + swprintf(str_out + wcslen(str_out), BUFFERSIZE, L"%s", numeric_value); + } return; } diff --git a/src.scim2/screen.h b/src.scim2/screen.h index 50ac0d3..68b0683 100755 --- a/src.scim2/screen.h +++ b/src.scim2/screen.h @@ -16,7 +16,7 @@ void show_sc_row_headings(WINDOW * win, int mxrow); void show_sc_col_headings(WINDOW * win, int mxcol, int mxrow); void show_celldetails(WINDOW * win); -void pad_and_align (char * str_value, char * numeric_value, int col_width, int align, int padding, char * str_out); +void pad_and_align (char * str_value, char * numeric_value, int col_width, int align, int padding, wchar_t * str_out); int get_formated_value(struct ent ** p, int col, char * value); int calc_offscr_sc_rows(); diff --git a/src.scim2/utils/string.h b/src.scim2/utils/string.h index 549595e..10815ad 100755 --- a/src.scim2/utils/string.h +++ b/src.scim2/utils/string.h @@ -1,5 +1,8 @@ #include <wchar.h> +int wcswidth(const wchar_t * s, size_t n); +int wcwidth(const wchar_t wc); + int del_char(char * str, int posicion); int del_wchar(wchar_t * str, int posicion); |