mirror of
https://github.com/irssi/irssi.git
synced 2026-08-10 04:13:32 +02:00
Add a wrapper of wcwidth() that picks the best implementation
This adds a i_wcwidth() function that replaces mk_wcwidth(), and a
'wcwidth_implementation' setting to pick which one it wraps.
Values:
- old: uses our local mk_wcwidth() which implements unicode 5.0
- system: uses the libc-provided wcwidth(), which may be better or worse
than ours depending on how up to date the system is.
- auto: tests the system one against two characters that became
fullwidth in unicode 5.2 and 9.0 respectively. If either of them pass,
pick the system implementation, otherwise pick ours.
It defaults to auto.
mk_wcwidth() is still preferable in some cases, since the way it uses
ranges for fullwidth characters means most CJK blocks are covered even
if their characters didn't exist back then.
The "system" implementation is also wrapped to never return -1, but to
assume those unknown characters use one cell. Quoting the code:
/* Treat all unknown characters as taking one cell. This is
* the reason mk_wcwidth and other outdated implementations
* mostly worked with newer unicode, while glibc's wcwidth
* needs updating to recognize new characters.
*
* Instead of relying on that, we keep the behavior of assuming
* one cell even for glibc's implementation, which is still
* highly accurate and less of a headache overall.
*/
This commit is contained in:
parent
19d84bc16e
commit
0d8632943d
8 changed files with 141 additions and 12 deletions
|
|
@ -51,7 +51,7 @@ static unichar i_tolower(unichar c)
|
|||
static int i_isalnum(unichar c)
|
||||
{
|
||||
if (term_type == TERM_TYPE_UTF8)
|
||||
return (g_unichar_isalnum(c) || mk_wcwidth(c) == 0);
|
||||
return (g_unichar_isalnum(c) || i_wcwidth(c) == 0);
|
||||
return c <= 255 ? isalnum(c) : 0;
|
||||
}
|
||||
|
||||
|
|
@ -219,7 +219,7 @@ static int pos2scrpos(GUI_ENTRY_REC *entry, int pos, int cursor)
|
|||
if (term_type == TERM_TYPE_BIG5)
|
||||
xpos += big5_width(c);
|
||||
else if (entry->utf8)
|
||||
xpos += unichar_isprint(c) ? mk_wcwidth(c) : 1;
|
||||
xpos += unichar_isprint(c) ? i_wcwidth(c) : 1;
|
||||
else
|
||||
xpos++;
|
||||
|
||||
|
|
@ -246,7 +246,7 @@ static int scrpos2pos(GUI_ENTRY_REC *entry, int pos)
|
|||
if (term_type == TERM_TYPE_BIG5)
|
||||
width = big5_width(c);
|
||||
else if (entry->utf8)
|
||||
width = unichar_isprint(c) ? mk_wcwidth(c) : 1;
|
||||
width = unichar_isprint(c) ? i_wcwidth(c) : 1;
|
||||
else
|
||||
width = 1;
|
||||
|
||||
|
|
@ -373,7 +373,7 @@ static void gui_entry_draw_from(GUI_ENTRY_REC *entry, int pos)
|
|||
else if (term_type == TERM_TYPE_BIG5)
|
||||
new_xpos += big5_width(c);
|
||||
else if (entry->utf8)
|
||||
new_xpos += unichar_isprint(c) ? mk_wcwidth(c) : 1;
|
||||
new_xpos += unichar_isprint(c) ? i_wcwidth(c) : 1;
|
||||
else
|
||||
new_xpos++;
|
||||
|
||||
|
|
@ -647,7 +647,7 @@ void gui_entry_insert_char(GUI_ENTRY_REC *entry, unichar chr)
|
|||
if (chr == 0 || chr == 13 || chr == 10)
|
||||
return; /* never insert NUL, CR or LF characters */
|
||||
|
||||
if (entry->utf8 && entry->pos == 0 && mk_wcwidth(chr) == 0)
|
||||
if (entry->utf8 && entry->pos == 0 && i_wcwidth(chr) == 0)
|
||||
return;
|
||||
|
||||
gui_entry_redraw_from(entry, entry->pos);
|
||||
|
|
@ -829,7 +829,7 @@ void gui_entry_erase(GUI_ENTRY_REC *entry, int size, CUTBUFFER_UPDATE_OP update_
|
|||
|
||||
if (entry->utf8)
|
||||
while (entry->pos-size-w > 0 &&
|
||||
mk_wcwidth(entry->text[entry->pos-size-w]) == 0) w++;
|
||||
i_wcwidth(entry->text[entry->pos-size-w]) == 0) w++;
|
||||
|
||||
g_memmove(entry->text + entry->pos - size, entry->text + entry->pos,
|
||||
(entry->text_len-entry->pos+1) * sizeof(unichar));
|
||||
|
|
@ -867,7 +867,7 @@ void gui_entry_erase_cell(GUI_ENTRY_REC *entry)
|
|||
|
||||
if (entry->utf8)
|
||||
while (entry->pos+size < entry->text_len &&
|
||||
mk_wcwidth(entry->text[entry->pos+size]) == 0) size++;
|
||||
i_wcwidth(entry->text[entry->pos+size]) == 0) size++;
|
||||
|
||||
g_memmove(entry->text + entry->pos, entry->text + entry->pos + size,
|
||||
(entry->text_len-entry->pos-size+1) * sizeof(unichar));
|
||||
|
|
@ -1188,7 +1188,7 @@ void gui_entry_move_pos(GUI_ENTRY_REC *entry, int pos)
|
|||
|
||||
if (entry->utf8) {
|
||||
int step = pos < 0 ? -1 : 1;
|
||||
while(mk_wcwidth(entry->text[entry->pos]) == 0 &&
|
||||
while(i_wcwidth(entry->text[entry->pos]) == 0 &&
|
||||
entry->pos + step >= 0 && entry->pos + step <= entry->text_len)
|
||||
entry->pos += step;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -515,7 +515,7 @@ void term_add_unichar(TERM_WINDOW *window, unichar chr)
|
|||
|
||||
switch (term_type) {
|
||||
case TERM_TYPE_UTF8:
|
||||
term_printed_text(unichar_isprint(chr) ? mk_wcwidth(chr) : 1);
|
||||
term_printed_text(unichar_isprint(chr) ? i_wcwidth(chr) : 1);
|
||||
term_addch_utf8(window, chr);
|
||||
break;
|
||||
case TERM_TYPE_BIG5:
|
||||
|
|
@ -558,7 +558,7 @@ int term_addstr(TERM_WINDOW *window, const char *str)
|
|||
len++;
|
||||
ptr++;
|
||||
} else {
|
||||
len += unichar_isprint(tmp) ? mk_wcwidth(tmp) : 1;
|
||||
len += unichar_isprint(tmp) ? i_wcwidth(tmp) : 1;
|
||||
ptr = g_utf8_next_char(ptr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ static inline unichar read_unichar(const unsigned char *data, const unsigned cha
|
|||
*width = 1;
|
||||
} else {
|
||||
*next = (unsigned char *)g_utf8_next_char(data);
|
||||
*width = unichar_isprint(chr) ? mk_wcwidth(chr) : 1;
|
||||
*width = unichar_isprint(chr) ? i_wcwidth(chr) : 1;
|
||||
}
|
||||
return chr;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue