mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 09:09: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_NO_ALTERNATE_SCREEN`, and `NCOPTION_PRESERVE_CURSOR`.
|
||||
* 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)
|
||||
* 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
|
||||
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***
|
||||
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
|
||||
// an even number of columns. Use the ncvisual rotation for a more
|
||||
// flexible approach.
|
||||
API int ncplane_rotate_cw(struct ncplane* n);
|
||||
API int ncplane_rotate_ccw(struct ncplane* n);
|
||||
API int ncplane_rotate_cw(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
|
||||
// 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.
|
||||
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
|
||||
// cell is invalidated if the associated plane is destroyed. Returns the number
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
// 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,
|
||||
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
|
||||
// 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
|
||||
// the secondary columns of a wide glyph, the return can be distinguished from
|
||||
// the primary column (nccell_wide_right_p(c) will return true).
|
||||
API int ncplane_at_yx_cell(struct ncplane* n, int y, int x, nccell* c);
|
||||
// the primary column (nccell_wide_right_p(c) will return true). It is an
|
||||
// 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
|
||||
// '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.
|
||||
// -1 can be specified for 'begx'/'begy' to use the current cursor location.
|
||||
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.
|
||||
// ncplane_set_userptr() returns the previous userptr after replacing
|
||||
// it with 'opaque'. the others simply return the userptr.
|
||||
API void* ncplane_set_userptr(struct ncplane* n, void* opaque);
|
||||
API void* ncplane_userptr(struct ncplane* n);
|
||||
API void* ncplane_set_userptr(struct ncplane* n, void* opaque)
|
||||
__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
|
||||
// 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
|
||||
// center is then modified relative to the plane's origin.
|
||||
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'.
|
||||
// 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);
|
||||
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)];
|
||||
// if we're the right side of a wide glyph, we return the main glyph
|
||||
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){
|
||||
if(n->sprite){
|
||||
logerror("invoked on a sprixel plane");
|
||||
return -1;
|
||||
}
|
||||
if(y < 0){
|
||||
if(y != -1){
|
||||
logerror("invalid y: %d", y);
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include <inttypes.h>
|
||||
#include <notcurses/notcurses.h>
|
||||
#include <compat/compat.h>
|
||||
|
||||
int main(int argc, char** argv){
|
||||
if(argc < 2){
|
||||
fprintf(stderr, "usage: %s images...\n", *argv);
|
||||
fprintf(stderr, "usage: %s images..." NL, *argv);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
struct notcurses_options opts = {0};
|
||||
@ -20,7 +22,7 @@ int main(int argc, char** argv){
|
||||
struct ncvisual* ncv = ncvisual_from_file(*argv);
|
||||
if(ncv == NULL){
|
||||
notcurses_stop(nc);
|
||||
fprintf(stderr, "error opening %s\n", *argv);
|
||||
fprintf(stderr, "error opening %s" NL, *argv);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
struct ncplane* ncp = ncplane_dup(stdn, NULL);
|
||||
@ -34,16 +36,25 @@ int main(int argc, char** argv){
|
||||
vopts.flags = NCVISUAL_OPTION_NODEGRADE;
|
||||
if(ncvisual_blit(nc, ncv, &vopts) == NULL){
|
||||
notcurses_stop(nc);
|
||||
fprintf(stderr, "error rendering %s\n", *argv);
|
||||
fprintf(stderr, "error rendering %s" NL, *argv);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// FIXME acquire sixel as s
|
||||
char* s = strdup("");
|
||||
char* s;
|
||||
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
|
||||
struct ncvisual* quantncv = ncvisual_from_sixel(s, leny, lenx);
|
||||
if(quantncv == NULL){
|
||||
notcurses_stop(nc);
|
||||
fprintf(stderr, "error loading %zuB sixel\n", strlen(s));
|
||||
fprintf(stderr, "error loading %" PRIuPTR "B sixel" NL, slen);
|
||||
free(s);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user