interpret logical plane line via scrolled_row() #443

This commit is contained in:
nick black 2020-04-14 15:33:58 -04:00 committed by Nick Black
parent 40fd887012
commit 40067c0ccd
3 changed files with 14 additions and 1 deletions

View File

@ -57,8 +57,13 @@ struct esctrie;
// A plane may be partially or wholly offscreen--this might occur if the
// screen is resized, for example. Offscreen portions will not be rendered.
// Accesses beyond the borders of a panel, however, are errors.
//
// The framebuffer 'fb' is a set of rows. For scrolling, we interpret it as a
// circular buffer of rows. 'logrow' is the index of the row at the logical top
// of the plane.
typedef struct ncplane {
cell* fb; // "framebuffer" of character cells
int logrow; // logical top row, starts at 0, add one for each scroll
int x, y; // current cursor location within this plane
int absx, absy; // origin of the plane relative to the screen
int lenx, leny; // size of the plane, [0..len{x,y}) is addressable

View File

@ -286,6 +286,7 @@ ncplane_create(notcurses* nc, ncplane* n, int rows, int cols,
p->leny = rows;
p->lenx = cols;
p->x = p->y = 0;
p->logrow = 0;
if( (p->bound = n) ){
p->absx = xoff + n->absx;
p->absy = yoff + n->absy;

View File

@ -233,6 +233,13 @@ lock_in_highcontrast(cell* targc, struct crender* crender){
}
}
// taking in a desired true row of the plane, find the line within the
// plane's framebuffer, taking into account the current scrolling state.
static inline int
scrolled_row(const ncplane* p, int y){
return (y + p->logrow) % p->leny;
}
// Paints a single ncplane into the provided scratch framebuffer 'fb', and
// ultimately 'lastframe' (we can't always write directly into 'lastframe',
// because we need build state to solve certain cells, and need compare their
@ -276,7 +283,7 @@ paint(ncplane* p, cell* lastframe, struct crender* rvec,
continue;
}
struct crender* crender = &rvec[fbcellidx(absy, dstlenx, absx)];
const cell* vis = &p->fb[nfbcellidx(p, y, x)];
const cell* vis = &p->fb[nfbcellidx(p, scrolled_row(p, y), x)];
// if we never loaded any content into the cell (or obliterated it by
// writing in a zero), use the plane's base cell.
if(vis->gcluster == 0 && !cell_wide_right_p(vis)){