diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2015-11-23 11:12:12 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2015-11-23 14:18:27 +0100 |
| commit | 0613073092b9f4172b5b87e9c7f243ff6d61f723 (patch) | |
| tree | 3ba8304237facd50a08ceac45eebe28903c9022e | |
| parent | 51e92f0c8e7b50c684287bea1a55edbde128053f (diff) | |
| download | vis-0613073092b9f4172b5b87e9c7f243ff6d61f723.tar.gz vis-0613073092b9f4172b5b87e9c7f243ff6d61f723.tar.xz | |
view: fix cell placement of combining characters
They now belong to the cell holding the corresponding regular
(i.e. non-combining) character. This also means that at least
in theory a cell could hold arbitrary amounts of data, in
practice it is limited to 16 bytes.
| -rw-r--r-- | view.c | 24 | ||||
| -rw-r--r-- | view.h | 5 |
2 files changed, 20 insertions, 9 deletions
@@ -123,6 +123,7 @@ void view_tabwidth_set(View *view, int tabwidth) { /* reset internal view data structures (cell matrix, line offsets etc.) */ static void view_clear(View *view) { + memset(view->lines, 0, view->lines_size); if (view->start != view->start_last) { view->start_mark = text_mark_set(view->text, view->start); } else { @@ -130,19 +131,17 @@ static void view_clear(View *view) { if (start != EPOS) view->start = start; } + view->start_last = view->start; view->topline = view->lines; view->topline->lineno = text_lineno_by_pos(view->text, view->start); view->lastline = view->topline; - /* reset all other lines */ size_t line_size = sizeof(Line) + view->width*sizeof(Cell); size_t end = view->height * line_size; Line *prev = NULL; for (size_t i = 0; i < end; i += line_size) { Line *line = (Line*)(((char*)view->lines) + i); - line->width = 0; - line->len = 0; line->prev = prev; if (prev) prev->next = line; @@ -365,12 +364,12 @@ void view_draw(View *view) { /* start from known multibyte state */ mbstate_t mbstate = { 0 }; + Cell cell = { 0 }, prev_cell = { 0 }; + while (rem > 0) { /* current 'parsed' character' */ wchar_t wchar; - Cell cell; - memset(&cell, 0, sizeof cell); size_t len = mbrtowc(&wchar, cur, rem, &mbstate); if (len == (size_t)-1 && errno == EILSEQ) { @@ -407,14 +406,25 @@ void view_draw(View *view) { cell = (Cell){ .data = "\n", .len = 2, .width = 1, .istab = false }; } - if (!view_addch(view, &cell)) - break; + if (cell.width == 0 && prev_cell.len + cell.len < sizeof(cell.len)) { + prev_cell.len += cell.len; + strcat(prev_cell.data, cell.data); + } else { + if (prev_cell.len && !view_addch(view, &prev_cell)) + break; + prev_cell = cell; + } rem -= cell.len; cur += cell.len; pos += cell.len; + + memset(&cell, 0, sizeof cell); } + if (prev_cell.len && view_addch(view, &prev_cell)) + pos += prev_cell.len; + /* set end of vieviewg region */ view->end = pos; view->lastline = view->line ? view->line : view->bottomline; @@ -23,8 +23,9 @@ typedef struct { character which use more than 1 column to display, their lenght is stored in the leftmost cell wheras all following cells occupied by the same character have a length of 0. */ - char data[8]; /* utf8 encoded character displayed in this cell might not be the - the same as in the underlying text, for example tabs get expanded */ + char data[16]; /* utf8 encoded character displayed in this cell (might be more than + one Unicode codepoint. might also not be the same as in the + underlying text, for example tabs get expanded */ unsigned int attr; bool istab; bool selected; /* whether this cell is part of a selected region */ |
