mirror of
https://github.com/weechat/weechat.git
synced 2026-07-04 08:43:13 +02:00
core: do not display non printable chars, fix function utf8_char_size_screen
Now the function utf8_char_size_screen can return -1 when the char is not printable. It has a specific behavior for some chars: - U+0009: value of option weechat.look.tab_width - U+0001 to U+001F (except U+0009): 1 - U+00AD (soft hyphen): -1 - U+200B (zero width space): -1
This commit is contained in:
+26
-7
@@ -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;
|
||||
|
||||
/* non printable chars are displayed with a space (so size = 1) */
|
||||
return (width >= 0) ? width : 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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 (!simulate)
|
||||
{
|
||||
output = string_iconv_from_internal (NULL, ptr_char);
|
||||
if (reverse_video)
|
||||
{
|
||||
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 (gui_window_current_emphasis)
|
||||
if (display_char)
|
||||
{
|
||||
while (ptr_char && ptr_char[0])
|
||||
{
|
||||
utf8_strncpy (utf_char2, ptr_char, 1);
|
||||
size_on_screen = utf8_char_size_screen (utf_char2);
|
||||
if (size_on_screen >= 0)
|
||||
{
|
||||
gui_window_emphasize (GUI_WINDOW_OBJECTS(window)->win_chat,
|
||||
x - window->scroll->start_col,
|
||||
window->win_chat_cursor_y,
|
||||
size_on_screen);
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
+14
-54
@@ -125,51 +125,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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user