mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
normalize lenghts for line-drawing functions #1696
This commit is contained in:
parent
d80884ea48
commit
37f077a653
4
NEWS.md
4
NEWS.md
@ -16,7 +16,9 @@ rearrangements of Notcurses.
|
||||
functions. Lengths are now `unsigned` as opposed to `int`. Where -1 was
|
||||
being used to indicate "everything", 0 is now required. This affects
|
||||
`ncplane_as_rgba()`, `ncplane_contents()`, and `ncvisual_from_plane()`,
|
||||
which all used -1.
|
||||
which all used -1. A length of zero passed to line-drawing functions is
|
||||
now an error. Several line-drawing functions now reliably return errors
|
||||
as opposed to short successes.
|
||||
* `ncvisual_geom()` has been introduced, using the `ncvgeom` struct
|
||||
introduced for direct mode. This allows complete statement of geometry
|
||||
for an `ncvisual`. It replaces `ncvisual_blitter_geom()`, which has been
|
||||
|
24
USAGE.md
24
USAGE.md
@ -526,10 +526,11 @@ int ncdirect_putegc(struct ncdirect* nc, uint64_t channels,
|
||||
// horizontal line, |len| cannot exceed the screen width minus the cursor's
|
||||
// offset. For a vertical line, it may be as long as you'd like; the screen
|
||||
// will scroll as necessary. All lines start at the current cursor position.
|
||||
int ncdirect_hline_interp(struct ncdirect* n, const char* egc, int len,
|
||||
uint64_t h1, uint64_t h2);
|
||||
int ncdirect_vline_interp(struct ncdirect* n, const char* egc, int len,
|
||||
uint64_t h1, uint64_t h2);
|
||||
// A length of 0 is an error, resulting in a return of -1.
|
||||
int ncdirect_hline_interp(struct ncdirect* n, const char* egc,
|
||||
unsigned len, uint64_t h1, uint64_t h2);
|
||||
int ncdirect_vline_interp(struct ncdirect* n, const char* egc,
|
||||
unsigned len, uint64_t h1, uint64_t h2);
|
||||
|
||||
// Draw a box with its upper-left corner at the current cursor position, having
|
||||
// dimensions |ylen|x|xlen|. See ncplane_box() for more information. The
|
||||
@ -1499,21 +1500,20 @@ on both sides. Boxes allow fairly detailed specification of how they're drawn.
|
||||
// current cursor position. The cursor will end at the cell following the last
|
||||
// cell output (even, perhaps counter-intuitively, when drawing vertical
|
||||
// lines), just as if ncplane_putc() was called at that spot. Return the
|
||||
// number of cells drawn on success. On error, return the negative number of
|
||||
// cells drawn.
|
||||
int ncplane_hline_interp(struct ncplane* n, const nccell* c, int len,
|
||||
uint64_t c1, uint64_t c2);
|
||||
// number of cells drawn on success. A length of 0 is an error.
|
||||
int ncplane_hline_interp(struct ncplane* n, const nccell* c,
|
||||
unsigned len, uint64_t c1, uint64_t c2);
|
||||
|
||||
static inline int
|
||||
ncplane_hline(struct ncplane* n, const nccell* c, int len){
|
||||
ncplane_hline(struct ncplane* n, const nccell* c, unsigned len){
|
||||
return ncplane_hline_interp(n, c, len, c->channels, c->channels);
|
||||
}
|
||||
|
||||
int ncplane_vline_interp(struct ncplane* n, const nccell* c, int len,
|
||||
uint64_t c1, uint64_t c2);
|
||||
int ncplane_vline_interp(struct ncplane* n, const nccell* c,
|
||||
unsigned len, uint64_t c1, uint64_t c2);
|
||||
|
||||
static inline int
|
||||
ncplane_vline(struct ncplane* n, const nccell* c, int len){
|
||||
ncplane_vline(struct ncplane* n, const nccell* c, unsigned len){
|
||||
return ncplane_vline_interp(n, c, len, c->channels, c->channels);
|
||||
}
|
||||
|
||||
|
@ -78,9 +78,9 @@ notcurses_direct - minimal notcurses instances for styling text
|
||||
|
||||
**const char* ncdirect_detected_terminal(const struct ncdirect* ***n***);**
|
||||
|
||||
**int ncdirect_hline_interp(struct ncdirect* ***n***, const char* ***egc***, int ***len***, uint64_t ***h1***, uint64_t ***h2***);**
|
||||
**int ncdirect_hline_interp(struct ncdirect* ***n***, const char* ***egc***, unsigned ***len***, uint64_t ***h1***, uint64_t ***h2***);**
|
||||
|
||||
**int ncdirect_vline_interp(struct ncdirect* ***n***, const char* ***egc***, int ***len***, uint64_t ***h1***, uint64_t ***h2***);**
|
||||
**int ncdirect_vline_interp(struct ncdirect* ***n***, const char* ***egc***, unsigned ***len***, uint64_t ***h1***, uint64_t ***h2***);**
|
||||
|
||||
**int ncdirect_box(struct ncdirect* ***n***, uint64_t ***ul***, uint64_t ***ur***, uint64_t ***ll***, uint64_t ***lr***, const wchar_t* ***wchars***, int ***ylen***, int ***xlen***, unsigned ***ctlword***);**
|
||||
|
||||
|
@ -10,13 +10,13 @@ notcurses_lines - operations on lines and boxes
|
||||
|
||||
**#include <notcurses/notcurses.h>**
|
||||
|
||||
**int ncplane_hline_interp(struct ncplane* ***n***, const nccell* ***c***, int ***len***, uint64_t ***c1***, uint64_t ***c2***);**
|
||||
**int ncplane_hline_interp(struct ncplane* ***n***, const nccell* ***c***, unsigned ***len***, uint64_t ***c1***, uint64_t ***c2***);**
|
||||
|
||||
**static inline int ncplane_hline(struct ncplane* ***n***, const nccell* ***c***, int ***len***);**
|
||||
**static inline int ncplane_hline(struct ncplane* ***n***, const nccell* ***c***, unsigned ***len***);**
|
||||
|
||||
**int ncplane_vline_interp(struct ncplane* ***n***, const nccell* ***c***, int ***len***, uint64_t ***c1***, uint64_t ***c2***);**
|
||||
**int ncplane_vline_interp(struct ncplane* ***n***, const nccell* ***c***, unsigned ***len***, uint64_t ***c1***, uint64_t ***c2***);**
|
||||
|
||||
**static inline int ncplane_vline(struct ncplane* ***n***, const nccell* ***c***, int ***len***);**
|
||||
**static inline int ncplane_vline(struct ncplane* ***n***, const nccell* ***c***, unsigned ***len***);**
|
||||
|
||||
```c
|
||||
#define NCBOXMASK_TOP 0x0001
|
||||
@ -78,6 +78,10 @@ Box- and line-drawing is unaffected by a plane's scrolling status.
|
||||
**ncplane_format** returns -1 if either **ystop** or **xstop** is less than the
|
||||
current equivalent position, otherwise 0.
|
||||
|
||||
**ncplane_hline_interp**, **ncplane_hline**, **ncplane_vline_interp**, and
|
||||
**ncplane_vline** all return the number of glyphs drawn on success, or -1
|
||||
on failure. Passing a length of 0 is an error.
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
**notcurses(3)**,
|
||||
|
@ -263,13 +263,13 @@ API const nccapabilities* ncdirect_capabilities(const struct ncdirect* n)
|
||||
// horizontal line, |len| cannot exceed the screen width minus the cursor's
|
||||
// offset. For a vertical line, it may be as long as you'd like; the screen
|
||||
// will scroll as necessary. All lines start at the current cursor position.
|
||||
API int ncdirect_hline_interp(struct ncdirect* n, const char* egc, int len,
|
||||
uint64_t h1, uint64_t h2)
|
||||
__attribute__ ((nonnull (1)));
|
||||
API int ncdirect_hline_interp(struct ncdirect* n, const char* egc,
|
||||
unsigned len, uint64_t h1, uint64_t h2)
|
||||
__attribute__ ((nonnull (1, 2)));
|
||||
|
||||
API int ncdirect_vline_interp(struct ncdirect* n, const char* egc, int len,
|
||||
uint64_t h1, uint64_t h2)
|
||||
__attribute__ ((nonnull (1)));
|
||||
API int ncdirect_vline_interp(struct ncdirect* n, const char* egc,
|
||||
unsigned len, uint64_t h1, uint64_t h2)
|
||||
__attribute__ ((nonnull (1, 2)));
|
||||
|
||||
// Draw a box with its upper-left corner at the current cursor position, having
|
||||
// dimensions |ylen|x|xlen|. See ncplane_box() for more information. The
|
||||
@ -278,7 +278,7 @@ API int ncdirect_vline_interp(struct ncdirect* n, const char* egc, int len,
|
||||
API int ncdirect_box(struct ncdirect* n, uint64_t ul, uint64_t ur,
|
||||
uint64_t ll, uint64_t lr, const wchar_t* wchars,
|
||||
int ylen, int xlen, unsigned ctlword)
|
||||
__attribute__ ((nonnull (1)));
|
||||
__attribute__ ((nonnull (1, 6)));
|
||||
|
||||
__attribute__ ((nonnull (1))) static inline int
|
||||
ncdirect_light_box(struct ncdirect* n, uint64_t ul, uint64_t ur,
|
||||
|
@ -2156,20 +2156,22 @@ API int ncplane_puttext(struct ncplane* n, int y, ncalign_e align,
|
||||
// cell output (even, perhaps counter-intuitively, when drawing vertical
|
||||
// lines), just as if ncplane_putc() was called at that spot. Return the
|
||||
// number of cells drawn on success. On error, return the negative number of
|
||||
// cells drawn.
|
||||
API int ncplane_hline_interp(struct ncplane* n, const nccell* c, int len,
|
||||
uint64_t c1, uint64_t c2);
|
||||
// cells drawn. A length of 0 is an error, resulting in a return of -1.
|
||||
API int ncplane_hline_interp(struct ncplane* n, const nccell* c,
|
||||
unsigned len, uint64_t c1, uint64_t c2)
|
||||
__attribute__ ((nonnull (1, 2)));
|
||||
|
||||
static inline int
|
||||
ncplane_hline(struct ncplane* n, const nccell* c, int len){
|
||||
__attribute__ ((nonnull (1, 2))) static inline int
|
||||
ncplane_hline(struct ncplane* n, const nccell* c, unsigned len){
|
||||
return ncplane_hline_interp(n, c, len, c->channels, c->channels);
|
||||
}
|
||||
|
||||
API int ncplane_vline_interp(struct ncplane* n, const nccell* c, int len,
|
||||
uint64_t c1, uint64_t c2);
|
||||
API int ncplane_vline_interp(struct ncplane* n, const nccell* c,
|
||||
unsigned len, uint64_t c1, uint64_t c2)
|
||||
__attribute__ ((nonnull (1, 2)));
|
||||
|
||||
static inline int
|
||||
ncplane_vline(struct ncplane* n, const nccell* c, int len){
|
||||
__attribute__ ((nonnull (1, 2))) static inline int
|
||||
ncplane_vline(struct ncplane* n, const nccell* c, unsigned len){
|
||||
return ncplane_vline_interp(n, c, len, c->channels, c->channels);
|
||||
}
|
||||
|
||||
|
@ -1242,8 +1242,11 @@ int ncdirect_set_bg_default(ncdirect* nc){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ncdirect_hline_interp(ncdirect* n, const char* egc, int len,
|
||||
int ncdirect_hline_interp(ncdirect* n, const char* egc, unsigned len,
|
||||
uint64_t c1, uint64_t c2){
|
||||
if(len == 0){
|
||||
return -1;
|
||||
}
|
||||
unsigned ur, ug, ub;
|
||||
int r1, g1, b1, r2, g2, b2;
|
||||
int br1, bg1, bb1, br2, bg2, bb2;
|
||||
@ -1261,7 +1264,7 @@ int ncdirect_hline_interp(ncdirect* n, const char* egc, int len,
|
||||
int deltbr = br2 - br1;
|
||||
int deltbg = bg2 - bg1;
|
||||
int deltbb = bb2 - bb1;
|
||||
int ret;
|
||||
unsigned ret;
|
||||
bool fgdef = false, bgdef = false;
|
||||
if(ncchannels_fg_default_p(c1) && ncchannels_fg_default_p(c2)){
|
||||
if(ncdirect_set_fg_default(n)){
|
||||
@ -1276,12 +1279,12 @@ int ncdirect_hline_interp(ncdirect* n, const char* egc, int len,
|
||||
bgdef = true;
|
||||
}
|
||||
for(ret = 0 ; ret < len ; ++ret){
|
||||
int r = (deltr * ret) / len + r1;
|
||||
int g = (deltg * ret) / len + g1;
|
||||
int b = (deltb * ret) / len + b1;
|
||||
int br = (deltbr * ret) / len + br1;
|
||||
int bg = (deltbg * ret) / len + bg1;
|
||||
int bb = (deltbb * ret) / len + bb1;
|
||||
int r = (deltr * (int)ret) / (int)len + r1;
|
||||
int g = (deltg * (int)ret) / (int)len + g1;
|
||||
int b = (deltb * (int)ret) / (int)len + b1;
|
||||
int br = (deltbr * (int)ret) / (int)len + br1;
|
||||
int bg = (deltbg * (int)ret) / (int)len + bg1;
|
||||
int bb = (deltbb * (int)ret) / (int)len + bb1;
|
||||
if(!fgdef){
|
||||
ncdirect_set_fg_rgb8(n, r, g, b);
|
||||
}
|
||||
@ -1289,14 +1292,17 @@ int ncdirect_hline_interp(ncdirect* n, const char* egc, int len,
|
||||
ncdirect_set_bg_rgb8(n, br, bg, bb);
|
||||
}
|
||||
if(fprintf(n->ttyfp, "%s", egc) < 0){
|
||||
break;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ncdirect_vline_interp(ncdirect* n, const char* egc, int len,
|
||||
int ncdirect_vline_interp(ncdirect* n, const char* egc, unsigned len,
|
||||
uint64_t c1, uint64_t c2){
|
||||
if(len == 0){
|
||||
return -1;
|
||||
}
|
||||
unsigned ur, ug, ub;
|
||||
int r1, g1, b1, r2, g2, b2;
|
||||
int br1, bg1, bb1, br2, bg2, bb2;
|
||||
@ -1308,13 +1314,13 @@ int ncdirect_vline_interp(ncdirect* n, const char* egc, int len,
|
||||
br1 = ur; bg1 = ug; bb1 = ub;
|
||||
ncchannels_bg_rgb8(c2, &ur, &ug, &ub);
|
||||
br2 = ur; bg2 = ug; bb2 = ub;
|
||||
int deltr = (r2 - r1) / (len + 1);
|
||||
int deltg = (g2 - g1) / (len + 1);
|
||||
int deltb = (b2 - b1) / (len + 1);
|
||||
int deltbr = (br2 - br1) / (len + 1);
|
||||
int deltbg = (bg2 - bg1) / (len + 1);
|
||||
int deltbb = (bb2 - bb1) / (len + 1);
|
||||
int ret;
|
||||
int deltr = (r2 - r1) / ((int)len + 1);
|
||||
int deltg = (g2 - g1) / ((int)len + 1);
|
||||
int deltb = (b2 - b1) / ((int)len + 1);
|
||||
int deltbr = (br2 - br1) / ((int)len + 1);
|
||||
int deltbg = (bg2 - bg1) / ((int)len + 1);
|
||||
int deltbb = (bb2 - bb1) / ((int)len + 1);
|
||||
unsigned ret;
|
||||
bool fgdef = false, bgdef = false;
|
||||
if(ncchannels_fg_default_p(c1) && ncchannels_fg_default_p(c2)){
|
||||
if(ncdirect_set_fg_default(n)){
|
||||
@ -1343,11 +1349,11 @@ int ncdirect_vline_interp(ncdirect* n, const char* egc, int len,
|
||||
ncchannels_set_bg_rgb8(&channels, br1, bg1, bb1);
|
||||
}
|
||||
if(ncdirect_putstr(n, channels, egc) <= 0){
|
||||
break;
|
||||
return -1;
|
||||
}
|
||||
if(len - ret > 1){
|
||||
if(ncdirect_cursor_down(n, 1) || ncdirect_cursor_left(n, 1)){
|
||||
break;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1877,8 +1877,12 @@ int ncplane_vprintf_stained(struct ncplane* n, const char* format, va_list ap){
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ncplane_hline_interp(ncplane* n, const nccell* c, int len,
|
||||
int ncplane_hline_interp(ncplane* n, const nccell* c, unsigned len,
|
||||
uint64_t c1, uint64_t c2){
|
||||
if(len <= 0){
|
||||
logerror("passed invalid length %u\n", len);
|
||||
return -1;
|
||||
}
|
||||
unsigned ur, ug, ub;
|
||||
int r1, g1, b1, r2, g2, b2;
|
||||
int br1, bg1, bb1, br2, bg2, bb2;
|
||||
@ -1896,7 +1900,7 @@ int ncplane_hline_interp(ncplane* n, const nccell* c, int len,
|
||||
int deltbr = br2 - br1;
|
||||
int deltbg = bg2 - bg1;
|
||||
int deltbb = bb2 - bb1;
|
||||
int ret;
|
||||
unsigned ret;
|
||||
nccell dupc = CELL_TRIVIAL_INITIALIZER;
|
||||
if(nccell_duplicate(n, &dupc, c) < 0){
|
||||
return -1;
|
||||
@ -1909,12 +1913,12 @@ int ncplane_hline_interp(ncplane* n, const nccell* c, int len,
|
||||
bgdef = true;
|
||||
}
|
||||
for(ret = 0 ; ret < len ; ++ret){
|
||||
int r = (deltr * ret) / len + r1;
|
||||
int g = (deltg * ret) / len + g1;
|
||||
int b = (deltb * ret) / len + b1;
|
||||
int br = (deltbr * ret) / len + br1;
|
||||
int bg = (deltbg * ret) / len + bg1;
|
||||
int bb = (deltbb * ret) / len + bb1;
|
||||
int r = (deltr * (int)ret) / (int)len + r1;
|
||||
int g = (deltg * (int)ret) / (int)len + g1;
|
||||
int b = (deltb * (int)ret) / (int)len + b1;
|
||||
int br = (deltbr * (int)ret) / (int)len + br1;
|
||||
int bg = (deltbg * (int)ret) / (int)len + bg1;
|
||||
int bb = (deltbb * (int)ret) / (int)len + bb1;
|
||||
if(!fgdef){
|
||||
nccell_set_fg_rgb8(&dupc, r, g, b);
|
||||
}
|
||||
@ -1922,15 +1926,19 @@ int ncplane_hline_interp(ncplane* n, const nccell* c, int len,
|
||||
nccell_set_bg_rgb8(&dupc, br, bg, bb);
|
||||
}
|
||||
if(ncplane_putc(n, &dupc) <= 0){
|
||||
break;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
nccell_release(n, &dupc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ncplane_vline_interp(ncplane* n, const nccell* c, int len,
|
||||
int ncplane_vline_interp(ncplane* n, const nccell* c, unsigned len,
|
||||
uint64_t c1, uint64_t c2){
|
||||
if(len <= 0){
|
||||
logerror("passed invalid length %u\n", len);
|
||||
return -1;
|
||||
}
|
||||
unsigned ur, ug, ub;
|
||||
int r1, g1, b1, r2, g2, b2;
|
||||
int br1, bg1, bb1, br2, bg2, bb2;
|
||||
@ -1942,13 +1950,14 @@ int ncplane_vline_interp(ncplane* n, const nccell* c, int len,
|
||||
br1 = ur; bg1 = ug; bb1 = ub;
|
||||
ncchannels_bg_rgb8(c2, &ur, &ug, &ub);
|
||||
br2 = ur; bg2 = ug; bb2 = ub;
|
||||
int deltr = (r2 - r1) / (len + 1);
|
||||
int deltg = (g2 - g1) / (len + 1);
|
||||
int deltb = (b2 - b1) / (len + 1);
|
||||
int deltbr = (br2 - br1) / (len + 1);
|
||||
int deltbg = (bg2 - bg1) / (len + 1);
|
||||
int deltbb = (bb2 - bb1) / (len + 1);
|
||||
int ret, ypos, xpos;
|
||||
int deltr = (r2 - r1) / ((int)len + 1);
|
||||
int deltg = (g2 - g1) / ((int)len + 1);
|
||||
int deltb = (b2 - b1) / ((int)len + 1);
|
||||
int deltbr = (br2 - br1) / ((int)len + 1);
|
||||
int deltbg = (bg2 - bg1) / ((int)len + 1);
|
||||
int deltbb = (bb2 - bb1) / ((int)len + 1);
|
||||
int ypos, xpos;
|
||||
unsigned ret;
|
||||
ncplane_cursor_yx(n, &ypos, &xpos);
|
||||
nccell dupc = CELL_TRIVIAL_INITIALIZER;
|
||||
if(nccell_duplicate(n, &dupc, c) < 0){
|
||||
@ -1978,7 +1987,7 @@ int ncplane_vline_interp(ncplane* n, const nccell* c, int len,
|
||||
nccell_set_bg_rgb8(&dupc, br1, bg1, bb1);
|
||||
}
|
||||
if(ncplane_putc(n, &dupc) <= 0){
|
||||
break;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
nccell_release(n, &dupc);
|
||||
|
Loading…
x
Reference in New Issue
Block a user