Index: EcnlProtoTool/trunk/prototool/src/libbb/vi.c
===================================================================
--- EcnlProtoTool/trunk/prototool/src/libbb/vi.c	(revision 321)
+++ EcnlProtoTool/trunk/prototool/src/libbb/vi.c	(revision 331)
@@ -210,4 +210,5 @@
 # define Isprint(c) ((unsigned char)(c) >= ' ' && (c) != 0x7f && (unsigned char)(c) != 0x9b)
 #else
+#define MULTI_BYTE_MULTIPLE	3
 bool Isprint(unsigned char c)
 {
@@ -228,4 +229,17 @@
 	mbc_st--;
 	return true;
+}
+bool IsMultiByteChar(unsigned char c, int *bytes)
+{
+	bool ret = false;
+	*bytes = 1;
+	if ((c & 0xE0) == 0xC0) { *bytes = 2; }
+	else if ((c & 0xF0) == 0xE0) { *bytes = 3; }
+	else if ((c & 0xF8) == 0xF0) { *bytes = 4; }
+	else if ((c & 0xFC) == 0xF8) { *bytes = 5; }
+	else if ((c & 0xFE) == 0xFC) { *bytes = 6; }
+	if (*bytes != 1)
+		ret = true;
+	return ret;
 }
 #endif
@@ -583,5 +597,9 @@
 static int format_edit_status(void);	// format file status on status line
 static void redraw(int);	// force a full screen refresh
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 static char* format_line(char* /*, int*/);
+#else
+static char* format_line(char* , int*, int*);
+#endif
 static void refresh(int);	// update the terminal from screen[]
 
@@ -1590,4 +1608,7 @@
 	char *tp;
 	int cnt, ro, co;
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+	int last_code_size = 0;
+#endif
 
 	beg_cur = begin_line(d);	// first char of cur line
@@ -1654,4 +1675,5 @@
 		co += (code_size > 1 ? 2 : code_size);
 		tp += code_size;
+		last_code_size = code_size;
 #endif
 	}
@@ -1674,5 +1696,9 @@
 	}
 	if (co >= columns + offset) {
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 		offset = co - columns + 1;
+#else
+		offset = co - columns + (last_code_size > 1 ? 2 : 1);
+#endif
 	}
 	// if the first char of the line is a tab, and "dot" is sitting on it
@@ -1831,5 +1857,10 @@
 			break;
 		if (*p == '\t') {
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 			co = next_tabstop(co);
+#else
+			co += tabstop;
+			p++;
+#endif
 		}
 #ifndef ENABLE_BASIC_MULTI_CHAR_CODE
@@ -1933,7 +1964,11 @@
 {
 	int li;
+	int internal_co = co;
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+	internal_co *= MULTI_BYTE_MULTIPLE;
+#endif
 
 	free(screen);
-	screensize = ro * co + 8;
+	screensize = ro * internal_co + 8;
 	screen = xmalloc(screensize);
 	// initialize the new screen. assume this will be a empty file.
@@ -1941,5 +1976,5 @@
 	//   non-existent text[] lines start with a tilde (~).
 	for (li = 1; li < ro - 1; li++) {
-		screen[(li * co) + 0] = '~';
+		screen[(li * internal_co) + 0] = '~';
 	}
 	return screen;
@@ -3361,6 +3396,43 @@
 }
 
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+//----- get screen column number of string ---------------------
+int get_view_col_from_bytes(char *st, char bytes, int max_size)
+{
+	char *buf_end = st + max_size;
+	int tmp_bytes = 0, tmp_total_bytes = 0, view_col = 0;
+	while (tmp_total_bytes < bytes) {
+		Utf8_to_Utf16(st, &tmp_bytes);
+		tmp_total_bytes += tmp_bytes;
+		view_col += tmp_bytes > 1 ? 2 : 1;
+		st += tmp_bytes;
+		if (st >= buf_end)
+			break;
+	}
+	return view_col;
+}
+//----- get string bytes of screen column ----------------------
+int get_bytes_from_view_col(char *st, int view_col, int max_size)
+{
+	char *buf_end = st + max_size;
+	int tmp_view_col = 0, bytes = 0, tmp_bytes;
+	while (tmp_view_col < view_col) {
+		Utf8_to_Utf16(st, &tmp_bytes);
+		bytes += tmp_bytes;
+		tmp_view_col += tmp_bytes > 1 ? 2 : 1;
+		st += tmp_bytes;
+		if (st >= buf_end)
+			break;
+	}
+	return bytes;
+}
+#endif
+
 //----- Format a text[] line into a buffer ---------------------
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 static char* format_line(char *src /*, int li*/)
+#else
+static char* format_line(char *src , int *bytes, int *view_co)
+#endif
 {
 	unsigned char c;
@@ -3368,8 +3440,16 @@
 	int ofs = offset;
 	char *dest = scr_out_buf; // [MAX_SCR_COLS + MAX_TABSTOP * 2]
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+	int tmp_bytes, tmp_columns_count, total_bytes = 0, view_columns = 0;
+	memset(scr_out_buf, 0x00, sizeof(scr_out_buf));
+#endif
 
 	c = '~'; // char in col 0 in non-existent lines is '~'
 	co = 0;
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 	while (co < columns + tabstop) {
+#else
+	while (view_columns < columns + ofs/* + tabstop*/) {
+#endif
 		// have we gone past the end?
 		if (src < end) {
@@ -3386,4 +3466,8 @@
 					while ((co % tabstop) != (tabstop - 1)) {
 						dest[co++] = c;
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+						total_bytes++;
+						view_columns++;
+#endif
 					}
 				} else {
@@ -3397,4 +3481,22 @@
 		}
 		dest[co++] = c;
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+		total_bytes++;
+		view_columns++;
+		if (IsMultiByteChar(c, &tmp_bytes)) {
+			if (view_columns + 1 > columns + ofs) {
+				dest[--co] = ' ';
+			}
+			else {
+				view_columns++;
+				int i;
+				for (i = 0; i < tmp_bytes - 1; i++) {
+					dest[co++] = *src++;
+					total_bytes++;
+				}
+			}
+		}
+#endif
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 		// discard scrolled-off-to-the-left portion,
 		// in tabstop-sized pieces
@@ -3404,7 +3506,9 @@
 			ofs -= tabstop;
 		}
+#endif
 		if (src >= end)
 			break;
 	}
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 	// check "short line, gigantic offset" case
 	if (co < ofs)
@@ -3416,4 +3520,26 @@
 	if (co < columns)
 		memset(&dest[co], ' ', columns - co);
+#else
+	// check "short line, gigantic offset" case
+	if (view_columns < ofs)
+		ofs = view_columns;
+	// discard last scrolled off part
+	view_columns -= ofs;
+	tmp_columns_count = 0;
+	while (tmp_columns_count < ofs) {
+		IsMultiByteChar(*dest, &tmp_bytes);
+		dest += tmp_bytes;
+		total_bytes -= tmp_bytes;
+		tmp_columns_count += tmp_bytes > 1 ? 2 : 1;
+	}
+	// fill the rest with spaces
+	if (view_columns < columns) {
+		int ofs_bytes = get_bytes_from_view_col(scr_out_buf, ofs, co);
+		memset(&dest[co - ofs_bytes], ' ', columns - view_columns);
+		total_bytes = total_bytes + (columns - view_columns);
+	}
+	*bytes = total_bytes;
+	*view_co = view_columns;
+#endif
 	return dest;
 }
@@ -3430,4 +3556,7 @@
 	int li, changed;
 	char *tp, *sp;		// pointer into text[] and screen[]
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+	int bytes, view_co;
+#endif
 
 	if (ENABLE_FEATURE_VI_WIN_RESIZE IF_FEATURE_VI_ASK_TERMINAL(&& !G.get_rowcol_error) ) {
@@ -3444,5 +3573,9 @@
 		char *out_buf;
 		// format current text line
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 		out_buf = format_line(tp /*, li*/);
+#else
+		out_buf = format_line(tp , &bytes, &view_co);
+#endif
 
 		// skip to the end of the current text[] line
@@ -3456,7 +3589,13 @@
 		changed = FALSE;	// assume no change
 		cs = 0;
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 		ce = columns - 1;
 		int cursor_column = 0;
 		sp = &screen[li * columns];	// start of screen line
+#else
+		ce = bytes - 1;
+		int cursor_column = 0;
+		sp = &screen[li * columns * MULTI_BYTE_MULTIPLE];	// start of screen line
+#endif
 		if (full_screen) {
 			// force re-draw of every single column from 0 - columns-1
@@ -3494,5 +3633,5 @@
 #else
 		while (ce >= cs) {
-			int code_size = bs_char_count(sp, ce);
+			int code_size = bs_char_count(out_buf, ce);
 			if (memcmp(&out_buf[ce], &sp[ce], code_size)) {
 				changed = TRUE;	// mark for redraw
@@ -3501,4 +3640,6 @@
 			ce -= code_size;
 		}
+		if (view_co < columns - 1)
+			ce = bytes;
 #endif
 		// now, cs is index of first diff, and ce is index of last diff
@@ -3511,7 +3652,18 @@
 
 		// make a sanity check of columns indexes
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 		if (cs < 0) { cs = 0; cursor_column = 0; }
 		if (ce > columns - 1) ce = columns - 1;
 		if (cs > ce) { cs = 0; ce = columns - 1; cursor_column = 0; }
+#else
+		if (cs < 0) { cs = 0; cursor_column = 0; }
+		if (get_view_col_from_bytes(out_buf, ce, (columns * MULTI_BYTE_MULTIPLE)) > columns - 1)
+			ce = get_bytes_from_view_col(out_buf, columns, (columns * MULTI_BYTE_MULTIPLE)) - 1;
+		if (cs > ce) {
+			cs = 0;
+			ce = get_bytes_from_view_col(out_buf, columns, (columns * MULTI_BYTE_MULTIPLE)) - 1;
+			cursor_column = 0;
+		}
+#endif
 		// is there a change between virtual screen and out_buf
 		if (changed) {
