From d863220e23434b0d376db88abf7e26c07a47e754 Mon Sep 17 00:00:00 2001 From: nick black Date: Sat, 6 Jun 2020 21:38:05 -0400 Subject: [PATCH] add pixels PoC --- NEWS.md | 5 +++- USAGE.md | 3 ++ doc/man/man3/notcurses_visual.3.md | 2 ++ include/notcurses/notcurses.h | 14 +++++++++ src/poc/pixels.c | 48 ++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/poc/pixels.c diff --git a/NEWS.md b/NEWS.md index bce28d8c7..e6067e148 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,12 +1,15 @@ This document attempts to list user-visible changes and any major internal rearrangements of Notcurses. +* 1.5.0 (not yet released) + * Added a Pixel API for working directly with the contents of `ncvisual`s, + including `ncvisual_at_yx()` and `ncvisual_set_yx()`. + * 1.4.5 (2020-06-04) * `ncblit_rgba()` and `ncblit_bgrx()` have replaced most of their arguments with a `const struct ncvisual_options*`. `NCBLIT_DEFAULT` will use `NCBLITTER_2x1` (with fallback) in this context. The `->n` field must be non-`NULL`--new planes will not be created. - * Added a Pixel API for working directly with the contents of `ncvisual`s. * Added `ncplane_notcurses_const()`. * 1.4.4.1 (2020-06-01) diff --git a/USAGE.md b/USAGE.md index 37aa31ace..5238b1b5b 100644 --- a/USAGE.md +++ b/USAGE.md @@ -2514,6 +2514,9 @@ int ncvisual_polyfill_yx(struct ncvisual* n, int y, int x, uint32_t rgba); // Get the specified pixel from the specified ncvisual. int ncvisual_at_yx(const struct ncvisual* n, int y, int x, uint32_t* pixel); +// Set the specified pixel in the specified ncvisual. +int ncvisual_set_yx(const struct ncvisual* n, int y, int x, uint32_t pixel); + // If a subtitle ought be displayed at this time, return a heap-allocated copy // of the UTF8 text. char* ncvisual_subtitle(const struct ncvisual* ncv); diff --git a/doc/man/man3/notcurses_visual.3.md b/doc/man/man3/notcurses_visual.3.md index 56cca8030..015f5b194 100644 --- a/doc/man/man3/notcurses_visual.3.md +++ b/doc/man/man3/notcurses_visual.3.md @@ -78,6 +78,8 @@ typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*); **int ncvisual_at_yx(const struct ncvisual* n, int y, int x, uint32_t* pixel);** +**int ncvisual_set_yx(const struct ncvisual* n, int y, int x, uint32_t pixel);** + **char* ncvisual_subtitle(const struct ncvisual* ncv);** # DESCRIPTION diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 3ec27aaed..224c1135b 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -193,6 +193,17 @@ channel_set_rgb(unsigned* channel, int r, int g, int b){ return 0; } +static inline uint32_t +ncpixel(int r, int g, int b){ + if(r < 0) r = 0; + if(r > 255) r = 255; + if(g < 0) g = 0; + if(g > 255) g = 255; + if(b < 0) b = 0; + if(b > 255) b = 255; + return 0xff000000ul | r | (b << 8u) | (g << 16u); +} + static inline int pixel_set_r(uint32_t* pixel, int r){ if(r > 255 || r < 0){ @@ -2209,6 +2220,9 @@ API int ncvisual_polyfill_yx(struct ncvisual* n, int y, int x, uint32_t rgba); // Get the specified pixel from the specified ncvisual. API int ncvisual_at_yx(const struct ncvisual* n, int y, int x, uint32_t* pixel); +// Set the specified pixel in the specified ncvisual. +API int ncvisual_set_yx(const struct ncvisual* n, int y, int x, uint32_t pixel); + #define NCVISUAL_OPTION_NODEGRADE 0x0001 // fail rather than degrading #define NCVISUAL_OPTION_BLEND 0x0002 // use CELL_ALPHA_BLEND with visual diff --git a/src/poc/pixels.c b/src/poc/pixels.c new file mode 100644 index 000000000..ed87ec48a --- /dev/null +++ b/src/poc/pixels.c @@ -0,0 +1,48 @@ +#include +#include + +int main(void){ + setlocale(LC_ALL, ""); + struct notcurses_options opts = { + .flags = NCOPTION_INHIBIT_SETLOCALE, + }; + struct timespec ts = { + .tv_sec = 1, + .tv_nsec = 500000000, + }; + struct notcurses* nc = notcurses_init(&opts, NULL); + int dimy, dimx; + struct ncplane* std = notcurses_stddim_yx(nc, &dimy, &dimx); + struct ncvisual* ncv = ncvisual_from_plane(std, NCBLIT_2x1, 0, 0, dimy / 2, dimx / 2); + if(ncv == NULL){ + notcurses_stop(nc); + return EXIT_FAILURE; + } + struct ncvisual_options vopts = { + .n = std, + }; + if(ncvisual_set_yx(ncv, dimy / 2 - 1, dimx / 2 - 1, 0xffffffff) < 0){ + notcurses_stop(nc); + return EXIT_FAILURE; + } + if(std != ncvisual_render(nc, ncv, &vopts)){ + notcurses_stop(nc); + return EXIT_FAILURE; + } + notcurses_render(nc); + clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL); + + if(ncvisual_polyfill_yx(ncv, 0, 0, ncpixel(0x00, 0x80, 0x80)) <= 0){ + notcurses_stop(nc); + return EXIT_FAILURE; + } + if(std != ncvisual_render(nc, ncv, &vopts)){ + notcurses_stop(nc); + return EXIT_FAILURE; + } + notcurses_render(nc); + clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL); + + notcurses_stop(nc); + return EXIT_SUCCESS; +}