summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/wee-utf8.c33
-rw-r--r--src/gui/curses/gui-curses-bar-window.c8
-rw-r--r--src/gui/curses/gui-curses-chat.c72
-rw-r--r--src/gui/gui-chat.c68
-rw-r--r--src/gui/gui-chat.h1
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);