summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormongo <mongo@iomega>2016-04-13 21:48:13 -0300
committermongo <mongo@iomega>2016-04-13 21:48:13 -0300
commitc1694653c24cf93f3c99761bb0dbf18669fa31e3 (patch)
tree24529a830f0523a0dfaa2b63b3df0d052ae3a096
parent3f4d8e82fce225cec78f00652b775960e9946942 (diff)
Various fixes to support full width chars (japanese and chinese alphabets)
-rwxr-xr-xsrc.scim2/cmds.c1
-rwxr-xr-xsrc.scim2/cmds.h1
-rwxr-xr-xsrc.scim2/cmds_command.c11
-rwxr-xr-xsrc.scim2/cmds_insert.c46
-rwxr-xr-xsrc.scim2/main.c4
-rwxr-xr-xsrc.scim2/screen.c57
-rwxr-xr-xsrc.scim2/screen.h2
-rwxr-xr-xsrc.scim2/utils/string.h3
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);