mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
implement notcurses_render_to_buffer() #214
This commit is contained in:
parent
b4f1065f69
commit
270b1b20ee
2
USAGE.md
2
USAGE.md
@ -175,7 +175,7 @@ int notcurses_render(struct notcurses* nc);
|
|||||||
// do not write the resulting buffer out to the terminal. Using this function,
|
// 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
|
// the user can control the writeout process, and render a second frame while
|
||||||
// writing another. The returned buffer must be freed by the caller.
|
// 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
|
// Write the last rendered frame, in its entirety, to 'fp'. If
|
||||||
// notcurses_render() has not yet been called, nothing will be written.
|
// notcurses_render() has not yet been called, nothing will be written.
|
||||||
|
@ -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_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
|
# DESCRIPTION
|
||||||
|
|
||||||
|
@ -195,6 +195,11 @@ namespace ncpp
|
|||||||
return error_guard (notcurses_render (nc), -1);
|
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
|
bool render_to_file (FILE* fp) const NOEXCEPT_MAYBE
|
||||||
{
|
{
|
||||||
return error_guard (notcurses_render_to_file (nc, fp), -1);
|
return error_guard (notcurses_render_to_file (nc, fp), -1);
|
||||||
|
@ -851,7 +851,7 @@ API int notcurses_render(struct notcurses* nc);
|
|||||||
// do not write the resulting buffer out to the terminal. Using this function,
|
// 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
|
// the user can control the writeout process, and render a second frame while
|
||||||
// writing another. The returned buffer must be freed by the caller.
|
// 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
|
// Write the last rendered frame, in its entirety, to 'fp'. If
|
||||||
// notcurses_render() has not yet been called, nothing will be written.
|
// notcurses_render() has not yet been called, nothing will be written.
|
||||||
|
@ -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_lex_margins(const char* op, notcurses_options* opts);
|
||||||
int notcurses_stop(struct notcurses*);
|
int notcurses_stop(struct notcurses*);
|
||||||
int notcurses_render(struct notcurses* nc);
|
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);
|
int notcurses_render_to_file(struct notcurses* nc, FILE* fp);
|
||||||
struct ncplane* notcurses_stdplane(struct notcurses*);
|
struct ncplane* notcurses_stdplane(struct notcurses*);
|
||||||
const struct ncplane* notcurses_stdplane_const(const struct notcurses* nc);
|
const struct ncplane* notcurses_stdplane_const(const struct notcurses* nc);
|
||||||
|
@ -909,7 +909,7 @@ notcurses_rasterize_inner(notcurses* nc, const struct crender* rvec, FILE* out){
|
|||||||
//fprintf(stderr, "damageidx: %ld\n", damageidx);
|
//fprintf(stderr, "damageidx: %ld\n", damageidx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return nc->rstate.mstrsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// rasterize the rendered frame, and blockingly write it out to the terminal.
|
// 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
|
// 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
|
// 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
|
static inline int
|
||||||
notcurses_rasterize(notcurses* nc, const struct crender* rvec, FILE* out){
|
notcurses_rasterize(notcurses* nc, const struct crender* rvec, FILE* out){
|
||||||
const int cursory = nc->cursory;
|
const int cursory = nc->cursory;
|
||||||
@ -1054,7 +1055,7 @@ notcurses_render_internal(notcurses* nc, struct crender* rvec){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int notcurses_render(notcurses* nc){
|
int notcurses_render(notcurses* nc){
|
||||||
struct timespec start, rasterdone, writedone;
|
struct timespec start, rasterdone;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||||
int dimy, dimx;
|
int dimy, dimx;
|
||||||
notcurses_resize(nc, &dimy, &dimx);
|
notcurses_resize(nc, &dimy, &dimx);
|
||||||
@ -1072,11 +1073,41 @@ int notcurses_render(notcurses* nc){
|
|||||||
if(bytes < 0){
|
if(bytes < 0){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
struct timespec writedone;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &writedone);
|
clock_gettime(CLOCK_MONOTONIC, &writedone);
|
||||||
update_write_stats(&writedone, &rasterdone, &nc->stats);
|
update_write_stats(&writedone, &rasterdone, &nc->stats);
|
||||||
return 0;
|
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
|
// 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.
|
// result is not tied to the ncplane, and persists across erases / destruction.
|
||||||
static inline char*
|
static inline char*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user