implement notcurses_render_to_buffer() #214

This commit is contained in:
nick black 2020-10-04 11:34:15 -04:00 committed by Nick Black
parent b4f1065f69
commit 270b1b20ee
6 changed files with 43 additions and 7 deletions

View File

@ -175,7 +175,7 @@ int notcurses_render(struct notcurses* nc);
// do not write the resulting buffer out to the terminal. Using this function,
// the user can control the writeout process, and render a second frame while
// writing another. The returned buffer must be freed by the caller.
int notcurses_render_to_buffer(struct notcurses* nc, char** buf, size_t buflen);
int notcurses_render_to_buffer(struct notcurses* nc, char** buf, size_t* buflen);
// Write the last rendered frame, in its entirety, to 'fp'. If
// notcurses_render() has not yet been called, nothing will be written.

View File

@ -16,7 +16,7 @@ notcurses_render - sync the physical display to the virtual ncplanes
**int notcurses_render_to_file(struct notcurses* nc, FILE* fp);**
**int notcurses_render_to_buffer(struct notcurses* nc, char** buf, size_t buflen);**
**int notcurses_render_to_buffer(struct notcurses* nc, char** buf, size_t* buflen);**
# DESCRIPTION

View File

@ -195,6 +195,11 @@ namespace ncpp
return error_guard (notcurses_render (nc), -1);
}
bool render_to_buffer (char** buf, size_t* buflen) const NOEXCEPT_MAYBE
{
return error_guard (notcurses_render_to_buffer (nc, buf, buflen), -1);
}
bool render_to_file (FILE* fp) const NOEXCEPT_MAYBE
{
return error_guard (notcurses_render_to_file (nc, fp), -1);

View File

@ -851,7 +851,7 @@ API int notcurses_render(struct notcurses* nc);
// do not write the resulting buffer out to the terminal. Using this function,
// the user can control the writeout process, and render a second frame while
// writing another. The returned buffer must be freed by the caller.
API int notcurses_render_to_buffer(struct notcurses* nc, char** buf, size_t buflen);
API int notcurses_render_to_buffer(struct notcurses* nc, char** buf, size_t* buflen);
// Write the last rendered frame, in its entirety, to 'fp'. If
// notcurses_render() has not yet been called, nothing will be written.

View File

@ -53,7 +53,7 @@ void notcurses_version_components(int* major, int* minor, int* patch, int* tweak
int notcurses_lex_margins(const char* op, notcurses_options* opts);
int notcurses_stop(struct notcurses*);
int notcurses_render(struct notcurses* nc);
int notcurses_render_to_buffer(struct notcurses* nc, char** buf, size_t buflen);
int notcurses_render_to_buffer(struct notcurses* nc, char** buf, size_t* buflen);
int notcurses_render_to_file(struct notcurses* nc, FILE* fp);
struct ncplane* notcurses_stdplane(struct notcurses*);
const struct ncplane* notcurses_stdplane_const(const struct notcurses* nc);

View File

@ -909,7 +909,7 @@ notcurses_rasterize_inner(notcurses* nc, const struct crender* rvec, FILE* out){
//fprintf(stderr, "damageidx: %ld\n", damageidx);
}
}
return 0;
return nc->rstate.mstrsize;
}
// rasterize the rendered frame, and blockingly write it out to the terminal.
@ -935,7 +935,8 @@ raster_and_write(notcurses* nc, const struct crender* rvec, FILE* out){
// if the cursor is enabled, store its location and disable it. then, once done
// rasterizing, enable it afresh, moving it to the stored location. if left on
// during rasterization, we'll get grotesque flicker.
// during rasterization, we'll get grotesque flicker. 'out' is a memstream
// used to collect a buffer.
static inline int
notcurses_rasterize(notcurses* nc, const struct crender* rvec, FILE* out){
const int cursory = nc->cursory;
@ -1054,7 +1055,7 @@ notcurses_render_internal(notcurses* nc, struct crender* rvec){
}
int notcurses_render(notcurses* nc){
struct timespec start, rasterdone, writedone;
struct timespec start, rasterdone;
clock_gettime(CLOCK_MONOTONIC, &start);
int dimy, dimx;
notcurses_resize(nc, &dimy, &dimx);
@ -1072,11 +1073,41 @@ int notcurses_render(notcurses* nc){
if(bytes < 0){
return -1;
}
struct timespec writedone;
clock_gettime(CLOCK_MONOTONIC, &writedone);
update_write_stats(&writedone, &rasterdone, &nc->stats);
return 0;
}
// for now, we just run the top half of notcurses_render(), and copy out the
// memstream from within rstate. we want to allocate our own here, and return
// it, to avoid the copy, but we need feed the params through to do so FIXME.
int notcurses_render_to_buffer(notcurses* nc, char** buf, size_t* buflen){
struct timespec start, rasterdone;
clock_gettime(CLOCK_MONOTONIC, &start);
int dimy, dimx;
notcurses_resize(nc, &dimy, &dimx);
int bytes = -1;
const size_t crenderlen = sizeof(struct crender) * nc->stdplane->leny * nc->stdplane->lenx;
struct crender* crender = malloc(crenderlen);
init_rvec(crender, crenderlen / sizeof(struct crender));
if(notcurses_render_internal(nc, crender) == 0){
clock_gettime(CLOCK_MONOTONIC, &rasterdone);
update_render_stats(&rasterdone, &start, &nc->stats);
bytes = notcurses_rasterize_inner(nc, crender, nc->rstate.mstreamfp);
}
update_render_bytes(&nc->stats, bytes);
if(bytes < 0){
return -1;
}
*buf = memdup(nc->rstate.mstreamfp, nc->rstate.mstrsize);
if(buf == NULL){
return -1;
}
*buflen = nc->rstate.mstrsize;
return 0;
}
// copy the UTF8-encoded EGC out of the cell, whether simple or complex. the
// result is not tied to the ncplane, and persists across erases / destruction.
static inline char*