diff options
author | Björn Linse <bjorn.linse@gmail.com> | 2017-11-05 11:33:31 +0100 |
---|---|---|
committer | Björn Linse <bjorn.linse@gmail.com> | 2018-12-31 12:44:21 +0100 |
commit | c9b559a0308714ef8ad396eb340a4af580e44d74 (patch) | |
tree | 922c689e4ebe9d4556c283a7eb5d82dc8966cdcd /src | |
parent | ccbcd390d42d33a15f15c29fab5d6076a6d3ac08 (diff) | |
download | rneovim-c9b559a0308714ef8ad396eb340a4af580e44d74.tar.gz rneovim-c9b559a0308714ef8ad396eb340a4af580e44d74.tar.bz2 rneovim-c9b559a0308714ef8ad396eb340a4af580e44d74.zip |
multigrid: introduce grid abstraction
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/globals.h | 8 | ||||
-rw-r--r-- | src/nvim/mbyte.h | 7 | ||||
-rw-r--r-- | src/nvim/memory.c | 4 | ||||
-rw-r--r-- | src/nvim/move.c | 5 | ||||
-rw-r--r-- | src/nvim/screen.c | 123 | ||||
-rw-r--r-- | src/nvim/types.h | 18 |
6 files changed, 94 insertions, 71 deletions
diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 04ff1320ce..097c71928c 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -128,12 +128,6 @@ typedef off_t off_T; # endif #endif -/* - * The characters and attributes cached for the screen. - */ -typedef char_u schar_T[(MAX_MCO+1) * 4 + 1]; -typedef int16_t sattr_T; - /// ScreenLines[] contains a copy of the whole screen, as it currently is /// displayed. It is a single block of screen cells, the size of the screen /// plus one line. The extra line used as a buffer while redrawing a window @@ -167,6 +161,8 @@ EXTERN char_u *LineWraps INIT(= NULL); /* line wraps to next line */ EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */ EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */ +EXTERN ScreenGrid default_grid INIT(= { 0 }); + /* * When vgetc() is called, it sets mod_mask to the set of modifiers that are * held down based on the MOD_MASK_* symbols that are read first. diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h index 70073a8540..ed48705c6d 100644 --- a/src/nvim/mbyte.h +++ b/src/nvim/mbyte.h @@ -19,13 +19,6 @@ #define MB_BYTE2LEN(b) utf8len_tab[b] #define MB_BYTE2LEN_CHECK(b) (((b) < 0 || (b) > 255) ? 1 : utf8len_tab[b]) -/// Maximum value for 'maxcombine' -/// -/// At most that number of composing characters may be attached to the leading -/// character by various `utfc_*` functions. Note that some functions do not -/// have this limit. -enum { MAX_MCO = 6 }; - // max length of an unicode char #define MB_MAXCHAR 6 diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 6b96a3b070..ce914b43f9 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -698,8 +698,8 @@ void free_all_mem(void) buf = bufref_valid(&bufref) ? nextbuf : firstbuf; } - /* screenlines (can't display anything now!) */ - free_screenlines(); + // free screenlines (can't display anything now!) + free_screengrid(&default_grid); clear_hl_tables(false); list_free_log(); diff --git a/src/nvim/move.c b/src/nvim/move.c index 3a29851ee6..bb44b458e8 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -149,9 +149,12 @@ void update_topline(void) bool check_botline = false; long save_so = p_so; + // need to have w_grid.Rows/Columns updated + win_grid_alloc(curwin, false); + // If there is no valid screen and when the window height is zero just use // the cursor line. - if (!screen_valid(true) || curwin->w_height == 0) { + if (!screen_valid(true) || curwin->w_grid.Rows == 0) { curwin->w_topline = curwin->w_cursor.lnum; curwin->w_botline = curwin->w_topline; curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP; diff --git a/src/nvim/screen.c b/src/nvim/screen.c index d095bdb7c8..fcb225084d 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -130,6 +130,10 @@ static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */ static schar_T *current_ScreenLine; StlClickDefinition *tab_page_click_defs = NULL; + +int grid_Rows = 0; +int grid_Columns = 0; + long tab_page_click_defs_size = 0; // for line_putchar. Contains the state that needs to be remembered from @@ -5883,8 +5887,6 @@ int screen_valid(int doclear) */ void screenalloc(bool doclear) { - int new_row, old_row; - int len; static bool entered = false; // avoid recursiveness int retry_count = 0; @@ -5892,7 +5894,7 @@ retry: // Allocation of the screen buffers is done only when the size changes and // when Rows and Columns have been set and we have started doing full // screen stuff. - if ((ScreenLines != NULL + if ((default_grid.ScreenLines != NULL && Rows == screen_Rows && Columns == screen_Columns ) @@ -5938,13 +5940,7 @@ retry: if (aucmd_win != NULL) win_free_lsize(aucmd_win); - // Allocate space for an extra row as scratch space, so that a redrawn - // line can be compared with the previous screen line state. - size_t ncells = (size_t)((Rows+1) * Columns); - schar_T *new_ScreenLines = xmalloc(ncells * sizeof(*new_ScreenLines)); - sattr_T *new_ScreenAttrs = xmalloc(ncells * sizeof(*new_ScreenAttrs)); - unsigned *new_LineOffset = xmalloc((size_t)(Rows * sizeof(*new_LineOffset))); - char_u *new_LineWraps = xmalloc((size_t)(Rows * sizeof(*new_LineWraps))); + alloc_grid(&default_grid, Rows, Columns, !doclear); StlClickDefinition *new_tab_page_click_defs = xcalloc( (size_t)Columns, sizeof(*new_tab_page_click_defs)); @@ -5955,46 +5951,11 @@ retry: win_alloc_lines(aucmd_win); } - for (new_row = 0; new_row < Rows; new_row++) { - new_LineOffset[new_row] = new_row * Columns; - new_LineWraps[new_row] = false; - - // If the screen is not going to be cleared, copy as much as - // possible from the old screen to the new one and clear the rest - // (used when resizing the window at the "--more--" prompt or when - // executing an external command, for the GUI). - if (!doclear) { - for (int col = 0; col < Columns; col++) { - schar_from_ascii(new_ScreenLines[new_row * Columns + col], ' '); - } - memset(new_ScreenAttrs + new_row * Columns, - 0, (size_t)Columns * sizeof(*new_ScreenAttrs)); - old_row = new_row + (screen_Rows - Rows); - if (old_row >= 0 && ScreenLines != NULL) { - if (screen_Columns < Columns) { - len = screen_Columns; - } else { - len = Columns; - } - - memmove(new_ScreenLines + new_LineOffset[new_row], - ScreenLines + LineOffset[old_row], - (size_t)len * sizeof(schar_T)); - memmove(new_ScreenAttrs + new_LineOffset[new_row], - ScreenAttrs + LineOffset[old_row], - (size_t)len * sizeof(new_ScreenAttrs[0])); - } - } - } - // Use the last line of the screen for the current line. - current_ScreenLine = new_ScreenLines + Rows * Columns; + clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size); + xfree(tab_page_click_defs); - free_screenlines(); + set_screengrid(&default_grid); - ScreenLines = new_ScreenLines; - ScreenAttrs = new_ScreenAttrs; - LineOffset = new_LineOffset; - LineWraps = new_LineWraps; tab_page_click_defs = new_tab_page_click_defs; tab_page_click_defs_size = Columns; @@ -6023,14 +5984,66 @@ retry: } } -void free_screenlines(void) +void alloc_grid(ScreenGrid *grid, int Rows, int Columns, bool copy) { - xfree(ScreenLines); - xfree(ScreenAttrs); - xfree(LineOffset); - xfree(LineWraps); - clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size); - xfree(tab_page_click_defs); + int new_row, old_row; + ScreenGrid new = { 0 }; + + size_t ncells = (size_t)((Rows+1) * Columns); + new.ScreenLines = xmalloc(ncells * sizeof(schar_T)); + new.ScreenAttrs = xmalloc(ncells * sizeof(sattr_T)); + new.LineOffset = xmalloc((size_t)(Rows * sizeof(unsigned))); + new.LineWraps = xmalloc((size_t)(Rows * sizeof(char_u))); + + new.Rows = Rows; + new.Columns = Columns; + + for (new_row = 0; new_row < Rows; new_row++) { + new.LineOffset[new_row] = new_row * Columns; + new.LineWraps[new_row] = false; + if (copy) { + // If the screen is not going to be cleared, copy as much as + // possible from the old screen to the new one and clear the rest + // (used when resizing the window at the "--more--" prompt or when + // executing an external command, for the GUI). + memset(new.ScreenLines + new_row * Columns, + ' ', (size_t)Columns * sizeof(schar_T)); + memset(new.ScreenAttrs + new_row * Columns, + 0, (size_t)Columns * sizeof(sattr_T)); + old_row = new_row + (grid->Rows - Rows); + if (old_row >= 0 && grid->ScreenLines != NULL) { + int len = MIN(grid->Columns, Columns); + memmove(new.ScreenLines + new.LineOffset[new_row], + grid->ScreenLines + grid->LineOffset[old_row], + (size_t)len * sizeof(schar_T)); + memmove(new.ScreenAttrs + new.LineOffset[new_row], + grid->ScreenAttrs + grid->LineOffset[old_row], + (size_t)len * sizeof(sattr_T)); + } + } + } + free_screengrid(grid); + *grid = new; +} + + +void free_screengrid(ScreenGrid *grid) +{ + xfree(grid->ScreenLines); + xfree(grid->ScreenAttrs); + xfree(grid->LineOffset); + xfree(grid->LineWraps); +} + +void set_screengrid(ScreenGrid *grid) +{ + ScreenLines = grid->ScreenLines; + ScreenAttrs = grid->ScreenAttrs; + LineOffset = grid->LineOffset; + LineWraps = grid->LineWraps; + grid_Rows = grid->Rows; + grid_Columns = grid->Columns; + current_ScreenLine = ScreenLines + grid_Rows * grid_Columns; } /// Clear tab_page_click_defs table diff --git a/src/nvim/types.h b/src/nvim/types.h index 317bead3bb..84634b1cb7 100644 --- a/src/nvim/types.h +++ b/src/nvim/types.h @@ -15,4 +15,22 @@ typedef uint32_t u8char_T; typedef struct expand expand_T; +#define MAX_MCO 6 // maximum value for 'maxcombine' + + +// The characters and attributes cached for the screen. +typedef char_u schar_T[(MAX_MCO+1) * 4 + 1]; +typedef int16_t sattr_T; + +// TODO(bfredl): find me a good home +typedef struct { + schar_T *ScreenLines; + sattr_T *ScreenAttrs; + unsigned *LineOffset; + char_u *LineWraps; + + int Rows; + int Columns; +} ScreenGrid; + #endif // NVIM_TYPES_H |