mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 09:09:03 -04:00
ncdirect_hline_interp(), ncdirect_vline_interp(), dirlines PoC #753
This commit is contained in:
parent
750f88b70a
commit
c783244185
1
NEWS.md
1
NEWS.md
@ -11,6 +11,7 @@ rearrangements of Notcurses.
|
|||||||
been purged, as have `min_` and `max_supported_rows` and `_cols`. There
|
been purged, as have `min_` and `max_supported_rows` and `_cols`. There
|
||||||
is no longer any need to provide a pipe/eventfd. `ncreel_touch()`,
|
is no longer any need to provide a pipe/eventfd. `ncreel_touch()`,
|
||||||
`ncreel_del_focused()`, and `ncreel_move()` have been removed.
|
`ncreel_del_focused()`, and `ncreel_move()` have been removed.
|
||||||
|
* Added `ncdirect_hline_interp()` and `ncdirect_vline_interp()`.
|
||||||
|
|
||||||
* 1.6.0 (2020-07-04)
|
* 1.6.0 (2020-07-04)
|
||||||
* Behavior has changed regarding use of the provided `FILE*` (which, when
|
* Behavior has changed regarding use of the provided `FILE*` (which, when
|
||||||
|
37
USAGE.md
37
USAGE.md
@ -47,6 +47,10 @@ supplied a struct of type `notcurses_options`:
|
|||||||
// Get a human-readable string describing the running Notcurses version.
|
// Get a human-readable string describing the running Notcurses version.
|
||||||
const char* notcurses_version(void);
|
const char* notcurses_version(void);
|
||||||
|
|
||||||
|
// Cannot be inline, as we want to get the versions of the actual notcurses
|
||||||
|
// library we loaded, not what we compile against.
|
||||||
|
void notcurses_version_components(int* major, int* minor, int* patch, int* tweak);
|
||||||
|
|
||||||
struct cell; // a coordinate on an ncplane: an EGC plus styling
|
struct cell; // a coordinate on an ncplane: an EGC plus styling
|
||||||
struct ncplane; // a drawable Notcurses surface, composed of cells
|
struct ncplane; // a drawable Notcurses surface, composed of cells
|
||||||
struct notcurses; // Notcurses state for a given terminal, composed of ncplanes
|
struct notcurses; // Notcurses state for a given terminal, composed of ncplanes
|
||||||
@ -263,10 +267,10 @@ bool notcurses_cansixel(const struct notcurses* nc);
|
|||||||
## Direct mode
|
## Direct mode
|
||||||
|
|
||||||
"Direct mode" makes a limited subset of notcurses is available for manipulating
|
"Direct mode" makes a limited subset of notcurses is available for manipulating
|
||||||
typical scrolling or file-backed output. These functions output directly and
|
typical scrolling or file-backed output. Its functions are exported via
|
||||||
immediately to the provided `FILE*`, and `notcurses_render()` is neither
|
`<notcurses/direct.h>`, and output directly and immediately to the provided
|
||||||
supported nor necessary for such an instance. Use `ncdirect_init()` to create a
|
`FILE*`. `notcurses_render()` is neither supported nor necessary for such an
|
||||||
direct mode context:
|
instance. Use `ncdirect_init()` to create a direct mode context:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
struct ncdirect; // minimal state for a terminal
|
struct ncdirect; // minimal state for a terminal
|
||||||
@ -328,6 +332,31 @@ int ncdirect_cursor_left(struct ncdirect* nc, int num);
|
|||||||
int ncdirect_cursor_right(struct ncdirect* nc, int num);
|
int ncdirect_cursor_right(struct ncdirect* nc, int num);
|
||||||
int ncdirect_cursor_down(struct ncdirect* nc, int num);
|
int ncdirect_cursor_down(struct ncdirect* nc, int num);
|
||||||
|
|
||||||
|
// Get the cursor position, when supported. This requires writing to the
|
||||||
|
// terminal, and then reading from it. If the terminal doesn't reply, or
|
||||||
|
// doesn't reply in a way we understand, the results might be deleterious.
|
||||||
|
int ncdirect_cursor_yx(struct ncdirect* n, int* y, int* x);
|
||||||
|
|
||||||
|
// Push or pop the cursor location to the terminal's stack. The depth of this
|
||||||
|
// stack, and indeed its existence, is terminal-dependent.
|
||||||
|
int ncdirect_cursor_push(struct ncdirect* n);
|
||||||
|
int ncdirect_cursor_pop(struct ncdirect* n);
|
||||||
|
|
||||||
|
// Formatted printing (plus alignment relative to the terminal).
|
||||||
|
int ncdirect_printf_aligned(struct ncdirect* n, int y, ncalign_e align,
|
||||||
|
const char* fmt, ...)
|
||||||
|
__attribute__ ((format (printf, 4, 5)));
|
||||||
|
|
||||||
|
// Draw horizontal/vertical lines using the specified channels, interpolating
|
||||||
|
// between them as we go. The EGC may not use more than one column. For a
|
||||||
|
// 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);
|
||||||
|
|
||||||
// Display an image using the specified blitter and scaling. The image may
|
// Display an image using the specified blitter and scaling. The image may
|
||||||
// be arbitrarily many rows -- the output will scroll -- but will only occupy
|
// be arbitrarily many rows -- the output will scroll -- but will only occupy
|
||||||
// the column of the cursor, and those to the right.
|
// the column of the cursor, and those to the right.
|
||||||
|
@ -54,7 +54,7 @@ ncdirect_init - minimal notcurses instances for styling text
|
|||||||
|
|
||||||
**int ncdirect_cursor_down(struct ncdirect* nc, int num);**
|
**int ncdirect_cursor_down(struct ncdirect* nc, int num);**
|
||||||
|
|
||||||
**int ncdirect_putc(struct ncdirect* nc, uint64_t channels, const char* egc);**
|
**int ncdirect_putstr(struct ncdirect* nc, uint64_t channels, const char* utf8);**
|
||||||
|
|
||||||
**nc_err_e ncdirect_render_image(struct ncdirect* n, const char* filename, ncblitter_e blitter, ncscale_e scale);**
|
**nc_err_e ncdirect_render_image(struct ncdirect* n, const char* filename, ncblitter_e blitter, ncscale_e scale);**
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ API int ncdirect_bg_palindex(struct ncdirect* nc, int pidx);
|
|||||||
// more colors than they actually support, downsampling internally.
|
// more colors than they actually support, downsampling internally.
|
||||||
API int ncdirect_palette_size(const struct ncdirect* nc);
|
API int ncdirect_palette_size(const struct ncdirect* nc);
|
||||||
|
|
||||||
// Output the EGC |egc| according to the channels |channels|.
|
// Output the string |utf8| according to the channels |channels|.
|
||||||
API int ncdirect_putc(struct ncdirect* nc, uint64_t channels, const char* egc);
|
API int ncdirect_putstr(struct ncdirect* nc, uint64_t channels, const char* utf8);
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
ncdirect_bg_rgb(struct ncdirect* nc, unsigned r, unsigned g, unsigned b){
|
ncdirect_bg_rgb(struct ncdirect* nc, unsigned r, unsigned g, unsigned b){
|
||||||
@ -87,8 +87,8 @@ API int ncdirect_printf_aligned(struct ncdirect* n, int y, ncalign_e align,
|
|||||||
__attribute__ ((format (printf, 4, 5)));
|
__attribute__ ((format (printf, 4, 5)));
|
||||||
|
|
||||||
// Display an image using the specified blitter and scaling. The image may
|
// Display an image using the specified blitter and scaling. The image may
|
||||||
// // be arbitrarily many rows -- the output will scroll -- but will only occupy
|
// be arbitrarily many rows -- the output will scroll -- but will only occupy
|
||||||
// // the column of the cursor, and those to the right.
|
// the column of the cursor, and those to the right.
|
||||||
API nc_err_e ncdirect_render_image(struct ncdirect* n, const char* filename,
|
API nc_err_e ncdirect_render_image(struct ncdirect* n, const char* filename,
|
||||||
ncalign_e align, ncblitter_e blitter,
|
ncalign_e align, ncblitter_e blitter,
|
||||||
ncscale_e scale);
|
ncscale_e scale);
|
||||||
@ -99,6 +99,16 @@ API int ncdirect_clear(struct ncdirect* nc);
|
|||||||
// Release 'nc' and any associated resources. 0 on success, non-0 on failure.
|
// Release 'nc' and any associated resources. 0 on success, non-0 on failure.
|
||||||
API int ncdirect_stop(struct ncdirect* nc);
|
API int ncdirect_stop(struct ncdirect* nc);
|
||||||
|
|
||||||
|
// Draw horizontal/vertical lines using the specified channels, interpolating
|
||||||
|
// between them as we go. The EGC may not use more than one column. For a
|
||||||
|
// 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);
|
||||||
|
API int ncdirect_vline_interp(struct ncdirect* n, const char* egc, int len,
|
||||||
|
uint64_t h1, uint64_t h2);
|
||||||
|
|
||||||
#undef API
|
#undef API
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -484,7 +484,7 @@ struct ncdirect* ncdirect_init(const char* termtype, FILE* fp);
|
|||||||
int ncdirect_bg_rgb(struct ncdirect* n, unsigned r, unsigned g, unsigned b);
|
int ncdirect_bg_rgb(struct ncdirect* n, unsigned r, unsigned g, unsigned b);
|
||||||
int ncdirect_fg_rgb(struct ncdirect* n, unsigned r, unsigned g, unsigned b);
|
int ncdirect_fg_rgb(struct ncdirect* n, unsigned r, unsigned g, unsigned b);
|
||||||
int ncdirect_palette_size(const struct ncdirect* nc);
|
int ncdirect_palette_size(const struct ncdirect* nc);
|
||||||
int ncdirect_putc(struct ncdirect* nc, uint64_t channels, const char* egc);
|
int ncdirect_putstr(struct ncdirect* nc, uint64_t channels, const char* utf8);
|
||||||
int ncdirect_fg(struct ncdirect* n, unsigned rgb);
|
int ncdirect_fg(struct ncdirect* n, unsigned rgb);
|
||||||
int ncdirect_bg(struct ncdirect* n, unsigned rgb);
|
int ncdirect_bg(struct ncdirect* n, unsigned rgb);
|
||||||
int ncdirect_styles_set(struct ncdirect* n, unsigned stylebits);
|
int ncdirect_styles_set(struct ncdirect* n, unsigned stylebits);
|
||||||
@ -501,6 +501,8 @@ int ncdirect_cursor_up(struct ncdirect* nc, int num);
|
|||||||
int ncdirect_cursor_left(struct ncdirect* nc, int num);
|
int ncdirect_cursor_left(struct ncdirect* nc, int num);
|
||||||
int ncdirect_cursor_right(struct ncdirect* nc, int num);
|
int ncdirect_cursor_right(struct ncdirect* nc, int num);
|
||||||
int ncdirect_cursor_down(struct ncdirect* nc, int num);
|
int ncdirect_cursor_down(struct ncdirect* nc, int num);
|
||||||
|
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);
|
||||||
nc_err_e ncdirect_render_image(struct ncdirect* n, const char* filename, ncalign_e align, ncblitter_e blitter, ncscale_e scale);
|
nc_err_e ncdirect_render_image(struct ncdirect* n, const char* filename, ncalign_e align, ncblitter_e blitter, ncscale_e scale);
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "notcurses/direct.h"
|
#include "notcurses/direct.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
int ncdirect_putc(ncdirect* nc, uint64_t channels, const char* egc){
|
int ncdirect_putstr(ncdirect* nc, uint64_t channels, const char* egc){
|
||||||
if(channels_fg_default_p(channels)){
|
if(channels_fg_default_p(channels)){
|
||||||
if(ncdirect_fg_default(nc)){
|
if(ncdirect_fg_default(nc)){
|
||||||
return -1;
|
return -1;
|
||||||
@ -474,7 +474,7 @@ int ncdirect_stop(ncdirect* nc){
|
|||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
ncdirect_style_emit(ncdirect* n, const char* sgr, unsigned stylebits, FILE* out){
|
ncdirect_style_emit(ncdirect* n, const char* sgr, unsigned stylebits, FILE* out){
|
||||||
if(sgr == NULL){
|
if(sgr == nullptr){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int r = term_emit("sgr", tiparm(sgr, stylebits & NCSTYLE_STANDOUT,
|
int r = term_emit("sgr", tiparm(sgr, stylebits & NCSTYLE_STANDOUT,
|
||||||
@ -536,7 +536,7 @@ int ncdirect_fg_default(ncdirect* nc){
|
|||||||
if(nc->bgdefault){
|
if(nc->bgdefault){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ncdirect_bg(nc, nc->fgrgb);
|
return ncdirect_bg(nc, nc->bgrgb);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -547,7 +547,107 @@ int ncdirect_bg_default(ncdirect* nc){
|
|||||||
if(nc->fgdefault){
|
if(nc->fgdefault){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ncdirect_fg(nc, nc->bgrgb);
|
return ncdirect_fg(nc, nc->fgrgb);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ncdirect_hline_interp(ncdirect* n, const char* egc, int len,
|
||||||
|
uint64_t c1, uint64_t c2){
|
||||||
|
unsigned ur, ug, ub;
|
||||||
|
int r1, g1, b1, r2, g2, b2;
|
||||||
|
int br1, bg1, bb1, br2, bg2, bb2;
|
||||||
|
channels_fg_rgb(c1, &ur, &ug, &ub);
|
||||||
|
r1 = ur; g1 = ug; b1 = ub;
|
||||||
|
channels_fg_rgb(c2, &ur, &ug, &ub);
|
||||||
|
r2 = ur; g2 = ug; b2 = ub;
|
||||||
|
channels_bg_rgb(c1, &ur, &ug, &ub);
|
||||||
|
br1 = ur; bg1 = ug; bb1 = ub;
|
||||||
|
channels_bg_rgb(c2, &ur, &ug, &ub);
|
||||||
|
br2 = ur; bg2 = ug; bb2 = ub;
|
||||||
|
int deltr = r2 - r1;
|
||||||
|
int deltg = g2 - g1;
|
||||||
|
int deltb = b2 - b1;
|
||||||
|
int deltbr = br2 - br1;
|
||||||
|
int deltbg = bg2 - bg1;
|
||||||
|
int deltbb = bb2 - bb1;
|
||||||
|
int ret;
|
||||||
|
bool fgdef = false, bgdef = false;
|
||||||
|
if(channels_fg_default_p(c1) && channels_fg_default_p(c2)){
|
||||||
|
fgdef = true;
|
||||||
|
}
|
||||||
|
if(channels_bg_default_p(c1) && channels_bg_default_p(c2)){
|
||||||
|
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;
|
||||||
|
if(!fgdef){
|
||||||
|
ncdirect_fg_rgb(n, r, g, b);
|
||||||
|
}
|
||||||
|
if(!bgdef){
|
||||||
|
ncdirect_bg_rgb(n, br, bg, bb);
|
||||||
|
}
|
||||||
|
if(fprintf(n->ttyfp, "%s", egc) < 0){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ncdirect_vline_interp(ncdirect* n, const char* egc, int len,
|
||||||
|
uint64_t c1, uint64_t c2){
|
||||||
|
unsigned ur, ug, ub;
|
||||||
|
int r1, g1, b1, r2, g2, b2;
|
||||||
|
int br1, bg1, bb1, br2, bg2, bb2;
|
||||||
|
channels_fg_rgb(c1, &ur, &ug, &ub);
|
||||||
|
r1 = ur; g1 = ug; b1 = ub;
|
||||||
|
channels_fg_rgb(c2, &ur, &ug, &ub);
|
||||||
|
r2 = ur; g2 = ug; b2 = ub;
|
||||||
|
channels_bg_rgb(c1, &ur, &ug, &ub);
|
||||||
|
br1 = ur; bg1 = ug; bb1 = ub;
|
||||||
|
channels_bg_rgb(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;
|
||||||
|
bool fgdef = false, bgdef = false;
|
||||||
|
if(channels_fg_default_p(c1) && channels_fg_default_p(c2)){
|
||||||
|
fgdef = true;
|
||||||
|
}
|
||||||
|
if(channels_bg_default_p(c1) && channels_bg_default_p(c2)){
|
||||||
|
bgdef = true;
|
||||||
|
}
|
||||||
|
for(ret = 0 ; ret < len ; ++ret){
|
||||||
|
r1 += deltr;
|
||||||
|
g1 += deltg;
|
||||||
|
b1 += deltb;
|
||||||
|
br1 += deltbr;
|
||||||
|
bg1 += deltbg;
|
||||||
|
bb1 += deltbb;
|
||||||
|
uint64_t channels = 0;
|
||||||
|
if(!fgdef){
|
||||||
|
channels_set_fg_rgb(&channels, r1, g1, b1);
|
||||||
|
}
|
||||||
|
if(!bgdef){
|
||||||
|
channels_set_bg_rgb(&channels, br1, bg1, bb1);
|
||||||
|
}
|
||||||
|
if(ncdirect_putstr(n, channels, egc) <= 0){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(len - ret > 1){
|
||||||
|
if(ncdirect_cursor_down(n, 1) || ncdirect_cursor_left(n, 1)){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
41
src/poc/dirlines.c
Normal file
41
src/poc/dirlines.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <notcurses/direct.h>
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
if(!setlocale(LC_ALL, "")){
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
struct ncdirect* n = ncdirect_init(NULL, stdout);
|
||||||
|
putchar('\n');
|
||||||
|
for(int i = 0 ; i < 15 ; ++i){
|
||||||
|
uint64_t c1 = 0, c2 = 0;
|
||||||
|
channels_set_fg_rgb(&c1, 0x0, 0x10 * i, 0xff);
|
||||||
|
channels_set_fg_rgb(&c2, 0x10 * i, 0x0, 0x0);
|
||||||
|
if(ncdirect_hline_interp(n, "-", i, c1, c2) < i){
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
ncdirect_fg_default(n);
|
||||||
|
ncdirect_bg_default(n);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
for(int i = 0 ; i < 15 ; ++i){
|
||||||
|
uint64_t c1 = 0, c2 = 0;
|
||||||
|
channels_set_fg_rgb(&c1, 0x0, 0x10 * i, 0xff);
|
||||||
|
channels_set_fg_rgb(&c2, 0x10 * i, 0x0, 0x0);
|
||||||
|
if(ncdirect_vline_interp(n, "|", i, c1, c2) < i){
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
ncdirect_fg_default(n);
|
||||||
|
ncdirect_bg_default(n);
|
||||||
|
if(i < 14){
|
||||||
|
if(ncdirect_cursor_up(n, i)){
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(ncdirect_stop(n)){
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <notcurses/notcurses.h>
|
#include <notcurses/direct.h>
|
||||||
|
|
||||||
// can we leave what was already on the screen there? (narrator: it seems not)
|
// can we leave what was already on the screen there? (narrator: it seems not)
|
||||||
int main(void){
|
int main(void){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user