mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
multigrid: avoid allocation when not ext_multigrid.
Move grid specific functions from mbyte.c to screen.c
This commit is contained in:
parent
4f1dcf7c28
commit
1a896bc93f
@ -1508,7 +1508,7 @@ void edit_putchar(int c, int highlight)
|
||||
if (curwin->w_p_rl) {
|
||||
pc_col += curwin->w_grid.Columns - 1 - curwin->w_wcol;
|
||||
if (has_mbyte) {
|
||||
int fix_col = mb_fix_col(&curwin->w_grid, pc_col, pc_row);
|
||||
int fix_col = grid_fix_col(&curwin->w_grid, pc_col, pc_row);
|
||||
|
||||
if (fix_col != pc_col) {
|
||||
grid_putchar(&curwin->w_grid, ' ', pc_row, fix_col, attr);
|
||||
@ -1518,7 +1518,7 @@ void edit_putchar(int c, int highlight)
|
||||
}
|
||||
} else {
|
||||
pc_col += curwin->w_wcol;
|
||||
if (mb_lefthalve(&curwin->w_grid, pc_row, pc_col))
|
||||
if (grid_lefthalve(&curwin->w_grid, pc_row, pc_col))
|
||||
pc_status = PC_STATUS_LEFT;
|
||||
}
|
||||
|
||||
|
@ -1823,32 +1823,6 @@ const char *mb_unescape(const char **const pp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the character at "row"/"col" on the screen is the left side
|
||||
* of a double-width character.
|
||||
* Caller must make sure "row" and "col" are not invalid!
|
||||
*/
|
||||
bool mb_lefthalve(ScreenGrid *grid, int row, int col)
|
||||
{
|
||||
return utf_off2cells(grid, grid->LineOffset[row] + col,
|
||||
grid->LineOffset[row] + grid->Columns) > 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Correct a position on the screen, if it's the right half of a double-wide
|
||||
* char move it to the left half. Returns the corrected column.
|
||||
*/
|
||||
int mb_fix_col(ScreenGrid *grid, int col, int row)
|
||||
{
|
||||
col = check_col(grid, col);
|
||||
row = check_row(grid, row);
|
||||
if (grid->ScreenLines != NULL && col > 0
|
||||
&& grid->ScreenLines[grid->LineOffset[row] + col][0] == 0) {
|
||||
return col - 1;
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Skip the Vim specific head of a 'encoding' name.
|
||||
@ -2525,23 +2499,3 @@ char_u * string_convert_ext(const vimconv_T *const vcp, char_u *ptr,
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Check bounds for column number
|
||||
static int check_col(ScreenGrid *grid, int col)
|
||||
{
|
||||
if (col < 0)
|
||||
return 0;
|
||||
if (col >= grid->Columns)
|
||||
return grid->Columns - 1;
|
||||
return col;
|
||||
}
|
||||
|
||||
// Check bounds for row number
|
||||
static int check_row(ScreenGrid *grid, int row)
|
||||
{
|
||||
if (row < 0)
|
||||
return 0;
|
||||
if (row >= grid->Rows)
|
||||
return grid->Rows - 1;
|
||||
return row;
|
||||
}
|
||||
|
@ -699,7 +699,7 @@ void free_all_mem(void)
|
||||
}
|
||||
|
||||
// free screenlines (can't display anything now!)
|
||||
free_screengrid(&default_grid);
|
||||
screen_free_all_mem();
|
||||
|
||||
clear_hl_tables(false);
|
||||
list_free_log();
|
||||
|
@ -121,8 +121,12 @@
|
||||
#define W_ENDCOL(wp) (wp->w_wincol + wp->w_width)
|
||||
#define W_ENDROW(wp) (wp->w_winrow + wp->w_height)
|
||||
|
||||
// Get the offset for the current line buffer when redrawing a line for a grid
|
||||
#define GRID_TMPLINE(grid) ((grid)->Rows * (grid)->Columns)
|
||||
|
||||
// temporary buffer for rendering a single screenline, so it can be
|
||||
// comparared with previous contents to calulate smallest delta.
|
||||
static size_t linebuf_size = 0;
|
||||
static schar_T *linebuf_char = NULL;
|
||||
static sattr_T *linebuf_attr = NULL;
|
||||
|
||||
static match_T search_hl; /* used for 'hlsearch' highlight matching */
|
||||
|
||||
@ -502,7 +506,7 @@ void update_single_line(win_T *wp, linenr_T lnum)
|
||||
int j;
|
||||
|
||||
// Don't do anything if the screen structures are (not yet) valid.
|
||||
if (wp->w_grid.ScreenLines == NULL || updating_screen) {
|
||||
if (linebuf_char == NULL || updating_screen) {
|
||||
return;
|
||||
}
|
||||
updating_screen = true;
|
||||
@ -516,6 +520,8 @@ void update_single_line(win_T *wp, linenr_T lnum)
|
||||
start_search_hl();
|
||||
prepare_search_hl(wp, lnum);
|
||||
update_window_hl(wp, false);
|
||||
// allocate window grid if not already
|
||||
win_grid_alloc(wp, false);
|
||||
win_line(wp, lnum, row, row + wp->w_lines[j].wl_size, false, false);
|
||||
end_search_hl();
|
||||
break;
|
||||
@ -1774,15 +1780,15 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
|
||||
* 6. set highlighting for the Visual area an other text
|
||||
*/
|
||||
col = 0;
|
||||
off = (int)GRID_TMPLINE(grid);
|
||||
off = 0;
|
||||
|
||||
/*
|
||||
* 1. Add the cmdwin_type for the command-line window
|
||||
* Ignores 'rightleft', this window is never right-left.
|
||||
*/
|
||||
if (cmdwin_type != 0 && wp == curwin) {
|
||||
schar_from_ascii(grid->ScreenLines[off], cmdwin_type);
|
||||
grid->ScreenAttrs[off] = win_hl_attr(wp, HLF_AT);
|
||||
schar_from_ascii(linebuf_char[off], cmdwin_type);
|
||||
linebuf_attr[off] = win_hl_attr(wp, HLF_AT);
|
||||
col++;
|
||||
}
|
||||
|
||||
@ -1798,7 +1804,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
|
||||
win_hl_attr(wp, HLF_FC));
|
||||
// reverse the fold column
|
||||
for (i = 0; i < fdc; i++) {
|
||||
schar_from_ascii(grid->ScreenLines[off + wp->w_width - i - 1 - col], buf[i]);
|
||||
schar_from_ascii(linebuf_char[off + wp->w_width - i - 1 - col], buf[i]);
|
||||
}
|
||||
} else {
|
||||
copy_text_attr(off + col, buf, fdc, win_hl_attr(wp, HLF_FC));
|
||||
@ -1808,10 +1814,10 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
|
||||
|
||||
# define RL_MEMSET(p, v, l) if (wp->w_p_rl) \
|
||||
for (ri = 0; ri < l; ++ri) \
|
||||
grid->ScreenAttrs[off + (wp->w_width - (p) - (l)) + ri] = v; \
|
||||
linebuf_attr[off + (wp->w_width - (p) - (l)) + ri] = v; \
|
||||
else \
|
||||
for (ri = 0; ri < l; ++ri) \
|
||||
grid->ScreenAttrs[off + (p) + ri] = v
|
||||
linebuf_attr[off + (p) + ri] = v
|
||||
|
||||
/* Set all attributes of the 'number' or 'relativenumber' column and the
|
||||
* text */
|
||||
@ -1877,7 +1883,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
|
||||
|
||||
txtcol = col; /* remember where text starts */
|
||||
|
||||
// 5. move the text to grid->ScreenLines[off]. Fill up with "fill_fold".
|
||||
// 5. move the text to linebuf_char[off]. Fill up with "fill_fold".
|
||||
// Right-left text is put in columns 0 - number-col, normal text is put
|
||||
// in columns number-col - window-width.
|
||||
int idx;
|
||||
@ -1895,8 +1901,8 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
|
||||
// if(col + cells > wp->w_width - (wp->w_p_rl ? col : 0)) { break; }
|
||||
// This is obvious wrong. If Vim ever fixes this, solve for "cells" again
|
||||
// in the correct condition.
|
||||
int maxcells = wp->w_width - col - (wp->w_p_rl ? col : 0);
|
||||
int cells = line_putchar(&s, &grid->ScreenLines[idx], maxcells, wp->w_p_rl);
|
||||
int maxcells = grid->Columns - col - (wp->w_p_rl ? col : 0);
|
||||
int cells = line_putchar(&s, &linebuf_char[idx], maxcells, wp->w_p_rl);
|
||||
if (cells == -1) {
|
||||
break;
|
||||
}
|
||||
@ -1913,7 +1919,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
|
||||
while (col < wp->w_width
|
||||
- (wp->w_p_rl ? txtcol : 0)
|
||||
) {
|
||||
schar_copy(grid->ScreenLines[off+col++], sc);
|
||||
schar_copy(linebuf_char[off+col++], sc);
|
||||
}
|
||||
|
||||
if (text != buf)
|
||||
@ -1977,8 +1983,8 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
|
||||
txtcol -= wp->w_leftcol;
|
||||
}
|
||||
if (txtcol >= 0 && txtcol < wp->w_width) {
|
||||
grid->ScreenAttrs[off + txtcol] =
|
||||
hl_combine_attr(grid->ScreenAttrs[off + txtcol], win_hl_attr(wp, HLF_MC));
|
||||
linebuf_attr[off + txtcol] =
|
||||
hl_combine_attr(linebuf_attr[off + txtcol], win_hl_attr(wp, HLF_MC));
|
||||
}
|
||||
txtcol = old_txtcol;
|
||||
j = wp->w_p_cc_cols[++i];
|
||||
@ -1992,13 +1998,14 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
|
||||
txtcol -= wp->w_skipcol;
|
||||
else
|
||||
txtcol -= wp->w_leftcol;
|
||||
if (txtcol >= 0 && txtcol < wp->w_width)
|
||||
grid->ScreenAttrs[off + txtcol] = hl_combine_attr(
|
||||
grid->ScreenAttrs[off + txtcol], win_hl_attr(wp, HLF_CUC));
|
||||
if (txtcol >= 0 && txtcol < wp->w_width) {
|
||||
linebuf_attr[off + txtcol] = hl_combine_attr(
|
||||
linebuf_attr[off + txtcol], win_hl_attr(wp, HLF_CUC));
|
||||
}
|
||||
}
|
||||
|
||||
grid_move_line(grid, row, 0, grid->Columns, grid->Columns, false, wp,
|
||||
wp->w_hl_attr_normal, false);
|
||||
grid_put_linebuf(grid, row, 0, grid->Columns, grid->Columns, false, wp,
|
||||
wp->w_hl_attr_normal, false);
|
||||
|
||||
/*
|
||||
* Update w_cline_height and w_cline_folded if the cursor line was
|
||||
@ -2023,8 +2030,8 @@ static void copy_text_attr(int off, char_u *buf, int len, int attr)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
schar_from_ascii(default_grid.ScreenLines[off + i], buf[i]);
|
||||
default_grid.ScreenAttrs[off + i] = attr;
|
||||
schar_from_ascii(linebuf_char[off + i], buf[i]);
|
||||
linebuf_attr[off + i] = attr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2099,7 +2106,6 @@ win_line (
|
||||
bool number_only // only update the number column
|
||||
)
|
||||
{
|
||||
unsigned off; // offset in ScreenLines/ScreenAttrs
|
||||
int c = 0; // init for GCC
|
||||
long vcol = 0; // virtual column (for tabs)
|
||||
long vcol_sbr = -1; // virtual column after showbreak
|
||||
@ -2238,9 +2244,6 @@ win_line (
|
||||
|
||||
row = startrow;
|
||||
|
||||
// allocate window grid if not already
|
||||
win_grid_alloc(wp, true);
|
||||
|
||||
if (!number_only) {
|
||||
// To speed up the loop below, set extra_check when there is linebreak,
|
||||
// trailing white space and/or syntax processing to be done.
|
||||
@ -2676,11 +2679,11 @@ win_line (
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
off = (unsigned)GRID_TMPLINE(grid);
|
||||
unsigned off = 0; // Offset relative start of line
|
||||
int col = 0; // Visual column on screen.
|
||||
if (wp->w_p_rl) {
|
||||
// Rightleft window: process the text in the normal direction, but put
|
||||
// it in grid->ScreenLines[off] from right to left. Start at the
|
||||
// it in linebuf_char[off] from right to left. Start at the
|
||||
// rightmost column of the window.
|
||||
col = grid->Columns - 1;
|
||||
off += col;
|
||||
@ -2901,8 +2904,8 @@ win_line (
|
||||
&& lnum == wp->w_cursor.lnum && vcol >= (long)wp->w_virtcol
|
||||
&& filler_todo <= 0)
|
||||
|| (number_only && draw_state > WL_NR)) {
|
||||
grid_move_line(grid, row, 0, col, -grid->Columns, wp->w_p_rl, wp,
|
||||
wp->w_hl_attr_normal, false);
|
||||
grid_put_linebuf(grid, row, 0, col, -grid->Columns, wp->w_p_rl, wp,
|
||||
wp->w_hl_attr_normal, false);
|
||||
// Pretend we have finished updating the window. Except when
|
||||
// 'cursorcolumn' is set.
|
||||
if (wp->w_p_cuc) {
|
||||
@ -3846,7 +3849,7 @@ win_line (
|
||||
col += n;
|
||||
} else {
|
||||
// Add a blank character to highlight.
|
||||
schar_from_ascii(grid->ScreenLines[off], ' ');
|
||||
schar_from_ascii(linebuf_char[off], ' ');
|
||||
}
|
||||
if (area_attr == 0) {
|
||||
/* Use attributes from match with highest priority among
|
||||
@ -3877,7 +3880,7 @@ win_line (
|
||||
if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
|
||||
eol_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), eol_attr);
|
||||
}
|
||||
grid->ScreenAttrs[off] = eol_attr;
|
||||
linebuf_attr[off] = eol_attr;
|
||||
if (wp->w_p_rl) {
|
||||
--col;
|
||||
--off;
|
||||
@ -3971,14 +3974,14 @@ win_line (
|
||||
}
|
||||
}
|
||||
if (*s.p != NUL) {
|
||||
cells = line_putchar(&s, &grid->ScreenLines[off], grid->Columns - col,
|
||||
cells = line_putchar(&s, &linebuf_char[off], grid->Columns - col,
|
||||
false);
|
||||
}
|
||||
}
|
||||
delay_virttext = false;
|
||||
|
||||
if (cells == -1) {
|
||||
schar_from_ascii(grid->ScreenLines[off], ' ');
|
||||
schar_from_ascii(linebuf_char[off], ' ');
|
||||
cells = 1;
|
||||
}
|
||||
col += cells * col_stride;
|
||||
@ -4000,9 +4003,9 @@ win_line (
|
||||
|
||||
attr = hl_combine_attr(attr, line_attr);
|
||||
|
||||
grid->ScreenAttrs[off] = attr;
|
||||
linebuf_attr[off] = attr;
|
||||
if (cells == 2) {
|
||||
grid->ScreenAttrs[off+1] = attr;
|
||||
linebuf_attr[off+1] = attr;
|
||||
}
|
||||
off += cells * col_stride;
|
||||
|
||||
@ -4020,12 +4023,12 @@ win_line (
|
||||
// terminal buffers may need to highlight beyond the end of the
|
||||
// logical line
|
||||
while (col < grid->Columns) {
|
||||
schar_from_ascii(grid->ScreenLines[off], ' ');
|
||||
grid->ScreenAttrs[off++] = term_attrs[vcol++];
|
||||
schar_from_ascii(linebuf_char[off], ' ');
|
||||
linebuf_attr[off++] = term_attrs[vcol++];
|
||||
col++;
|
||||
}
|
||||
}
|
||||
grid_move_line(grid, row, 0, col, grid->Columns, wp->w_p_rl, wp,
|
||||
grid_put_linebuf(grid, row, 0, col, grid->Columns, wp->w_p_rl, wp,
|
||||
wp->w_hl_attr_normal, false);
|
||||
row++;
|
||||
|
||||
@ -4106,22 +4109,23 @@ win_line (
|
||||
--col;
|
||||
}
|
||||
if (mb_utf8) {
|
||||
schar_from_cc(grid->ScreenLines[off], mb_c, u8cc);
|
||||
schar_from_cc(linebuf_char[off], mb_c, u8cc);
|
||||
} else {
|
||||
schar_from_ascii(grid->ScreenLines[off], c);
|
||||
schar_from_ascii(linebuf_char[off], c);
|
||||
}
|
||||
if (multi_attr) {
|
||||
grid->ScreenAttrs[off] = multi_attr;
|
||||
linebuf_attr[off] = multi_attr;
|
||||
multi_attr = 0;
|
||||
} else
|
||||
grid->ScreenAttrs[off] = char_attr;
|
||||
} else {
|
||||
linebuf_attr[off] = char_attr;
|
||||
}
|
||||
|
||||
if (has_mbyte && (*mb_char2cells)(mb_c) > 1) {
|
||||
// Need to fill two screen columns.
|
||||
off++;
|
||||
col++;
|
||||
// UTF-8: Put a 0 in the second screen char.
|
||||
grid->ScreenLines[off][0] = 0;
|
||||
linebuf_char[off][0] = 0;
|
||||
if (draw_state > WL_NR && filler_todo <= 0) {
|
||||
vcol++;
|
||||
}
|
||||
@ -4241,8 +4245,8 @@ win_line (
|
||||
&& row != endrow - 1 // Not the last line being displayed.
|
||||
&& grid->Columns == Columns // Window spans the width of the screen.
|
||||
&& !wp->w_p_rl; // Not right-to-left.
|
||||
grid_move_line(grid, row, 0, col - boguscols, grid->Columns, wp->w_p_rl,
|
||||
wp, wp->w_hl_attr_normal, wrap);
|
||||
grid_put_linebuf(grid, row, 0, col - boguscols, grid->Columns, wp->w_p_rl,
|
||||
wp, wp->w_hl_attr_normal, wrap);
|
||||
if (wrap) {
|
||||
// Force a redraw of the first column of the next line.
|
||||
grid->ScreenAttrs[grid->LineOffset[row + 1]] = -1;
|
||||
@ -4276,7 +4280,7 @@ win_line (
|
||||
}
|
||||
|
||||
col = 0;
|
||||
off = (unsigned)GRID_TMPLINE(grid);
|
||||
off = 0;
|
||||
if (wp->w_p_rl) {
|
||||
col = grid->Columns - 1; /* col is not used if breaking! */
|
||||
off += col;
|
||||
@ -4323,15 +4327,15 @@ static int grid_char_needs_redraw(ScreenGrid *grid, int off_from, int off_to,
|
||||
int cols)
|
||||
{
|
||||
return (cols > 0
|
||||
&& ((schar_cmp(grid->ScreenLines[off_from], grid->ScreenLines[off_to])
|
||||
|| grid->ScreenAttrs[off_from] != grid->ScreenAttrs[off_to]
|
||||
|| (utf_off2cells(grid, off_from, off_from + cols) > 1
|
||||
&& schar_cmp(grid->ScreenLines[off_from + 1],
|
||||
&& ((schar_cmp(linebuf_char[off_from], grid->ScreenLines[off_to])
|
||||
|| linebuf_attr[off_from] != grid->ScreenAttrs[off_to]
|
||||
|| (line_off2cells(linebuf_char, off_from, off_from + cols) > 1
|
||||
&& schar_cmp(linebuf_char[off_from + 1],
|
||||
grid->ScreenLines[off_to + 1])))
|
||||
|| p_wd < 0));
|
||||
}
|
||||
|
||||
/// Move one "cooked" line to the window grid, but only the characters that
|
||||
/// Move one buffered line to the window grid, but only the characters that
|
||||
/// have actually changed. Handle insert/delete character.
|
||||
/// "coloff" gives the first column on the grid for this line.
|
||||
/// "endcol" gives the columns where valid characters are.
|
||||
@ -4342,9 +4346,9 @@ static int grid_char_needs_redraw(ScreenGrid *grid, int off_from, int off_to,
|
||||
/// When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width"
|
||||
/// If "wrap" is true, then hint to the UI that "row" contains a line
|
||||
/// which has wrapped into the next row.
|
||||
static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol,
|
||||
int clear_width, int rlflag, win_T *wp, int bg_attr,
|
||||
bool wrap)
|
||||
static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol,
|
||||
int clear_width, int rlflag, win_T *wp,
|
||||
int bg_attr, bool wrap)
|
||||
{
|
||||
unsigned off_from;
|
||||
unsigned off_to;
|
||||
@ -4372,18 +4376,12 @@ static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol,
|
||||
if (!ui_is_external(kUIMultigrid) && grid != &default_grid) {
|
||||
row += grid->OffsetRow;
|
||||
coloff += grid->OffsetColumn;
|
||||
memcpy(default_grid.ScreenLines + GRID_TMPLINE(&default_grid),
|
||||
grid->ScreenLines + GRID_TMPLINE(grid),
|
||||
sizeof(schar_T) * grid->Columns);
|
||||
memcpy(default_grid.ScreenAttrs + GRID_TMPLINE(&default_grid),
|
||||
grid->ScreenAttrs + GRID_TMPLINE(grid),
|
||||
sizeof(sattr_T) * grid->Columns);
|
||||
grid = &default_grid;
|
||||
}
|
||||
|
||||
off_from = (unsigned)GRID_TMPLINE(grid);
|
||||
off_from = 0;
|
||||
off_to = grid->LineOffset[row] + coloff;
|
||||
max_off_from = off_from + grid->Columns;
|
||||
max_off_from = linebuf_size;
|
||||
max_off_to = grid->LineOffset[row] + grid->Columns;
|
||||
|
||||
if (rlflag) {
|
||||
@ -4409,8 +4407,8 @@ static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol,
|
||||
|
||||
if (bg_attr) {
|
||||
for (int c = col; c < endcol; c++) {
|
||||
grid->ScreenAttrs[off_from+c] =
|
||||
hl_combine_attr(bg_attr, grid->ScreenAttrs[off_from+c]);
|
||||
linebuf_attr[off_from+c] =
|
||||
hl_combine_attr(bg_attr, linebuf_attr[off_from+c]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4419,7 +4417,7 @@ static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol,
|
||||
while (col < endcol) {
|
||||
char_cells = 1;
|
||||
if (col + 1 < endcol) {
|
||||
char_cells = utf_off2cells(grid, off_from, max_off_from);
|
||||
char_cells = line_off2cells(linebuf_char, off_from, max_off_from);
|
||||
}
|
||||
redraw_this = redraw_next;
|
||||
redraw_next = grid_char_needs_redraw(grid, off_from + char_cells,
|
||||
@ -4438,23 +4436,23 @@ static void grid_move_line(ScreenGrid *grid, int row, int coloff, int endcol,
|
||||
// char over the left halve of an existing one
|
||||
if (col + char_cells == endcol
|
||||
&& ((char_cells == 1
|
||||
&& utf_off2cells(grid, off_to, max_off_to) > 1)
|
||||
&& grid_off2cells(grid, off_to, max_off_to) > 1)
|
||||
|| (char_cells == 2
|
||||
&& utf_off2cells(grid, off_to, max_off_to) == 1
|
||||
&& utf_off2cells(grid, off_to + 1, max_off_to) > 1))) {
|
||||
&& grid_off2cells(grid, off_to, max_off_to) == 1
|
||||
&& grid_off2cells(grid, off_to + 1, max_off_to) > 1))) {
|
||||
clear_next = true;
|
||||
}
|
||||
|
||||
schar_copy(grid->ScreenLines[off_to], grid->ScreenLines[off_from]);
|
||||
schar_copy(grid->ScreenLines[off_to], linebuf_char[off_from]);
|
||||
if (char_cells == 2) {
|
||||
schar_copy(grid->ScreenLines[off_to+1], grid->ScreenLines[off_from+1]);
|
||||
schar_copy(grid->ScreenLines[off_to+1], linebuf_char[off_from+1]);
|
||||
}
|
||||
|
||||
grid->ScreenAttrs[off_to] = grid->ScreenAttrs[off_from];
|
||||
grid->ScreenAttrs[off_to] = linebuf_attr[off_from];
|
||||
// For simplicity set the attributes of second half of a
|
||||
// double-wide character equal to the first half.
|
||||
if (char_cells == 2) {
|
||||
grid->ScreenAttrs[off_to + 1] = grid->ScreenAttrs[off_from];
|
||||
grid->ScreenAttrs[off_to + 1] = linebuf_attr[off_from];
|
||||
}
|
||||
}
|
||||
|
||||
@ -5257,6 +5255,52 @@ static void schar_copy(char_u *sc1, char_u *sc2)
|
||||
STRLCPY(sc1, sc2, sizeof(schar_T));
|
||||
}
|
||||
|
||||
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 number of display cells for char at ScreenLines[off].
|
||||
/// We make sure that the offset used is less than "max_off".
|
||||
static int grid_off2cells(ScreenGrid *grid, size_t off, size_t max_off)
|
||||
{
|
||||
return line_off2cells(grid->ScreenLines, off, max_off);
|
||||
}
|
||||
|
||||
/// Return true if the character at "row"/"col" on the screen is the left side
|
||||
/// of a double-width character.
|
||||
///
|
||||
/// Caller must make sure "row" and "col" are not invalid!
|
||||
bool grid_lefthalve(ScreenGrid *grid, int row, int col)
|
||||
{
|
||||
if (!ui_is_external(kUIMultigrid)) {
|
||||
row += grid->OffsetRow;
|
||||
col += grid->OffsetColumn;
|
||||
grid = &default_grid;
|
||||
}
|
||||
|
||||
return grid_off2cells(grid, grid->LineOffset[row] + col,
|
||||
grid->LineOffset[row] + grid->Columns) > 1;
|
||||
}
|
||||
|
||||
/// Correct a position on the screen, if it's the right half of a double-wide
|
||||
/// char move it to the left half. Returns the corrected column.
|
||||
int grid_fix_col(ScreenGrid *grid, int col, int row)
|
||||
{
|
||||
int coloff = 0;
|
||||
if (!ui_is_external(kUIMultigrid)) {
|
||||
row += grid->OffsetRow;
|
||||
coloff = grid->OffsetColumn;
|
||||
grid = &default_grid;
|
||||
}
|
||||
|
||||
col += coloff;
|
||||
if (grid->ScreenLines != NULL && col > 0
|
||||
&& grid->ScreenLines[grid->LineOffset[row] + col][0] == 0) {
|
||||
return col - 1 - coloff;
|
||||
}
|
||||
return col - coloff;
|
||||
}
|
||||
|
||||
/// output a single character directly to the grid and update ScreenLines.
|
||||
void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr)
|
||||
@ -5363,7 +5407,7 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row,
|
||||
|
||||
/* When drawing over the right halve of a double-wide char clear out the
|
||||
* left halve. Only needed in a terminal. */
|
||||
if (col > 0 && col < grid->Columns && mb_fix_col(grid, col, row) != col) {
|
||||
if (col > 0 && col < grid->Columns && grid_fix_col(grid, col, row) != col) {
|
||||
schar_from_ascii(grid->ScreenLines[off - 1], ' ');
|
||||
grid->ScreenAttrs[off - 1] = 0;
|
||||
// redraw the previous cell, make it empty
|
||||
@ -5438,10 +5482,11 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row,
|
||||
clear_next_cell = false;
|
||||
} else if ((len < 0 ? ptr[mbyte_blen] == NUL
|
||||
: ptr + mbyte_blen >= text + len)
|
||||
&& ((mbyte_cells == 1 && utf_off2cells(grid, off, max_off) > 1)
|
||||
&& ((mbyte_cells == 1
|
||||
&& grid_off2cells(grid, off, max_off) > 1)
|
||||
|| (mbyte_cells == 2
|
||||
&& utf_off2cells(grid, off, max_off) == 1
|
||||
&& utf_off2cells(grid, off + 1, max_off) > 1))) {
|
||||
&& grid_off2cells(grid, off, max_off) == 1
|
||||
&& grid_off2cells(grid, off + 1, max_off) > 1))) {
|
||||
clear_next_cell = true;
|
||||
}
|
||||
|
||||
@ -5826,10 +5871,11 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col,
|
||||
// out the left halve. When drawing over the left halve of a
|
||||
// double wide-char clear out the right halve. Only needed in a
|
||||
// terminal.
|
||||
if (start_col > 0 && mb_fix_col(grid, start_col, row) != start_col) {
|
||||
if (start_col > 0 && grid_fix_col(grid, start_col, row) != start_col) {
|
||||
grid_puts_len(grid, (char_u *)" ", 1, row, start_col - 1, 0);
|
||||
}
|
||||
if (end_col < grid->Columns && mb_fix_col(grid, end_col, row) != end_col) {
|
||||
if (end_col < grid->Columns
|
||||
&& grid_fix_col(grid, end_col, row) != end_col) {
|
||||
grid_puts_len(grid, (char_u *)" ", 1, row, end_col, 0);
|
||||
}
|
||||
}
|
||||
@ -5936,20 +5982,30 @@ void win_grid_alloc(win_T *wp, int doclear)
|
||||
columns = wp->w_width;
|
||||
}
|
||||
|
||||
if (grid->ScreenLines == NULL
|
||||
// TODO(bfredl): floating windows should force this to true
|
||||
bool want_allocation = ui_is_external(kUIMultigrid);
|
||||
bool has_allocation = (grid->ScreenLines != NULL);
|
||||
|
||||
if ((has_allocation != want_allocation)
|
||||
|| grid->Rows != rows
|
||||
|| grid->Columns != columns) {
|
||||
grid_alloc(grid, rows, columns, doclear);
|
||||
win_free_lsize(wp);
|
||||
win_alloc_lines(wp);
|
||||
if (want_allocation) {
|
||||
grid_alloc(grid, rows, columns, !doclear);
|
||||
win_free_lsize(wp);
|
||||
win_alloc_lines(wp);
|
||||
} else {
|
||||
// Single grid mode, all rendering will be redirected to default_grid.
|
||||
// Only keep track of the size and offset of the window.
|
||||
grid_free(grid);
|
||||
grid->Rows = rows;
|
||||
grid->Columns = columns;
|
||||
}
|
||||
grid->was_resized = true;
|
||||
}
|
||||
|
||||
grid->OffsetRow = wp->w_winrow;
|
||||
grid->OffsetColumn = wp->w_wincol;
|
||||
|
||||
grid_assign_handle(grid);
|
||||
|
||||
// send grid resize event if:
|
||||
// - a grid was just resized
|
||||
// - screen_resize was called and all grid sizes must be sent
|
||||
@ -6116,17 +6172,39 @@ void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy)
|
||||
}
|
||||
}
|
||||
}
|
||||
free_screengrid(grid);
|
||||
grid_free(grid);
|
||||
*grid = new;
|
||||
|
||||
// Share a single scratch buffer for all grids, by
|
||||
// ensuring it is as wide as the widest grid.
|
||||
if (linebuf_size < (size_t)columns) {
|
||||
xfree(linebuf_char);
|
||||
xfree(linebuf_attr);
|
||||
linebuf_char = xmalloc(columns * sizeof(schar_T));
|
||||
linebuf_attr = xmalloc(columns * sizeof(sattr_T));
|
||||
linebuf_size = columns;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void free_screengrid(ScreenGrid *grid)
|
||||
void grid_free(ScreenGrid *grid)
|
||||
{
|
||||
xfree(grid->ScreenLines);
|
||||
xfree(grid->ScreenAttrs);
|
||||
xfree(grid->LineOffset);
|
||||
xfree(grid->LineWraps);
|
||||
|
||||
grid->ScreenLines = NULL;
|
||||
grid->ScreenAttrs = NULL;
|
||||
grid->LineOffset = NULL;
|
||||
grid->LineWraps = NULL;
|
||||
}
|
||||
|
||||
/// Doesn't allow reinit, so must only be called by free_all_mem!
|
||||
void screen_free_all_mem(void)
|
||||
{
|
||||
grid_free(&default_grid);
|
||||
xfree(linebuf_char);
|
||||
xfree(linebuf_attr);
|
||||
}
|
||||
|
||||
/// Clear tab_page_click_defs table
|
||||
|
@ -3990,7 +3990,7 @@ void win_free_grid(win_T *wp, bool reinit)
|
||||
ui_call_grid_destroy(wp->w_grid.handle);
|
||||
wp->w_grid.handle = 0;
|
||||
}
|
||||
free_screengrid(&wp->w_grid);
|
||||
grid_free(&wp->w_grid);
|
||||
if (reinit) {
|
||||
// if a float is turned into a split and back into a float, the grid
|
||||
// data structure will be reused
|
||||
@ -4100,7 +4100,7 @@ void win_alloc_lines(win_T *wp)
|
||||
{
|
||||
wp->w_lines_valid = 0;
|
||||
assert(wp->w_grid.Rows >= 0);
|
||||
wp->w_lines = xcalloc(wp->w_grid.Rows + 1, sizeof(wline_T));
|
||||
wp->w_lines = xcalloc(MAX(wp->w_grid.Rows + 1, Rows), sizeof(wline_T));
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user