mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
handle arbitary target glyph widths in ncplane_put #1873
This commit is contained in:
parent
7b5f4175eb
commit
ee6de771e4
3
NEWS.md
3
NEWS.md
@ -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
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user