diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/wee-utf8.c | 33 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-bar-window.c | 8 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-chat.c | 72 | ||||
-rw-r--r-- | src/gui/gui-chat.c | 68 | ||||
-rw-r--r-- | src/gui/gui-chat.h | 1 |
5 files changed, 81 insertions, 101 deletions
diff --git a/src/core/wee-utf8.c b/src/core/wee-utf8.c index 6f6526319..c976f7441 100644 --- a/src/core/wee-utf8.c +++ b/src/core/wee-utf8.c @@ -489,18 +489,34 @@ utf8_strnlen (const char *string, int bytes) int utf8_char_size_screen (const char *string) { - int width; + wchar_t codepoint; - if (!string) + if (!string || !string[0]) return 0; if (string[0] == '\t') return CONFIG_INTEGER(config_look_tab_width); - width = wcwidth ((wchar_t)utf8_char_int (string)); + /* + * chars < 32 are displayed with a letter/symbol and reverse video, + * so exactly one column + */ + if (((unsigned char)string[0]) < 32) + return 1; + + codepoint = (wchar_t)utf8_char_int (string); + + /* + * special chars not displayed (because not handled by WeeChat): + * U+00AD: soft hyphen (wcwidth == 1) + * U+200B: zero width space (wcwidth == 0) + */ + if ((codepoint == 0x00AD) || (codepoint == 0x200B)) + { + return -1; + } - /* non printable chars are displayed with a space (so size = 1) */ - return (width >= 0) ? width : 1; + return wcwidth (codepoint); } /* @@ -512,7 +528,7 @@ utf8_char_size_screen (const char *string) int utf8_strlen_screen (const char *string) { - int size_screen; + int size_screen, size_screen_char; const char *ptr_string; if (!string) @@ -525,7 +541,10 @@ utf8_strlen_screen (const char *string) ptr_string = string; while (ptr_string && ptr_string[0]) { - size_screen += utf8_char_size_screen (ptr_string); + size_screen_char = utf8_char_size_screen (ptr_string); + /* count only chars that use at least one column */ + if (size_screen_char > 0) + size_screen += size_screen_char; ptr_string = utf8_next_char (ptr_string); } diff --git a/src/gui/curses/gui-curses-bar-window.c b/src/gui/curses/gui-curses-bar-window.c index 99d64b21b..5d1ea4378 100644 --- a/src/gui/curses/gui-curses-bar-window.c +++ b/src/gui/curses/gui-curses-bar-window.c @@ -361,12 +361,6 @@ gui_bar_window_print_string (struct t_gui_bar_window *bar_window, reverse_video = (gui_window_current_color_attr & A_REVERSE) ? 0 : 1; } - else - { - /* display non printable chars as spaces */ - if (!gui_chat_utf_char_valid (utf_char)) - snprintf (utf_char, sizeof (utf_char), " "); - } while (ptr_char && ptr_char[0]) { @@ -411,8 +405,8 @@ gui_bar_window_print_string (struct t_gui_bar_window *bar_window, *x += size_on_screen; } - ptr_char = utf8_next_char (ptr_char); } + ptr_char = utf8_next_char (ptr_char); } string = utf8_next_char (string); break; diff --git a/src/gui/curses/gui-curses-chat.c b/src/gui/curses/gui-curses-chat.c index e106a43ef..40bc38577 100644 --- a/src/gui/curses/gui-curses-chat.c +++ b/src/gui/curses/gui-curses-chat.c @@ -373,7 +373,8 @@ gui_chat_display_word_raw (struct t_gui_window *window, struct t_gui_line *line, int apply_style_inactive, int nick_offline) { - char *output, utf_char[16], *ptr_char; + const char *ptr_char; + char *output, utf_char[16], utf_char2[16]; int x, chars_displayed, display_char, size_on_screen, reverse_video; if (!simulate) @@ -416,13 +417,6 @@ gui_chat_display_word_raw (struct t_gui_window *window, struct t_gui_line *line, reverse_video = (gui_window_current_color_attr & A_REVERSE) ? 0 : 1; } - else - { - /* display non printable chars as spaces */ - if (!gui_chat_utf_char_valid (utf_char)) - snprintf (utf_char, sizeof (utf_char), " "); - - } display_char = (window->buffer->type != GUI_BUFFER_TYPE_FREE) || (x >= window->scroll->start_col); @@ -433,37 +427,51 @@ gui_chat_display_word_raw (struct t_gui_window *window, struct t_gui_line *line, { return chars_displayed; } - if (display_char && (size_on_screen >= 0)) + + if (display_char) { - if (!simulate) + while (ptr_char && ptr_char[0]) { - output = string_iconv_from_internal (NULL, ptr_char); - if (reverse_video) + utf8_strncpy (utf_char2, ptr_char, 1); + size_on_screen = utf8_char_size_screen (utf_char2); + if (size_on_screen >= 0) { - wattron (GUI_WINDOW_OBJECTS(window)->win_chat, - A_REVERSE); - } - waddstr (GUI_WINDOW_OBJECTS(window)->win_chat, - (output) ? output : ptr_char); - if (reverse_video) - { - wattroff (GUI_WINDOW_OBJECTS(window)->win_chat, - A_REVERSE); - } - if (output) - free (output); + if (!simulate) + { + output = string_iconv_from_internal (NULL, utf_char2); + if (reverse_video) + { + wattron (GUI_WINDOW_OBJECTS(window)->win_chat, + A_REVERSE); + } + waddstr (GUI_WINDOW_OBJECTS(window)->win_chat, + (output) ? output : utf_char2); + if (reverse_video) + { + wattroff (GUI_WINDOW_OBJECTS(window)->win_chat, + A_REVERSE); + } + if (output) + free (output); - if (gui_window_current_emphasis) - { - gui_window_emphasize (GUI_WINDOW_OBJECTS(window)->win_chat, - x - window->scroll->start_col, - window->win_chat_cursor_y, - size_on_screen); + if (gui_window_current_emphasis) + { + gui_window_emphasize (GUI_WINDOW_OBJECTS(window)->win_chat, + x - window->scroll->start_col, + window->win_chat_cursor_y, + size_on_screen); + } + } + chars_displayed += size_on_screen; + x += size_on_screen; } + ptr_char = utf8_next_char (ptr_char); } - chars_displayed += size_on_screen; } - x += size_on_screen; + else + { + x += size_on_screen; + } } string = utf8_next_char (string); diff --git a/src/gui/gui-chat.c b/src/gui/gui-chat.c index f7bc8943f..26d82aaf3 100644 --- a/src/gui/gui-chat.c +++ b/src/gui/gui-chat.c @@ -126,51 +126,6 @@ gui_chat_prefix_build () } /* - * Checks if an UTF-8 char is valid for screen. - * - * Returns: - * 1: char is valid - * 0: char is not valid - */ - -int -gui_chat_utf_char_valid (const char *utf_char) -{ - if (!utf_char) - return 0; - - /* chars below 32 are not valid (except TAB) */ - if (((unsigned char)utf_char[0] < 32) && (utf_char[0] != '\t')) - return 0; - - /* 146 or 0x7F are not valid */ - if ((((unsigned char)(utf_char[0]) == 146) - || ((unsigned char)(utf_char[0]) == 0x7F)) - && (!utf_char[1])) - return 0; - - /* any other char is valid */ - return 1; -} - -/* - * Returns number of char needed on screen to display a char. - */ - -int -gui_chat_char_size_screen (const char *utf_char) -{ - if (!utf_char) - return 0; - - /* if char is invalid, it will be displayed as one space on screen */ - if (!gui_chat_utf_char_valid (utf_char)) - return 1; - - return utf8_char_size_screen (utf_char); -} - -/* * Returns number of char in a string (special chars like colors/attributes are * ignored). */ @@ -211,7 +166,7 @@ gui_chat_strlen_screen (const char *string) (unsigned char *)string, 0, 0, 0); if (string) { - size_on_screen = gui_chat_char_size_screen (string); + size_on_screen = utf8_char_size_screen (string); if (size_on_screen > 0) length += size_on_screen; string = utf8_next_char (string); @@ -259,10 +214,13 @@ gui_chat_string_add_offset_screen (const char *string, int offset_screen) 0, 0, 0); if (string) { - size_on_screen = gui_chat_char_size_screen (string); - offset_screen -= size_on_screen; - if (offset_screen < 0) - return string; + size_on_screen = utf8_char_size_screen (string); + if (size_on_screen > 0) + { + offset_screen -= size_on_screen; + if (offset_screen < 0) + return string; + } string = utf8_next_char (string); } } @@ -300,7 +258,7 @@ gui_chat_string_real_pos (const char *string, int pos, int use_screen_size) 0, 0, 0); if (ptr_string) { - size_on_screen = gui_chat_char_size_screen (ptr_string); + size_on_screen = utf8_char_size_screen (ptr_string); if (size_on_screen > 0) pos -= (use_screen_size) ? size_on_screen : 1; ptr_string = utf8_next_char (ptr_string); @@ -382,11 +340,13 @@ gui_chat_get_word_info (struct t_gui_window *window, *word_start_offset = next_char - start_data; leading_spaces = 0; *word_end_offset = next_char2 - start_data - 1; - char_size_screen = gui_chat_char_size_screen (next_char); - (*word_length_with_spaces) += char_size_screen; + char_size_screen = utf8_char_size_screen (next_char); + if (char_size_screen > 0) + (*word_length_with_spaces) += char_size_screen; if (*word_length < 0) *word_length = 0; - (*word_length) += char_size_screen; + if (char_size_screen > 0) + (*word_length) += char_size_screen; } else { diff --git a/src/gui/gui-chat.h b/src/gui/gui-chat.h index 6a5e7b194..c51b23048 100644 --- a/src/gui/gui-chat.h +++ b/src/gui/gui-chat.h @@ -71,7 +71,6 @@ extern int gui_chat_display_tags; extern void gui_chat_init (); extern void gui_chat_prefix_build (); -extern int gui_chat_utf_char_valid (const char *utf_char); extern int gui_chat_strlen (const char *string); extern int gui_chat_strlen_screen (const char *string); extern const char *gui_chat_string_add_offset (const char *string, int offset); |