From 7e664cbeb3d3402f057753d178cf770a017dc384 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Fri, 25 Apr 2014 22:59:43 -0400 Subject: handle wide characters --- src/display.c | 17 +++++++++++------ src/screen.c | 11 +++++++++-- src/screen.h | 1 + 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/display.c b/src/display.c index dff5173..02e7d1a 100644 --- a/src/display.c +++ b/src/display.c @@ -4,7 +4,7 @@ #include "runes.h" static void runes_display_recalculate_font_metrics(RunesTerm *t); -static void runes_display_draw_cell(RunesTerm *t, int row, int col); +static int runes_display_draw_cell(RunesTerm *t, int row, int col); static void runes_display_paint_rectangle( RunesTerm *t, cairo_t *cr, cairo_pattern_t *pattern, int row, int col, int width, int height); @@ -91,12 +91,14 @@ void runes_display_set_window_size(RunesTerm *t) void runes_display_draw_screen(RunesTerm *t) { - int r, c; + int r; /* XXX quite inefficient */ for (r = 0; r < t->scr.max.row; ++r) { - for (c = 0; c < t->scr.max.col; ++c) { - runes_display_draw_cell(t, r, c); + int c = 0; + + while (c < t->scr.max.col) { + c += runes_display_draw_cell(t, r, c); } } runes_window_backend_request_flush(t); @@ -148,7 +150,7 @@ static void runes_display_recalculate_font_metrics(RunesTerm *t) } } -static void runes_display_draw_cell(RunesTerm *t, int row, int col) +static int runes_display_draw_cell(RunesTerm *t, int row, int col) { struct runes_cell *cell = &t->scr.rows[row].cells[col]; cairo_pattern_t *bg = NULL, *fg = NULL; @@ -204,7 +206,8 @@ static void runes_display_draw_cell(RunesTerm *t, int row, int col) } } - runes_display_paint_rectangle(t, t->cr, bg, row, col, 1, 1); + runes_display_paint_rectangle( + t, t->cr, bg, row, col, cell->is_wide ? 2 : 1, 1); if (cell->len) { runes_display_draw_glyph( @@ -218,6 +221,8 @@ static void runes_display_draw_cell(RunesTerm *t, int row, int col) if (fg_is_custom) { cairo_pattern_destroy(fg); } + + return cell->is_wide ? 2 : 1; } static void runes_display_paint_rectangle( diff --git a/src/screen.c b/src/screen.c index 9d77ea3..1b460e6 100644 --- a/src/screen.c +++ b/src/screen.c @@ -69,6 +69,7 @@ void runes_screen_show_string_ascii(RunesTerm *t, char *buf, size_t len) cell->contents[0] = buf[i]; cell->contents[1] = '\0'; cell->attrs = scr->attrs; + cell->is_wide = 0; runes_screen_move_to(t, scr->cur.row, scr->cur.col + 1); } @@ -83,17 +84,23 @@ void runes_screen_show_string_utf8(RunesTerm *t, char *buf, size_t len) * cell */ while ((next = g_utf8_next_char(c))) { struct runes_cell *cell; + int is_wide; - if (scr->cur.col >= scr->max.col) { + /* XXX handle zero width characters */ + is_wide = g_unichar_iswide(g_utf8_get_char(c)); + + if (scr->cur.col + (is_wide ? 2 : 1) > scr->max.col) { runes_screen_move_to(t, scr->cur.row + 1, 0); } cell = &scr->rows[scr->cur.row].cells[scr->cur.col]; + cell->is_wide = is_wide; cell->len = next - c; strncpy(cell->contents, c, cell->len); cell->attrs = scr->attrs; - runes_screen_move_to(t, scr->cur.row, scr->cur.col + 1); + runes_screen_move_to( + t, scr->cur.row, scr->cur.col + (is_wide ? 2 : 1)); c = next; if ((size_t)(c - buf) >= len) { break; diff --git a/src/screen.h b/src/screen.h index 73b9360..deddb81 100644 --- a/src/screen.h +++ b/src/screen.h @@ -49,6 +49,7 @@ struct runes_cell { char contents[8]; size_t len; struct runes_cell_attrs attrs; + unsigned char is_wide: 1; }; struct runes_row { -- cgit v1.2.3-54-g00ecf