summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLemonBoy <thatlemon@gmail.com>2015-10-02 14:04:04 +0200
committerLemonBoy <thatlemon@gmail.com>2015-10-02 14:44:35 +0200
commit2e860abd2b8b3a30f74005450830c34a318b64a3 (patch)
tree64a6b6fa5f8b591d5a45cd948c90cbedcaca2902
parentacbe2ecac299d4f6770c60747776cbea290bee3f (diff)
downloadirssi-2e860abd2b8b3a30f74005450830c34a318b64a3.zip
Fix the display of utf8 sequences in the gui
term_addstr() had a long-standing fixme that suggested it didn't take into account the string encoding when calculating the string length. The BIG5 code path is untested.
-rw-r--r--src/fe-common/core/utf8.h2
-rw-r--r--src/fe-text/gui-printtext.c7
-rw-r--r--src/fe-text/term-terminfo.c53
-rw-r--r--src/fe-text/term.h2
4 files changed, 55 insertions, 9 deletions
diff --git a/src/fe-common/core/utf8.h b/src/fe-common/core/utf8.h
index 3c15dc7d..70b44d7e 100644
--- a/src/fe-common/core/utf8.h
+++ b/src/fe-common/core/utf8.h
@@ -8,6 +8,8 @@
#define is_big5_hi(hi) (0x81 <= (hi) && (hi) <= 0xFE)
#define is_big5(hi,lo) (is_big5_hi(hi) && is_big5_lo(lo))
+int strlen_big5(const unsigned char *str);
+
/* Returns width for character (0-2). */
int mk_wcwidth(unichar c);
diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c
index 547d39c9..d8272df5 100644
--- a/src/fe-text/gui-printtext.c
+++ b/src/fe-text/gui-printtext.c
@@ -220,16 +220,15 @@ static void sig_gui_print_text(WINDOW_REC *window, void *fgcolor,
get_colors(flags, &fg, &bg, &attr);
if (window == NULL) {
- g_return_if_fail(next_xpos != -1);
+ g_return_if_fail(next_xpos != -1);
term_set_color2(root_window, attr, fg, bg);
term_move(root_window, next_xpos, next_ypos);
if (flags & GUI_PRINT_FLAG_CLRTOEOL)
term_clrtoeol(root_window);
- term_addstr(root_window, str);
- next_xpos += strlen(str); /* FIXME utf8 or big5 */
- return;
+ next_xpos += term_addstr(root_window, str);
+ return;
}
lineinfo.level = dest == NULL ? 0 : dest->level;
diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c
index ded79c28..8c95bc0d 100644
--- a/src/fe-text/term-terminfo.c
+++ b/src/fe-text/term-terminfo.c
@@ -522,15 +522,60 @@ void term_add_unichar(TERM_WINDOW *window, unichar chr)
}
}
-void term_addstr(TERM_WINDOW *window, const char *str)
+int term_addstr(TERM_WINDOW *window, const char *str)
{
- int len;
+ int i, len, raw_len;
+ unichar *tmp;
+ const char *ptr;
if (vcmove) term_move_real();
- len = strlen(str); /* FIXME utf8 or big5 */
+
+ raw_len = strlen(str);
+
+ /* The string length depends on the terminal encoding */
+ switch (term_type) {
+ case TERM_TYPE_BIG5:
+ len = strlen_big5((const unsigned char *)str);
+ break;
+ case TERM_TYPE_UTF8:
+ len = g_utf8_strlen(str, -1);
+ break;
+ default:
+ len = strlen(str);
+ break;
+ }
+
+ tmp = calloc(len, sizeof(unichar));
+ if (tmp == NULL)
+ return 0;
+
+ switch (term_type) {
+ case TERM_TYPE_BIG5:
+ big5_to_unichars(str, tmp);
+ break;
+ case TERM_TYPE_UTF8:
+ ptr = str;
+ for (i = 0; i < len; i++) {
+ tmp[i] = g_utf8_get_char(ptr);
+ ptr = g_utf8_next_char(ptr);
+ }
+ break;
+ default:
+ for (i = 0; i < len; i++)
+ tmp[i] = str[i];
+ }
+
+ for (len = i = 0; i < len; i++)
+ len += unichar_isprint(tmp[i]) ? mk_wcwidth(tmp[i]) : 1;
+
+ free(tmp);
+
term_printed_text(len);
- fwrite(str, 1, len, window->term->out);
+ /* Use strlen() here since we need the number of raw bytes */
+ fwrite(str, 1, raw_len, window->term->out);
+
+ return len;
}
void term_clrtoeol(TERM_WINDOW *window)
diff --git a/src/fe-text/term.h b/src/fe-text/term.h
index cdcc787a..f0a76c42 100644
--- a/src/fe-text/term.h
+++ b/src/fe-text/term.h
@@ -83,7 +83,7 @@ void term_set_color(TERM_WINDOW *window, int col);
void term_move(TERM_WINDOW *window, int x, int y);
void term_addch(TERM_WINDOW *window, char chr);
void term_add_unichar(TERM_WINDOW *window, unichar chr);
-void term_addstr(TERM_WINDOW *window, const char *str);
+int term_addstr(TERM_WINDOW *window, const char *str);
void term_clrtoeol(TERM_WINDOW *window);
void term_move_cursor(int x, int y);