handle arbitary target glyph widths in ncplane_put #1873

This commit is contained in:
nick black 2021-07-26 19:39:47 -04:00
parent 7b5f4175eb
commit ee6de771e4
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
2 changed files with 27 additions and 16 deletions

View File

@ -13,6 +13,9 @@ rearrangements of Notcurses.
only been marked deprecated. New functions `ncdirect_get()` and only been marked deprecated. New functions `ncdirect_get()` and
`notcurses_get()` elide this parameter entirely, and ought be used in `notcurses_get()` elide this parameter entirely, and ought be used in
new code. All callers have been updated. new code. All callers have been updated.
* Added `nccell_cols()`, which is just `nccell_width()` except it doesn't
require the first `const ncplane*` argument, and it's `static inline`.
`nccell_width()` has been deprecated, and will be removed in ABI3.
* 2.3.11 (2021-07-20) * 2.3.11 (2021-07-20)
* Notcurses now requires libz to build. In exchange, it can now generate * Notcurses now requires libz to build. In exchange, it can now generate

View File

@ -1559,7 +1559,7 @@ void scroll_down(ncplane* n){
} }
int nccell_width(const ncplane* n __attribute__ ((unused)), const nccell* c){ int nccell_width(const ncplane* n __attribute__ ((unused)), const nccell* c){
return c->width ? c->width : 1; return nccell_cols(c);
} }
int nccell_load(ncplane* n, nccell* c, const char* gcluster){ int nccell_load(ncplane* n, nccell* c, const char* gcluster){
@ -1619,18 +1619,25 @@ ncplane_put(ncplane* n, int y, int x, const char* egc, int cols,
return 0; return 0;
} }
// A wide character obliterates anything to its immediate right (and marks // A wide character obliterates anything to its immediate right (and marks
// that cell as wide). Any character placed atop one half of a wide character // that cell as wide). Any character placed atop one cell of a wide character
// obliterates the other half. Note that a wide char can thus obliterate two // obliterates all cells. Note that a two-cell glyph can thus obliterate two
// wide chars, totalling four columns. // other two-cell glyphs, totalling four columns.
nccell* targ = ncplane_cell_ref_yx(n, n->y, n->x); nccell* targ = ncplane_cell_ref_yx(n, n->y, n->x);
if(n->x > 0){ // we're always starting on the leftmost cell of our output glyph. check the
if(nccell_wide_right_p(targ)){ // target, and find the leftmost cell of the glyph it will be displacing.
// right half will never be on the first column of a row // obliterate as we go along.
nccell_obliterate(n, &n->fb[nfbcellidx(n, n->y, n->x - 1)]); int idx = n->x;
}else if(nccell_wide_left_p(targ)){ nccell* lmc = targ;
// left half will never be on the last column of a row while(nccell_wide_right_p(lmc)){
nccell_obliterate(n, &n->fb[nfbcellidx(n, n->y, n->x + 1)]); nccell_obliterate(n, &n->fb[nfbcellidx(n, n->y, idx)]);
} lmc = ncplane_cell_ref_yx(n, n->y, --idx);
}
// we're now on the leftmost cell of the target glyph.
int twidth = nccell_cols(targ);
nccell_release(n, &n->fb[nfbcellidx(n, n->y, idx)]);
twidth -= n->x - idx;
while(--twidth > 0){
nccell_obliterate(n, &n->fb[nfbcellidx(n, n->y, n->x + twidth)]);
} }
targ->stylemask = stylemask; targ->stylemask = stylemask;
targ->channels = channels; targ->channels = channels;
@ -1642,10 +1649,11 @@ ncplane_put(ncplane* n, int y, int x, const char* egc, int cols,
++n->x; ++n->x;
for(int i = 1 ; i < cols ; ++i){ for(int i = 1 ; i < cols ; ++i){
nccell* candidate = &n->fb[nfbcellidx(n, n->y, n->x)]; nccell* candidate = &n->fb[nfbcellidx(n, n->y, n->x)];
if(nccell_wide_left_p(candidate)){ int off = nccell_cols(candidate);
nccell_obliterate(n, &n->fb[nfbcellidx(n, n->y, n->x + 1)]); nccell_release(n, &n->fb[nfbcellidx(n, n->y, n->x)]);
while(--off > 0){
nccell_obliterate(n, &n->fb[nfbcellidx(n, n->y, n->x + off)]);
} }
nccell_release(n, candidate);
candidate->channels = targ->channels; candidate->channels = targ->channels;
candidate->stylemask = targ->stylemask; candidate->stylemask = targ->stylemask;
candidate->width = targ->width; candidate->width = targ->width;
@ -1655,7 +1663,7 @@ ncplane_put(ncplane* n, int y, int x, const char* egc, int cols,
} }
int ncplane_putc_yx(ncplane* n, int y, int x, const nccell* c){ int ncplane_putc_yx(ncplane* n, int y, int x, const nccell* c){
const int cols = nccell_width(n, c); const int cols = nccell_cols(c);
const char* egc = nccell_extended_gcluster(n, c); const char* egc = nccell_extended_gcluster(n, c);
return ncplane_put(n, y, x, egc, cols, c->stylemask, c->channels, strlen(egc)); return ncplane_put(n, y, x, egc, cols, c->stylemask, c->channels, strlen(egc));
} }