mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
[quantanal] recover control sequence with ncplane_at_yx()
This commit is contained in:
parent
0e190d0bc0
commit
635da75c3c
2
NEWS.md
2
NEWS.md
@ -9,6 +9,8 @@ rearrangements of Notcurses.
|
|||||||
`NCOPTION_SCROLLING`, `NCOPTION_NO_CLEAR_BITMAPS`,
|
`NCOPTION_SCROLLING`, `NCOPTION_NO_CLEAR_BITMAPS`,
|
||||||
`NCOPTION_NO_ALTERNATE_SCREEN`, and `NCOPTION_PRESERVE_CURSOR`.
|
`NCOPTION_NO_ALTERNATE_SCREEN`, and `NCOPTION_PRESERVE_CURSOR`.
|
||||||
* Added `ncvisual_from_sixel()`.
|
* Added `ncvisual_from_sixel()`.
|
||||||
|
* The control sequence corresponding to a pixel-blitted `ncvisual()`
|
||||||
|
can be retrieved by using `ncplane_at_yx()` on the sprixel plane.
|
||||||
|
|
||||||
* 3.0.1 (2021-12-14)
|
* 3.0.1 (2021-12-14)
|
||||||
* Added the `NCPLANE_OPTION_VSCROLL` flag. Creating an `ncplane` with this
|
* Added the `NCPLANE_OPTION_VSCROLL` flag. Creating an `ncplane` with this
|
||||||
|
@ -375,6 +375,10 @@ secondary column of a wide glyph with **ncplane_at_yx_cell** will fill in
|
|||||||
the **nccell** argument such that **nccell_extended_gcluster(3)** returns an
|
the **nccell** argument such that **nccell_extended_gcluster(3)** returns an
|
||||||
empty string, and **nccell_wide_right_p(3)** returns **true**.
|
empty string, and **nccell_wide_right_p(3)** returns **true**.
|
||||||
|
|
||||||
|
If **ncplane_at_yx** is invoked upon a sprixel plane, the control sequence will
|
||||||
|
be returned for any valid coordinates (note that this may be quite large).
|
||||||
|
This does not apply to **ncplane_at_yx_cell**, which will return an error.
|
||||||
|
|
||||||
**ncplane_set_name** sets the plane's name, freeing any old name. ***name***
|
**ncplane_set_name** sets the plane's name, freeing any old name. ***name***
|
||||||
may be **NULL**. **ncplane_set_name** duplicates the provided name internally.
|
may be **NULL**. **ncplane_set_name** duplicates the provided name internally.
|
||||||
|
|
||||||
|
@ -1876,18 +1876,22 @@ API int ncplane_scrollup_child(struct ncplane* n, const struct ncplane* child)
|
|||||||
// characters, spaces, half blocks, and full blocks. The plane must have
|
// characters, spaces, half blocks, and full blocks. The plane must have
|
||||||
// an even number of columns. Use the ncvisual rotation for a more
|
// an even number of columns. Use the ncvisual rotation for a more
|
||||||
// flexible approach.
|
// flexible approach.
|
||||||
API int ncplane_rotate_cw(struct ncplane* n);
|
API int ncplane_rotate_cw(struct ncplane* n)
|
||||||
API int ncplane_rotate_ccw(struct ncplane* n);
|
__attribute__ ((nonnull (1)));
|
||||||
|
API int ncplane_rotate_ccw(struct ncplane* n)
|
||||||
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
// Retrieve the current contents of the cell under the cursor. The EGC is
|
// Retrieve the current contents of the cell under the cursor. The EGC is
|
||||||
// returned, or NULL on error. This EGC must be free()d by the caller. The
|
// returned, or NULL on error. This EGC must be free()d by the caller. The
|
||||||
// stylemask and channels are written to 'stylemask' and 'channels', respectively.
|
// stylemask and channels are written to 'stylemask' and 'channels', respectively.
|
||||||
API char* ncplane_at_cursor(struct ncplane* n, uint16_t* stylemask, uint64_t* channels);
|
API char* ncplane_at_cursor(struct ncplane* n, uint16_t* stylemask, uint64_t* channels)
|
||||||
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
// Retrieve the current contents of the cell under the cursor into 'c'. This
|
// Retrieve the current contents of the cell under the cursor into 'c'. This
|
||||||
// cell is invalidated if the associated plane is destroyed. Returns the number
|
// cell is invalidated if the associated plane is destroyed. Returns the number
|
||||||
// of bytes in the EGC, or -1 on error.
|
// of bytes in the EGC, or -1 on error.
|
||||||
API int ncplane_at_cursor_cell(struct ncplane* n, nccell* c);
|
API int ncplane_at_cursor_cell(struct ncplane* n, nccell* c)
|
||||||
|
__attribute__ ((nonnull (1, 2)));
|
||||||
|
|
||||||
// Retrieve the current contents of the specified cell. The EGC is returned, or
|
// Retrieve the current contents of the specified cell. The EGC is returned, or
|
||||||
// NULL on error. This EGC must be free()d by the caller. The stylemask and
|
// NULL on error. This EGC must be free()d by the caller. The stylemask and
|
||||||
@ -1895,16 +1899,20 @@ API int ncplane_at_cursor_cell(struct ncplane* n, nccell* c);
|
|||||||
// represents how the cell will be used during rendering, and thus integrates
|
// represents how the cell will be used during rendering, and thus integrates
|
||||||
// any base cell where appropriate. If called upon the secondary columns of a
|
// any base cell where appropriate. If called upon the secondary columns of a
|
||||||
// wide glyph, the EGC will be returned (i.e. this function does not distinguish
|
// wide glyph, the EGC will be returned (i.e. this function does not distinguish
|
||||||
// between the primary and secondary columns of a wide glyph).
|
// between the primary and secondary columns of a wide glyph). If called on a
|
||||||
|
// sprixel plane, its control sequence is returned for all valid locations.
|
||||||
API char* ncplane_at_yx(const struct ncplane* n, int y, int x,
|
API char* ncplane_at_yx(const struct ncplane* n, int y, int x,
|
||||||
uint16_t* stylemask, uint64_t* channels);
|
uint16_t* stylemask, uint64_t* channels)
|
||||||
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
// Retrieve the current contents of the specified cell into 'c'. This cell is
|
// Retrieve the current contents of the specified cell into 'c'. This cell is
|
||||||
// invalidated if the associated plane is destroyed. Returns the number of
|
// invalidated if the associated plane is destroyed. Returns the number of
|
||||||
// bytes in the EGC, or -1 on error. Unlike ncplane_at_yx(), when called upon
|
// bytes in the EGC, or -1 on error. Unlike ncplane_at_yx(), when called upon
|
||||||
// the secondary columns of a wide glyph, the return can be distinguished from
|
// the secondary columns of a wide glyph, the return can be distinguished from
|
||||||
// the primary column (nccell_wide_right_p(c) will return true).
|
// the primary column (nccell_wide_right_p(c) will return true). It is an
|
||||||
API int ncplane_at_yx_cell(struct ncplane* n, int y, int x, nccell* c);
|
// error to call this on a sprixel plane (unlike ncplane_at_yx()).
|
||||||
|
API int ncplane_at_yx_cell(struct ncplane* n, int y, int x, nccell* c)
|
||||||
|
__attribute__ ((nonnull (1, 4)));
|
||||||
|
|
||||||
// Create a flat string from the EGCs of the selected region of the ncplane
|
// Create a flat string from the EGCs of the selected region of the ncplane
|
||||||
// 'n'. Start at the plane's 'begy'x'begx' coordinate (which must lie on the
|
// 'n'. Start at the plane's 'begy'x'begx' coordinate (which must lie on the
|
||||||
@ -1912,20 +1920,24 @@ API int ncplane_at_yx_cell(struct ncplane* n, int y, int x, nccell* c);
|
|||||||
// 'lenx' can be specified as 0 to go through the boundary of the plane.
|
// 'lenx' can be specified as 0 to go through the boundary of the plane.
|
||||||
// -1 can be specified for 'begx'/'begy' to use the current cursor location.
|
// -1 can be specified for 'begx'/'begy' to use the current cursor location.
|
||||||
API char* ncplane_contents(struct ncplane* n, int begy, int begx,
|
API char* ncplane_contents(struct ncplane* n, int begy, int begx,
|
||||||
unsigned leny, unsigned lenx);
|
unsigned leny, unsigned lenx)
|
||||||
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
// Manipulate the opaque user pointer associated with this plane.
|
// Manipulate the opaque user pointer associated with this plane.
|
||||||
// ncplane_set_userptr() returns the previous userptr after replacing
|
// ncplane_set_userptr() returns the previous userptr after replacing
|
||||||
// it with 'opaque'. the others simply return the userptr.
|
// it with 'opaque'. the others simply return the userptr.
|
||||||
API void* ncplane_set_userptr(struct ncplane* n, void* opaque);
|
API void* ncplane_set_userptr(struct ncplane* n, void* opaque)
|
||||||
API void* ncplane_userptr(struct ncplane* n);
|
__attribute__ ((nonnull (1)));
|
||||||
|
API void* ncplane_userptr(struct ncplane* n)
|
||||||
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
// Find the center coordinate of a plane, preferring the top/left in the
|
// Find the center coordinate of a plane, preferring the top/left in the
|
||||||
// case of an even number of rows/columns (in such a case, there will be one
|
// case of an even number of rows/columns (in such a case, there will be one
|
||||||
// more cell to the bottom/right of the center than the top/left). The
|
// more cell to the bottom/right of the center than the top/left). The
|
||||||
// center is then modified relative to the plane's origin.
|
// center is then modified relative to the plane's origin.
|
||||||
API void ncplane_center_abs(const struct ncplane* n, int* RESTRICT y,
|
API void ncplane_center_abs(const struct ncplane* n, int* RESTRICT y,
|
||||||
int* RESTRICT x);
|
int* RESTRICT x)
|
||||||
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
// Create an RGBA flat array from the selected region of the ncplane 'nc'.
|
// Create an RGBA flat array from the selected region of the ncplane 'nc'.
|
||||||
// Start at the plane's 'begy'x'begx' coordinate (which must lie on the
|
// Start at the plane's 'begy'x'begx' coordinate (which must lie on the
|
||||||
|
@ -229,6 +229,15 @@ char* ncplane_at_yx(const ncplane* n, int y, int x, uint16_t* stylemask, uint64_
|
|||||||
logerror("invalid coordinates: %d/%d", y, x);
|
logerror("invalid coordinates: %d/%d", y, x);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if(n->sprite){
|
||||||
|
if(stylemask){
|
||||||
|
*stylemask = 0;
|
||||||
|
}
|
||||||
|
if(channels){
|
||||||
|
*channels = 0;
|
||||||
|
}
|
||||||
|
return strdup(n->sprite->glyph.buf);
|
||||||
|
}
|
||||||
const nccell* yx = &n->fb[nfbcellidx(n, y, x)];
|
const nccell* yx = &n->fb[nfbcellidx(n, y, x)];
|
||||||
// if we're the right side of a wide glyph, we return the main glyph
|
// if we're the right side of a wide glyph, we return the main glyph
|
||||||
if(nccell_wide_right_p(yx)){
|
if(nccell_wide_right_p(yx)){
|
||||||
@ -258,6 +267,10 @@ int ncplane_at_cursor_cell(ncplane* n, nccell* c){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ncplane_at_yx_cell(ncplane* n, int y, int x, nccell* c){
|
int ncplane_at_yx_cell(ncplane* n, int y, int x, nccell* c){
|
||||||
|
if(n->sprite){
|
||||||
|
logerror("invoked on a sprixel plane");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if(y < 0){
|
if(y < 0){
|
||||||
if(y != -1){
|
if(y != -1){
|
||||||
logerror("invalid y: %d", y);
|
logerror("invalid y: %d", y);
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
|
#include <inttypes.h>
|
||||||
#include <notcurses/notcurses.h>
|
#include <notcurses/notcurses.h>
|
||||||
|
#include <compat/compat.h>
|
||||||
|
|
||||||
int main(int argc, char** argv){
|
int main(int argc, char** argv){
|
||||||
if(argc < 2){
|
if(argc < 2){
|
||||||
fprintf(stderr, "usage: %s images...\n", *argv);
|
fprintf(stderr, "usage: %s images..." NL, *argv);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
struct notcurses_options opts = {0};
|
struct notcurses_options opts = {0};
|
||||||
@ -20,7 +22,7 @@ int main(int argc, char** argv){
|
|||||||
struct ncvisual* ncv = ncvisual_from_file(*argv);
|
struct ncvisual* ncv = ncvisual_from_file(*argv);
|
||||||
if(ncv == NULL){
|
if(ncv == NULL){
|
||||||
notcurses_stop(nc);
|
notcurses_stop(nc);
|
||||||
fprintf(stderr, "error opening %s\n", *argv);
|
fprintf(stderr, "error opening %s" NL, *argv);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
struct ncplane* ncp = ncplane_dup(stdn, NULL);
|
struct ncplane* ncp = ncplane_dup(stdn, NULL);
|
||||||
@ -34,16 +36,25 @@ int main(int argc, char** argv){
|
|||||||
vopts.flags = NCVISUAL_OPTION_NODEGRADE;
|
vopts.flags = NCVISUAL_OPTION_NODEGRADE;
|
||||||
if(ncvisual_blit(nc, ncv, &vopts) == NULL){
|
if(ncvisual_blit(nc, ncv, &vopts) == NULL){
|
||||||
notcurses_stop(nc);
|
notcurses_stop(nc);
|
||||||
fprintf(stderr, "error rendering %s\n", *argv);
|
fprintf(stderr, "error rendering %s" NL, *argv);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
// FIXME acquire sixel as s
|
char* s;
|
||||||
char* s = strdup("");
|
if((s = ncplane_at_yx(ncp, 0, 0, NULL, NULL)) == NULL){
|
||||||
|
notcurses_stop(nc);
|
||||||
|
fprintf(stderr, "error retrieving sixel for %s" NL, *argv);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
ncplane_set_fg_rgb(stdn, 0x74b72e);
|
||||||
|
size_t slen = strlen(s);
|
||||||
|
ncplane_printf(stdn, " control sequence: %" PRIuPTR " byte%s\n",
|
||||||
|
slen, slen == 1 ? "" : "s");
|
||||||
|
notcurses_render(nc);
|
||||||
unsigned leny = 0, lenx = 0; // FIXME
|
unsigned leny = 0, lenx = 0; // FIXME
|
||||||
struct ncvisual* quantncv = ncvisual_from_sixel(s, leny, lenx);
|
struct ncvisual* quantncv = ncvisual_from_sixel(s, leny, lenx);
|
||||||
if(quantncv == NULL){
|
if(quantncv == NULL){
|
||||||
notcurses_stop(nc);
|
notcurses_stop(nc);
|
||||||
fprintf(stderr, "error loading %zuB sixel\n", strlen(s));
|
fprintf(stderr, "error loading %" PRIuPTR "B sixel" NL, slen);
|
||||||
free(s);
|
free(s);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user