From 93e69f5b3efec9ddc9198e7bb4d5f06af19bad28 Mon Sep 17 00:00:00 2001 From: Sebastien Helleu Date: Mon, 8 May 2006 13:26:08 +0000 Subject: Fixed UTF-8 display bug with chars using more than one cell on screen (bug #16356) --- src/gui/curses/gui-curses-chat.c | 40 +++++++++++++++++++++++++++------------ src/gui/curses/gui-curses-input.c | 40 ++++++++++++++++++++++++++++----------- 2 files changed, 57 insertions(+), 23 deletions(-) (limited to 'src/gui/curses') diff --git a/src/gui/curses/gui-curses-chat.c b/src/gui/curses/gui-curses-chat.c index 45f73bfc8..e1d8d3e94 100644 --- a/src/gui/curses/gui-curses-chat.c +++ b/src/gui/curses/gui-curses-chat.c @@ -246,10 +246,14 @@ gui_chat_display_new_line (t_gui_window *window, int num_lines, int count, */ char * -gui_chat_word_get_next_char (t_gui_window *window, unsigned char *string, int apply_style) +gui_chat_word_get_next_char (t_gui_window *window, unsigned char *string, + int apply_style, int *width_screen) { - char str_fg[3], str_bg[3]; - int fg, bg, weechat_color; + char str_fg[3], str_bg[3], utf_char[16]; + int fg, bg, weechat_color, char_size; + + if (width_screen) + *width_screen = 0; while (string[0]) { @@ -399,7 +403,16 @@ gui_chat_word_get_next_char (t_gui_window *window, unsigned char *string, int ap if (string[0] < 32) string++; else - return utf8_next_char ((char *)string); + { + char_size = utf8_char_size ((char *) string); + if (width_screen) + { + memcpy (utf_char, string, char_size); + utf_char[char_size] = '\0'; + *width_screen = utf8_width_screen (utf_char); + } + return (char *)string + char_size; + } } } @@ -424,7 +437,7 @@ gui_chat_display_word_raw (t_gui_window *window, char *string) while (string && string[0]) { - next_char = gui_chat_word_get_next_char (window, (unsigned char *)string, 1); + next_char = gui_chat_word_get_next_char (window, (unsigned char *)string, 1, NULL); if (!next_char) return; @@ -447,10 +460,10 @@ gui_chat_display_word_raw (t_gui_window *window, char *string) void gui_chat_display_word (t_gui_window *window, - t_gui_line *line, - char *data, - char *end_offset, - int num_lines, int count, int *lines_displayed, int simulate) + t_gui_line *line, + char *data, + char *end_offset, + int num_lines, int count, int *lines_displayed, int simulate) { char *end_line, saved_char_end, saved_char; int pos_saved_char, chars_to_display, num_displayed; @@ -557,7 +570,7 @@ gui_chat_get_word_info (t_gui_window *window, leading_spaces = 1; while (data && data[0]) { - next_char = gui_chat_word_get_next_char (window, (unsigned char *)data, 0); + next_char = gui_chat_word_get_next_char (window, (unsigned char *)data, 0, NULL); if (next_char) { prev_char = utf8_prev_char (data, next_char); @@ -676,7 +689,9 @@ gui_chat_display_line (t_gui_window *window, t_gui_line *line, int count, saved_char = ptr_data[word_start_offset]; ptr_data[word_start_offset] = '\0'; ptr_style = ptr_data; - while ((ptr_style = gui_chat_word_get_next_char (window, (unsigned char *)ptr_style, 1)) != NULL) + while ((ptr_style = gui_chat_word_get_next_char (window, + (unsigned char *)ptr_style, + 1, NULL)) != NULL) { /* loop until no style/char available */ } @@ -705,7 +720,8 @@ gui_chat_display_line (t_gui_window *window, t_gui_line *line, int count, while (ptr_data && (ptr_data[0] == ' ')) { next_char = gui_chat_word_get_next_char (window, - (unsigned char *)ptr_data, 0); + (unsigned char *)ptr_data, + 0, NULL); if (!next_char) break; prev_char = utf8_prev_char (ptr_data, next_char); diff --git a/src/gui/curses/gui-curses-input.c b/src/gui/curses/gui-curses-input.c index f6ed316f1..54aaa4c2b 100644 --- a/src/gui/curses/gui-curses-input.c +++ b/src/gui/curses/gui-curses-input.c @@ -67,14 +67,14 @@ gui_input_set_color (t_gui_window *window, int irc_color) } /* - * gui_input_get_prompt_length: return input prompt length + * gui_input_get_prompt_length: return input prompt length (displayed on screen) */ int gui_input_get_prompt_length (t_gui_window *window, char *nick) { - char *pos, *modes; - int length, mode_found; + char *pos, saved_char, *modes; + int char_size, length, mode_found; length = 0; pos = cfg_look_input_format; @@ -134,8 +134,12 @@ gui_input_get_prompt_length (t_gui_window *window, char *nick) } break; default: - length++; - pos += utf8_char_size (pos); + char_size = utf8_char_size (pos); + saved_char = pos[char_size]; + pos[char_size] = '\0'; + length += utf8_width_screen (pos); + pos[char_size] = saved_char; + pos += char_size; break; } } @@ -144,6 +148,8 @@ gui_input_get_prompt_length (t_gui_window *window, char *nick) /* * gui_input_draw_prompt: display input prompt + * return: # chars displayed on screen (one UTF-8 char + * may be displayed on more than 1 char on screen) */ void @@ -250,18 +256,23 @@ gui_input_draw_prompt (t_gui_window *window, char *nick) /* * gui_input_draw_text: display text in input buffer, according to color mask + * return: offset for cursor position on screen (one UTF-8 + * char may be displayed on more than 1 char on screen) */ -void +int gui_input_draw_text (t_gui_window *window, int input_width) { char *ptr_start, *ptr_next, saved_char; - int pos_mask, size, last_color, color; + int pos_mask, size, last_color, color, count_cursor, offset_cursor; ptr_start = utf8_add_offset (window->buffer->input_buffer, window->buffer->input_buffer_1st_display); pos_mask = ptr_start - window->buffer->input_buffer; last_color = -1; + count_cursor = window->buffer->input_buffer_pos - + window->buffer->input_buffer_1st_display; + offset_cursor = 0; while ((input_width > 0) && ptr_start && ptr_start[0]) { ptr_next = utf8_next_char (ptr_start); @@ -283,6 +294,11 @@ gui_input_draw_text (t_gui_window *window, int input_width) } last_color = color; wprintw (GUI_CURSES(window)->win_input, "%s", ptr_start); + if (count_cursor > 0) + { + offset_cursor += utf8_width_screen (ptr_start); + count_cursor--; + } ptr_next[0] = saved_char; ptr_start = ptr_next; pos_mask += size; @@ -291,6 +307,7 @@ gui_input_draw_text (t_gui_window *window, int input_width) ptr_start = NULL; input_width--; } + return offset_cursor; } /* @@ -303,7 +320,7 @@ gui_input_draw (t_gui_buffer *buffer, int erase) t_gui_window *ptr_win; char format[32]; char *ptr_nickname; - int prompt_length, display_prompt; + int prompt_length, display_prompt, offset_cursor; t_irc_dcc *dcc_selected; if (!gui_ok) @@ -368,13 +385,14 @@ gui_input_draw (t_gui_buffer *buffer, int erase) gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_input, COLOR_WIN_INPUT); snprintf (format, 32, "%%-%ds", ptr_win->win_width - prompt_length); + offset_cursor = 0; if (ptr_win == gui_current_window) - gui_input_draw_text (ptr_win, ptr_win->win_width - prompt_length); + offset_cursor = gui_input_draw_text (ptr_win, + ptr_win->win_width - prompt_length); else wprintw (GUI_CURSES(ptr_win)->win_input, format, ""); wclrtoeol (GUI_CURSES(ptr_win)->win_input); - ptr_win->win_input_x = prompt_length + - (buffer->input_buffer_pos - buffer->input_buffer_1st_display); + ptr_win->win_input_x = prompt_length + offset_cursor; if (ptr_win == gui_current_window) move (ptr_win->win_y + ptr_win->win_height - 1, ptr_win->win_x + ptr_win->win_input_x); -- cgit v1.2.3