aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ui_compositor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ui_compositor.c')
-rw-r--r--src/nvim/ui_compositor.c84
1 files changed, 55 insertions, 29 deletions
diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c
index 2ca0d1a6eb..9e0c44f3c2 100644
--- a/src/nvim/ui_compositor.c
+++ b/src/nvim/ui_compositor.c
@@ -217,8 +217,16 @@ static void ui_comp_grid_cursor_goto(UI *ui, Integer grid_handle,
/// do something more efficient (where efficiency means smaller deltas to
/// the downstream UI.)
static void compose_line(Integer row, Integer startcol, Integer endcol,
- bool wrap)
+ LineFlags flags)
{
+ // in case we start on the right half of a double-width char, we need to
+ // check the left half. But skip it in output if it wasn't doublewidth.
+ int skip = 0;
+ if (startcol > 0 && (flags & kLineFlagInvalid)) {
+ startcol--;
+ skip = 1;
+ }
+
int col = (int)startcol;
ScreenGrid *grid = NULL;
@@ -247,15 +255,37 @@ static void compose_line(Integer row, Integer startcol, Integer endcol,
+ (size_t)(col-grid->comp_col);
memcpy(linebuf+(col-startcol), grid->chars+off, n * sizeof(*linebuf));
memcpy(attrbuf+(col-startcol), grid->attrs+off, n * sizeof(*attrbuf));
+
+ // Tricky: if overlap caused a doublewidth char to get cut-off, must
+ // replace the visible half with a space.
+ if (linebuf[col-startcol][0] == NUL) {
+ linebuf[col-startcol][0] = ' ';
+ linebuf[col-startcol][1] = NUL;
+ } else if (n > 1 && linebuf[col-startcol+1][0] == NUL) {
+ skip = 0;
+ }
+ if (grid->comp_col+grid->Columns > until
+ && grid->chars[off+n][0] == NUL) {
+ linebuf[until-1-startcol][0] = ' ';
+ linebuf[until-1-startcol][1] = '\0';
+ if (col == startcol && n == 1) {
+ skip = 0;
+ }
+ }
col = until;
}
assert(endcol <= chk_width);
assert(row < chk_height);
- // TODO(bfredl): too conservative, need check
- // grid->line_wraps if grid->Width == Width
- wrap = wrap && grid && grid->handle == 1;
- ui_composed_call_raw_line(1, row, startcol, endcol, endcol, 0, wrap,
- (const schar_T *)linebuf, (const sattr_T *)attrbuf);
+
+ if (!(grid && grid == &default_grid)) {
+ // TODO(bfredl): too conservative, need check
+ // grid->line_wraps if grid->Width == Width
+ flags = flags & ~kLineFlagWrap;
+ }
+
+ ui_composed_call_raw_line(1, row, startcol+skip, endcol, endcol, 0, flags,
+ (const schar_T *)linebuf+skip,
+ (const sattr_T *)attrbuf+skip);
}
static void compose_area(Integer startrow, Integer endrow,
@@ -264,39 +294,35 @@ static void compose_area(Integer startrow, Integer endrow,
endrow = MIN(endrow, default_grid.Rows);
endcol = MIN(endcol, default_grid.Columns);
for (int r = (int)startrow; r < endrow; r++) {
- compose_line(r, startcol, endcol, false);
+ compose_line(r, startcol, endcol, kLineFlagInvalid);
}
}
-static void draw_line(ScreenGrid *grid, Integer row, Integer startcol,
- Integer endcol, Integer clearcol, Integer clearattr,
- bool wrap, const schar_T *chunk, const sattr_T *attrs)
-{
- row += grid->comp_row;
- startcol += grid->comp_col;
- endcol += grid->comp_col;
- clearcol += grid->comp_col;
- wrap = wrap && grid->handle == 1;
- assert(clearcol <= default_grid.Columns);
- if (kv_size(layers) > grid->comp_index+1) {
- compose_line(row, startcol, clearcol, wrap);
- } else {
- ui_composed_call_raw_line(1, row, startcol, endcol, clearcol, clearattr,
- wrap, chunk, attrs);
- }
-}
-
static void ui_comp_raw_line(UI *ui, Integer grid, Integer row,
Integer startcol, Integer endcol,
- Integer clearcol, Integer clearattr, bool wrap,
- const schar_T *chunk, const sattr_T *attrs)
+ Integer clearcol, Integer clearattr,
+ LineFlags flags, const schar_T *chunk,
+ const sattr_T *attrs)
{
if (!ui_comp_should_draw() || !ui_comp_set_grid((int)grid)) {
return;
}
- draw_line(curgrid, row, startcol, endcol, clearcol, clearattr, wrap, chunk,
- attrs);
+
+ row += curgrid->comp_row;
+ startcol += curgrid->comp_col;
+ endcol += curgrid->comp_col;
+ clearcol += curgrid->comp_col;
+ if (curgrid != &default_grid) {
+ flags = flags & ~kLineFlagWrap;
+ }
+ assert(clearcol <= default_grid.Columns);
+ if (flags & kLineFlagInvalid || kv_size(layers) > curgrid->comp_index+1) {
+ compose_line(row, startcol, clearcol, flags);
+ } else {
+ ui_composed_call_raw_line(1, row, startcol, endcol, clearcol, clearattr,
+ flags, chunk, attrs);
+ }
}
/// The screen is invalid and will soon be cleared