aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2014-04-25 22:59:43 -0400
committerJesse Luehrs <doy@tozt.net>2014-04-25 22:59:43 -0400
commit7e664cbeb3d3402f057753d178cf770a017dc384 (patch)
tree1e30c41ab89325e73939e0649596ef0a2fba013c
parent759969a2cae94a75877a2d2550e9c82f840ba618 (diff)
downloadrunes-7e664cbeb3d3402f057753d178cf770a017dc384.tar.gz
runes-7e664cbeb3d3402f057753d178cf770a017dc384.zip
handle wide characters
-rw-r--r--src/display.c17
-rw-r--r--src/screen.c11
-rw-r--r--src/screen.h1
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 {