diff options
Diffstat (limited to 'src/nvim/grid.c')
-rw-r--r-- | src/nvim/grid.c | 381 |
1 files changed, 244 insertions, 137 deletions
diff --git a/src/nvim/grid.c b/src/nvim/grid.c index fa7f270172..2eeefab27d 100644 --- a/src/nvim/grid.c +++ b/src/nvim/grid.c @@ -17,6 +17,7 @@ #include "nvim/arabic.h" #include "nvim/buffer_defs.h" +#include "nvim/drawscreen.h" #include "nvim/globals.h" #include "nvim/grid.h" #include "nvim/highlight.h" @@ -36,6 +37,15 @@ // Per-cell attributes static size_t linebuf_size = 0; +// Used to cache glyphs which doesn't fit an a sizeof(schar_T) length UTF-8 string. +// Then it instead stores an index into glyph_cache.keys[] which is a flat char array. +// The hash part is used by schar_from_buf() to quickly lookup glyphs which already +// has been interned. schar_get() should used to convert a schar_T value +// back to a string buffer. +// +// The maximum byte size of a glyph is MAX_SCHAR_SIZE (including the final NUL). +static Set(glyph) glyph_cache = SET_INIT; + /// Determine if dedicated window grid should be used or the default_grid /// /// If UI did not request multigrid support, draw all windows on the @@ -56,25 +66,119 @@ void grid_adjust(ScreenGrid **grid, int *row_off, int *col_off) } /// Put a unicode char, and up to MAX_MCO composing chars, in a screen cell. -int schar_from_cc(char *p, int c, int u8cc[MAX_MCO]) +schar_T schar_from_cc(int c, int u8cc[MAX_MCO]) { - int len = utf_char2bytes(c, p); + char buf[MAX_SCHAR_SIZE]; + int len = utf_char2bytes(c, buf); for (int i = 0; i < MAX_MCO; i++) { if (u8cc[i] == 0) { break; } - len += utf_char2bytes(u8cc[i], p + len); + len += utf_char2bytes(u8cc[i], buf + len); + } + buf[len] = 0; + return schar_from_buf(buf, (size_t)len); +} + +schar_T schar_from_str(char *str) +{ + if (str == NULL) { + return 0; + } + return schar_from_buf(str, strlen(str)); +} + +/// @param buf need not be NUL terminated, but may not contain embedded NULs. +/// +/// caller must ensure len < MAX_SCHAR_SIZE (not =, as NUL needs a byte) +schar_T schar_from_buf(const char *buf, size_t len) +{ + assert(len < MAX_SCHAR_SIZE); + if (len <= 4) { + schar_T sc = 0; + memcpy((char *)&sc, buf, len); + return sc; + } else { + String str = { .data = (char *)buf, .size = len }; + + MHPutStatus status; + uint32_t idx = set_put_idx(glyph, &glyph_cache, str, &status); + assert(idx < 0xFFFFFF); +#ifdef ORDER_BIG_ENDIAN + return idx + ((uint32_t)0xFF << 24); +#else + return 0xFF + (idx << 8); +#endif } - p[len] = 0; - return len; } +/// Check if cache is full, and if it is, clear it. +/// +/// This should normally only be called in update_screen() +/// +/// @return true if cache was clered, and all your screen buffers now are hosed +/// and you need to use UPD_CLEAR +bool schar_cache_clear_if_full(void) +{ + // note: critical max is really (1<<24)-1. This gives us some marginal + // until next time update_screen() is called + if (glyph_cache.h.n_keys > (1<<21)) { + set_clear(glyph, &glyph_cache); + return true; + } + return false; +} + +/// For testing. The condition in schar_cache_clear_force is hard to +/// reach, so this function can be used to force a cache clear in a test. +void schar_cache_clear_force(void) +{ + set_clear(glyph, &glyph_cache); + must_redraw = UPD_CLEAR; +} + +bool schar_high(schar_T sc) +{ +#ifdef ORDER_BIG_ENDIAN + return ((sc & 0xFF000000) == 0xFF000000); +#else + return ((sc & 0xFF) == 0xFF); +#endif +} + +void schar_get(char *buf_out, schar_T sc) +{ + if (schar_high(sc)) { +#ifdef ORDER_BIG_ENDIAN + uint32_t idx = sc & (0x00FFFFFF); +#else + uint32_t idx = sc >> 8; +#endif + if (idx >= glyph_cache.h.n_keys) { + abort(); + } + xstrlcpy(buf_out, &glyph_cache.keys[idx], 32); + } else { + memcpy(buf_out, (char *)&sc, 4); + buf_out[4] = NUL; + } +} + +/// @return ascii char or NUL if not ascii +char schar_get_ascii(schar_T sc) +{ +#ifdef ORDER_BIG_ENDIAN + return (!(sc & 0x80FFFFFF)) ? *(char *)&sc : NUL; +#else + return (sc < 0x80) ? (char)sc : NUL; +#endif +} /// clear a line in the grid starting at "off" until "width" characters /// are cleared. void grid_clear_line(ScreenGrid *grid, size_t off, int width, bool valid) { for (int col = 0; col < width; col++) { - schar_from_ascii(grid->chars[off + (size_t)col], ' '); + grid->chars[off + (size_t)col] = schar_from_ascii(' '); } int fill = valid ? 0 : -1; (void)memset(grid->attrs + off, fill, (size_t)width * sizeof(sattr_T)); @@ -93,7 +197,7 @@ bool grid_invalid_row(ScreenGrid *grid, int row) static int line_off2cells(schar_T *line, size_t off, size_t max_off) { - return (off + 1 < max_off && line[off + 1][0] == 0) ? 2 : 1; + return (off + 1 < max_off && line[off + 1] == 0) ? 2 : 1; } /// Return number of display cells for char at grid->chars[off]. @@ -124,7 +228,7 @@ int grid_fix_col(ScreenGrid *grid, int col, int row) col += coloff; if (grid->chars != NULL && col > 0 - && grid->chars[grid->line_offset[row] + (size_t)col][0] == 0) { + && grid->chars[grid->line_offset[row] + (size_t)col] == 0) { return col - 1 - coloff; } return col - coloff; @@ -135,8 +239,7 @@ void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr) { char buf[MB_MAXBYTES + 1]; - buf[utf_char2bytes(c, buf)] = NUL; - grid_puts(grid, buf, row, col, attr); + grid_puts(grid, buf, utf_char2bytes(c, buf), row, col, attr); } /// Get a single character directly from grid.chars into "bytes", which must @@ -155,54 +258,84 @@ void grid_getbytes(ScreenGrid *grid, int row, int col, char *bytes, int *attrp) if (attrp != NULL) { *attrp = grid->attrs[off]; } - schar_copy(bytes, grid->chars[off]); + schar_get(bytes, grid->chars[off]); } -/// put string '*text' on the window grid at position 'row' and 'col', with -/// attributes 'attr', and update chars[] and attrs[]. -/// Note: only outputs within one row, message is truncated at grid boundary! -/// Note: if grid, row and/or col is invalid, nothing is done. -int grid_puts(ScreenGrid *grid, char *text, int row, int col, int attr) +static bool check_grid(ScreenGrid *grid, int row, int col) { - return grid_puts_len(grid, text, -1, row, col, attr); + grid_adjust(&grid, &row, &col); + // Safety check. The check for negative row and column is to fix issue + // vim/vim#4102. TODO(neovim): find out why row/col could be negative. + if (grid->chars == NULL + || row >= grid->rows || row < 0 + || col >= grid->cols || col < 0) { + return false; + } + return true; } -static ScreenGrid *put_dirty_grid = NULL; -static int put_dirty_row = -1; -static int put_dirty_first = INT_MAX; -static int put_dirty_last = 0; +/// put string 'text' on the window grid at position 'row' and 'col', with +/// attributes 'attr', and update contents of 'grid' +/// @param textlen length of string or -1 to use strlen(text) +/// Note: only outputs within one row! +int grid_puts(ScreenGrid *grid, const char *text, int textlen, int row, int col, int attr) +{ + if (!check_grid(grid, row, col)) { + if (rdb_flags & RDB_INVALID) { + abort(); + } + return 0; + } + + grid_line_start(grid, row); + int len = grid_line_puts(col, text, textlen, attr); + grid_line_flush(true); + return len; +} -/// Start a group of grid_puts_len calls that builds a single grid line. +static ScreenGrid *grid_line_grid = NULL; +static int grid_line_row = -1; +static int grid_line_coloff = 0; +static int grid_line_first = INT_MAX; +static int grid_line_last = 0; +static bool grid_line_was_invalid = false; + +/// Start a group of grid_line_puts calls that builds a single grid line. /// -/// Must be matched with a grid_puts_line_flush call before moving to +/// Must be matched with a grid_line_flush call before moving to /// another line. -void grid_puts_line_start(ScreenGrid *grid, int row) +void grid_line_start(ScreenGrid *grid, int row) { - int col = 0; // unused + int col = 0; grid_adjust(&grid, &row, &col); - assert(put_dirty_row == -1); - put_dirty_row = row; - put_dirty_grid = grid; + assert(grid_line_row == -1); + grid_line_row = row; + grid_line_grid = grid; + grid_line_coloff = col; + // TODO(bfredl): ugly hackaround, will be fixed in STAGE 2 + grid_line_was_invalid = grid != &default_grid && grid_invalid_row(grid, row); } -void grid_put_schar(ScreenGrid *grid, int row, int col, char *schar, int attr) +void grid_line_put_schar(int col, schar_T schar, int attr) { - assert(put_dirty_row == row); - size_t off = grid->line_offset[row] + (size_t)col; - if (grid->attrs[off] != attr || schar_cmp(grid->chars[off], schar) || rdb_flags & RDB_NODELTA) { - schar_copy(grid->chars[off], schar); + assert(grid_line_row >= 0); + ScreenGrid *grid = grid_line_grid; + + size_t off = grid->line_offset[grid_line_row] + (size_t)col; + if (grid->attrs[off] != attr || grid->chars[off] != schar || rdb_flags & RDB_NODELTA) { + grid->chars[off] = schar; grid->attrs[off] = attr; - put_dirty_first = MIN(put_dirty_first, col); + grid_line_first = MIN(grid_line_first, col); // TODO(bfredl): Y U NO DOUBLEWIDTH? - put_dirty_last = MAX(put_dirty_last, col + 1); + grid_line_last = MAX(grid_line_last, col + 1); } grid->vcols[off] = -1; } /// like grid_puts(), but output "text[len]". When "len" is -1 output up to /// a NUL. -int grid_puts_len(ScreenGrid *grid, const char *text, int textlen, int row, int col, int attr) +int grid_line_puts(int col, const char *text, int textlen, int attr) { size_t off; const char *ptr = text; @@ -214,37 +347,15 @@ int grid_puts_len(ScreenGrid *grid, const char *text, int textlen, int row, int int prev_c = 0; // previous Arabic character int pc, nc, nc1; int pcc[MAX_MCO]; - bool do_flush = false; - - grid_adjust(&grid, &row, &col); - // Safety check. The check for negative row and column is to fix issue - // vim/vim#4102. TODO(neovim): find out why row/col could be negative. - if (grid->chars == NULL - || row >= grid->rows || row < 0 - || col >= grid->cols || col < 0) { - return 0; - } + assert(grid_line_row >= 0); + ScreenGrid *grid = grid_line_grid; + int row = grid_line_row; + col += grid_line_coloff; - if (put_dirty_row == -1) { - grid_puts_line_start(grid, row); - do_flush = true; - } else { - if (grid != put_dirty_grid || row != put_dirty_row) { - abort(); - } - } off = grid->line_offset[row] + (size_t)col; int start_col = col; - // When drawing over the right half of a double-wide char clear out the - // left half. Only needed in a terminal. - if (grid != &default_grid && col == 0 && grid_invalid_row(grid, row)) { - // redraw the previous cell, make it empty - put_dirty_first = -1; - put_dirty_last = MAX(put_dirty_last, 1); - } - max_off = grid->line_offset[row] + (size_t)grid->cols; while (col < grid->cols && (len < 0 || (int)(ptr - text) < len) @@ -293,10 +404,12 @@ int grid_puts_len(ScreenGrid *grid, const char *text, int textlen, int row, int } schar_T buf; - schar_from_cc(buf, u8c, u8cc); + // TODO(bfredl): why not just keep the original byte sequence. arabshape is + // an edge case, treat it as such.. + buf = schar_from_cc(u8c, u8cc); - int need_redraw = schar_cmp(grid->chars[off], buf) - || (mbyte_cells == 2 && grid->chars[off + 1][0] != 0) + int need_redraw = grid->chars[off] != buf + || (mbyte_cells == 2 && grid->chars[off + 1] != 0) || grid->attrs[off] != attr || exmode_active || rdb_flags & RDB_NODELTA; @@ -320,20 +433,20 @@ int grid_puts_len(ScreenGrid *grid, const char *text, int textlen, int row, int // When at the start of the text and overwriting the right half of a // two-cell character in the same grid, truncate that into a '>'. - if (ptr == text && col > 0 && grid->chars[off][0] == 0) { - schar_from_ascii(grid->chars[off - 1], '>'); + if (ptr == text && col > 0 && grid->chars[off] == 0) { + grid->chars[off - 1] = schar_from_ascii('>'); } - schar_copy(grid->chars[off], buf); + grid->chars[off] = buf; grid->attrs[off] = attr; grid->vcols[off] = -1; if (mbyte_cells == 2) { - grid->chars[off + 1][0] = 0; + grid->chars[off + 1] = 0; grid->attrs[off + 1] = attr; grid->vcols[off + 1] = -1; } - put_dirty_first = MIN(put_dirty_first, col); - put_dirty_last = MAX(put_dirty_last, col + mbyte_cells); + grid_line_first = MIN(grid_line_first, col); + grid_line_last = MAX(grid_line_last, col + mbyte_cells); } off += (size_t)mbyte_cells; @@ -346,39 +459,61 @@ int grid_puts_len(ScreenGrid *grid, const char *text, int textlen, int row, int } } - if (do_flush) { - grid_puts_line_flush(true); - } return col - start_col; } -/// End a group of grid_puts_len calls and send the screen buffer to the UI -/// layer. +void grid_line_fill(int start_col, int end_col, int c, int attr) +{ + ScreenGrid *grid = grid_line_grid; + size_t lineoff = grid->line_offset[grid_line_row]; + start_col += grid_line_coloff; + end_col += grid_line_coloff; + + schar_T sc = schar_from_char(c); + for (int col = start_col; col < end_col; col++) { + size_t off = lineoff + (size_t)col; + if (grid->chars[off] != sc || grid->attrs[off] != attr || rdb_flags & RDB_NODELTA) { + grid->chars[off] = sc; + grid->attrs[off] = attr; + grid_line_first = MIN(grid_line_first, col); + grid_line_last = MAX(grid_line_last, col + 1); + } + grid->vcols[off] = -1; + } +} + +/// End a group of grid_line_puts calls and send the screen buffer to the UI layer. /// /// @param set_cursor Move the visible cursor to the end of the changed region. /// This is a workaround for not yet refactored code paths /// and shouldn't be used in new code. -void grid_puts_line_flush(bool set_cursor) +void grid_line_flush(bool set_cursor) { - assert(put_dirty_row != -1); - if (put_dirty_first < put_dirty_last) { + assert(grid_line_row != -1); + if (grid_line_first < grid_line_last) { + // When drawing over the right half of a double-wide char clear out the + // left half. Only needed in a terminal. + if (grid_line_was_invalid && grid_line_first == 0) { + // redraw the previous cell, make it empty + grid_line_first = -1; + } if (set_cursor) { - ui_grid_cursor_goto(put_dirty_grid->handle, put_dirty_row, - MIN(put_dirty_last, put_dirty_grid->cols - 1)); + ui_grid_cursor_goto(grid_line_grid->handle, grid_line_row, + MIN(grid_line_last, grid_line_grid->cols - 1)); } - if (!put_dirty_grid->throttled) { - ui_line(put_dirty_grid, put_dirty_row, put_dirty_first, put_dirty_last, - put_dirty_last, 0, false); - } else if (put_dirty_grid->dirty_col) { - if (put_dirty_last > put_dirty_grid->dirty_col[put_dirty_row]) { - put_dirty_grid->dirty_col[put_dirty_row] = put_dirty_last; + if (!grid_line_grid->throttled) { + ui_line(grid_line_grid, grid_line_row, grid_line_first, grid_line_last, + grid_line_last, 0, false); + } else if (grid_line_grid->dirty_col) { + if (grid_line_last > grid_line_grid->dirty_col[grid_line_row]) { + grid_line_grid->dirty_col[grid_line_row] = grid_line_last; } } - put_dirty_first = INT_MAX; - put_dirty_last = 0; + grid_line_first = INT_MAX; + grid_line_last = 0; } - put_dirty_row = -1; - put_dirty_grid = NULL; + grid_line_row = -1; + grid_line_grid = NULL; } /// Fill the grid from "start_row" to "end_row" (exclusive), from "start_col" @@ -415,11 +550,11 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int // double wide-char clear out the right half. Only needed in a // terminal. if (start_col > 0 && grid_fix_col(grid, start_col, row) != start_col) { - grid_puts_len(grid, " ", 1, row, start_col - 1, 0); + grid_puts(grid, " ", 1, row, start_col - 1, 0); } if (end_col < grid->cols && grid_fix_col(grid, end_col, row) != end_col) { - grid_puts_len(grid, " ", 1, row, end_col, 0); + grid_puts(grid, " ", 1, row, end_col, 0); } // if grid was resized (in ext_multigrid mode), the UI has no redraw updates @@ -429,12 +564,12 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int int dirty_last = 0; int col = start_col; - schar_from_char(sc, c1); + sc = schar_from_char(c1); size_t lineoff = grid->line_offset[row]; for (col = start_col; col < end_col; col++) { size_t off = lineoff + (size_t)col; - if (schar_cmp(grid->chars[off], sc) || grid->attrs[off] != attr || rdb_flags & RDB_NODELTA) { - schar_copy(grid->chars[off], sc); + if (grid->chars[off] != sc || grid->attrs[off] != attr || rdb_flags & RDB_NODELTA) { + grid->chars[off] = sc; grid->attrs[off] = attr; if (dirty_first == INT_MAX) { dirty_first = col; @@ -443,15 +578,11 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int } grid->vcols[off] = -1; if (col == start_col) { - schar_from_char(sc, c2); + sc = schar_from_char(c2); } } if (dirty_last > dirty_first) { - // TODO(bfredl): support a cleared suffix even with a batched line? - if (put_dirty_row == row) { - put_dirty_first = MIN(put_dirty_first, dirty_first); - put_dirty_last = MAX(put_dirty_last, dirty_last); - } else if (grid->throttled) { + if (grid->throttled) { // Note: assumes msg_grid is the only throttled grid assert(grid == &msg_grid); int dirty = 0; @@ -468,10 +599,6 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int ui_line(grid, row, dirty_first, last, dirty_last, attr, false); } } - - if (end_col == grid->cols) { - grid->line_wraps[row] = false; - } } } @@ -483,11 +610,10 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int static int grid_char_needs_redraw(ScreenGrid *grid, size_t off_from, size_t off_to, int cols) { return (cols > 0 - && ((schar_cmp(linebuf_char[off_from], grid->chars[off_to]) + && ((linebuf_char[off_from] != grid->chars[off_to] || linebuf_attr[off_from] != grid->attrs[off_to] || (line_off2cells(linebuf_char, off_from, off_from + (size_t)cols) > 1 - && schar_cmp(linebuf_char[off_from + 1], - grid->chars[off_to + 1]))) + && linebuf_char[off_from + 1] != grid->chars[off_to + 1])) || rdb_flags & RDB_NODELTA)); } @@ -544,7 +670,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle if (wp->w_p_nu && wp->w_p_rnu) { // do not overwrite the line number, change "123 text" to // "123<<<xt". - while (skip < max_off_from && ascii_isdigit(*linebuf_char[off])) { + while (skip < max_off_from && ascii_isdigit(schar_get_ascii(linebuf_char[off]))) { off++; skip++; } @@ -554,9 +680,9 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle if (line_off2cells(linebuf_char, off, max_off_from) > 1) { // When the first half of a double-width character is // overwritten, change the second half to a space. - schar_from_ascii(linebuf_char[off + 1], ' '); + linebuf_char[off + 1] = schar_from_ascii(' '); } - schar_from_ascii(linebuf_char[off], '<'); + linebuf_char[off] = schar_from_ascii('<'); linebuf_attr[off] = HL_ATTR(HLF_AT); off++; } @@ -565,8 +691,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle if (rlflag) { // Clear rest first, because it's left of the text. if (clear_width > 0) { - while (col <= endcol && grid->chars[off_to][0] == ' ' - && grid->chars[off_to][1] == NUL + while (col <= endcol && grid->chars[off_to] == schar_from_ascii(' ') && grid->attrs[off_to] == bg_attr) { off_to++; col++; @@ -619,9 +744,9 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle clear_next = true; } - schar_copy(grid->chars[off_to], linebuf_char[off_from]); + grid->chars[off_to] = linebuf_char[off_from]; if (char_cells == 2) { - schar_copy(grid->chars[off_to + 1], linebuf_char[off_from + 1]); + grid->chars[off_to + 1] = linebuf_char[off_from + 1]; } grid->attrs[off_to] = linebuf_attr[off_from]; @@ -645,7 +770,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle if (clear_next) { // Clear the second half of a double-wide character of which the left // half was overwritten with a single-wide character. - schar_from_ascii(grid->chars[off_to], ' '); + grid->chars[off_to] = schar_from_ascii(' '); end_dirty++; } @@ -654,12 +779,10 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle // blank out the rest of the line // TODO(bfredl): we could cache winline widths while (col < clear_width) { - if (grid->chars[off_to][0] != ' ' - || grid->chars[off_to][1] != NUL + if (grid->chars[off_to] != schar_from_ascii(' ') || grid->attrs[off_to] != bg_attr || rdb_flags & RDB_NODELTA) { - grid->chars[off_to][0] = ' '; - grid->chars[off_to][1] = NUL; + grid->chars[off_to] = schar_from_ascii(' '); grid->attrs[off_to] = bg_attr; if (start_dirty == -1) { start_dirty = col; @@ -675,12 +798,6 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, int cle } } - if (clear_width > 0 || wp->w_width != grid->cols) { - // If we cleared after the end of the line, it did not wrap. - // For vsplit, line wrapping is not possible. - grid->line_wraps[row] = false; - } - if (clear_end < end_dirty) { clear_end = end_dirty; } @@ -704,14 +821,12 @@ void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy, bool valid) ngrid.vcols = xmalloc(ncells * sizeof(colnr_T)); memset(ngrid.vcols, -1, ncells * sizeof(colnr_T)); ngrid.line_offset = xmalloc((size_t)rows * sizeof(*ngrid.line_offset)); - ngrid.line_wraps = xmalloc((size_t)rows * sizeof(*ngrid.line_wraps)); ngrid.rows = rows; ngrid.cols = columns; for (new_row = 0; new_row < ngrid.rows; new_row++) { ngrid.line_offset[new_row] = (size_t)new_row * (size_t)ngrid.cols; - ngrid.line_wraps[new_row] = false; grid_clear_line(&ngrid, ngrid.line_offset[new_row], columns, valid); @@ -756,13 +871,11 @@ void grid_free(ScreenGrid *grid) xfree(grid->attrs); xfree(grid->vcols); xfree(grid->line_offset); - xfree(grid->line_wraps); grid->chars = NULL; grid->attrs = NULL; grid->vcols = NULL; grid->line_offset = NULL; - grid->line_wraps = NULL; } /// Doesn't allow reinit, so must only be called by free_all_mem! @@ -885,16 +998,13 @@ void grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, } j += line_count; grid_clear_line(grid, grid->line_offset[j] + (size_t)col, width, false); - grid->line_wraps[j] = false; } else { j = end - 1 - i; temp = (unsigned)grid->line_offset[j]; while ((j -= line_count) >= row) { grid->line_offset[j + line_count] = grid->line_offset[j]; - grid->line_wraps[j + line_count] = grid->line_wraps[j]; } grid->line_offset[j + line_count] = temp; - grid->line_wraps[j + line_count] = false; grid_clear_line(grid, temp, grid->cols, false); } } @@ -933,17 +1043,14 @@ void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, } j -= line_count; grid_clear_line(grid, grid->line_offset[j] + (size_t)col, width, false); - grid->line_wraps[j] = false; } else { // whole width, moving the line pointers is faster j = row + i; temp = (unsigned)grid->line_offset[j]; while ((j += line_count) <= end - 1) { grid->line_offset[j - line_count] = grid->line_offset[j]; - grid->line_wraps[j - line_count] = grid->line_wraps[j]; } grid->line_offset[j - line_count] = temp; - grid->line_wraps[j - line_count] = false; grid_clear_line(grid, temp, grid->cols, false); } } |