mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
pixel plots: draw rgba area #1382
This commit is contained in:
parent
83b9a7820e
commit
00a4f9db83
207
src/lib/plot.c
207
src/lib/plot.c
@ -107,7 +107,7 @@ int redraw_pixelplot_##T(nc##X##plot* ncp){ \
|
||||
if(!interval){ \
|
||||
interval = 1; \
|
||||
} \
|
||||
uint32_t* pixels = malloc(dimy * dimx * states * scale); \
|
||||
uint32_t* pixels = malloc(dimy * dimx * states * scale * sizeof(*pixels)); \
|
||||
if(pixels == NULL){ \
|
||||
return -1; \
|
||||
} \
|
||||
@ -134,81 +134,44 @@ int redraw_pixelplot_##T(nc##X##plot* ncp){ \
|
||||
direction, prepping pixels, aborting early if we can't draw anything in a \
|
||||
given cell. */ \
|
||||
T intervalbase = ncp->miny; \
|
||||
const wchar_t* egc = ncp->plot.bset->plotegcs; \
|
||||
bool done = !ncp->plot.bset->fill; \
|
||||
int pcol = 0; /* column of pixels to which we're writing */ \
|
||||
for(int y = 0 ; y < dimy ; ++y){ \
|
||||
int prow = y * states; /* row of pixels we start at */ \
|
||||
uint64_t channels = 0; \
|
||||
calc_gradient_channels(&channels, ncp->plot.minchannels, ncp->plot.minchannels, \
|
||||
ncp->plot.maxchannels, ncp->plot.maxchannels, y, x, dimy, dimx); \
|
||||
ncplane_set_channels(ncp->plot.ncp, channels); \
|
||||
if(egc){ \
|
||||
size_t egcidx = 0, sumidx = 0; \
|
||||
/* if we've got at least one interval's worth on the number of positions \
|
||||
times the number of intervals per position plus the starting offset, \
|
||||
we're going to print *something* */ \
|
||||
for(int i = 0 ; i < scale ; ++i){ \
|
||||
sumidx *= states; \
|
||||
if(intervalbase < gvals[i]){ \
|
||||
if(ncp->plot.exponentiali){ \
|
||||
/* we want the log-base-interval of gvals[i] */ \
|
||||
double scaled = log(gvals[i] - ncp->miny) / log(interval); \
|
||||
double sival = intervalbase ? log(intervalbase) / log(interval) : 0; \
|
||||
egcidx = scaled - sival; \
|
||||
}else{ \
|
||||
egcidx = (gvals[i] - intervalbase) / interval; \
|
||||
} \
|
||||
if(egcidx >= states){ \
|
||||
egcidx = states - 1; \
|
||||
done = false; \
|
||||
} \
|
||||
sumidx += egcidx; \
|
||||
/* if we've got at least one interval's worth on the number of positions \
|
||||
times the number of intervals per position plus the starting offset, \
|
||||
we're going to print *something* */ \
|
||||
for(int i = 0 ; i < scale ; ++i){ \
|
||||
size_t egcidx; \
|
||||
if(intervalbase < gvals[i]){ \
|
||||
if(ncp->plot.exponentiali){ \
|
||||
/* we want the log-base-interval of gvals[i] */ \
|
||||
double scaled = log(gvals[i] - ncp->miny) / log(interval); \
|
||||
double sival = intervalbase ? log(intervalbase) / log(interval) : 0; \
|
||||
egcidx = scaled - sival; \
|
||||
}else{ \
|
||||
egcidx = 0; \
|
||||
egcidx = (gvals[i] - intervalbase) / interval; \
|
||||
} \
|
||||
/* printf(stderr, "y: %d i(scale): %d gvals[%d]: %ju egcidx: %zu sumidx: %zu interval: %f intervalbase: %ju\n", y, i, i, gvals[i], egcidx, sumidx, interval, intervalbase); */ \
|
||||
} \
|
||||
/* if we're not UTF8, we can only arrive here via NCBLIT_1x1 (otherwise \
|
||||
we would have errored out during construction). even then, however, \
|
||||
we need handle ASCII differently, since it can't print full block. \
|
||||
in ASCII mode, sumidx != 0 means swap colors and use space. in all \
|
||||
modes, sumidx == 0 means don't do shit, since we erased earlier. */ \
|
||||
/* if(sumidx)fprintf(stderr, "dimy: %d y: %d x: %d sumidx: %zu egc[%zu]: %lc\n", dimy, y, x, sumidx, sumidx, egc[sumidx]); */ \
|
||||
if(sumidx){ \
|
||||
if(notcurses_canutf8(ncplane_notcurses(ncp->plot.ncp))){ \
|
||||
char utf8[MB_CUR_MAX + 1]; \
|
||||
int bytes = wctomb(utf8, egc[sumidx]); \
|
||||
if(bytes < 0){ \
|
||||
free(pixels); \
|
||||
return -1; \
|
||||
} \
|
||||
utf8[bytes] = '\0'; \
|
||||
nccell* c = ncplane_cell_ref_yx(ncp->plot.ncp, dimy - y - 1, x); \
|
||||
cell_set_bchannel(c, ncchannels_bchannel(channels)); \
|
||||
cell_set_fchannel(c, ncchannels_fchannel(channels)); \
|
||||
nccell_set_styles(c, NCSTYLE_NONE); \
|
||||
if(pool_blit_direct(&ncp->plot.ncp->pool, c, utf8, bytes, 1) <= 0){ \
|
||||
free(pixels); \
|
||||
return -1; \
|
||||
} \
|
||||
}else{ \
|
||||
const uint64_t swapbg = ncchannels_bchannel(channels); \
|
||||
const uint64_t swapfg = ncchannels_fchannel(channels); \
|
||||
ncchannels_set_bchannel(&channels, swapfg); \
|
||||
ncchannels_set_fchannel(&channels, swapbg); \
|
||||
ncplane_set_channels(ncp->plot.ncp, channels); \
|
||||
if(ncplane_putchar_yx(ncp->plot.ncp, dimy - y - 1, x, ' ') <= 0){ \
|
||||
free(pixels); \
|
||||
return -1; \
|
||||
} \
|
||||
ncchannels_set_bchannel(&channels, swapbg); \
|
||||
ncchannels_set_fchannel(&channels, swapfg); \
|
||||
ncplane_set_channels(ncp->plot.ncp, channels); \
|
||||
if(egcidx >= states){ \
|
||||
egcidx = states - 1; \
|
||||
done = false; \
|
||||
} \
|
||||
}else{ \
|
||||
egcidx = 0; \
|
||||
} \
|
||||
if(done){ \
|
||||
break; \
|
||||
/* FIXME take egcidx into account for height */ \
|
||||
for(size_t yy = 0 ; yy < states ; ++yy){ \
|
||||
int poff = (prow + yy) * dimx * scale + pcol; \
|
||||
pixels[poff] = htole(0xfffffffflu); /* FIXME use real colors */ \
|
||||
} \
|
||||
} \
|
||||
if(done){ \
|
||||
break; \
|
||||
} \
|
||||
if(ncp->plot.exponentiali){ \
|
||||
intervalbase = ncp->miny + pow(interval, (y + 1) * states - 1); \
|
||||
}else{ \
|
||||
@ -325,71 +288,69 @@ int redraw_plot_##T(nc##X##plot* ncp){ \
|
||||
calc_gradient_channels(&channels, ncp->plot.minchannels, ncp->plot.minchannels, \
|
||||
ncp->plot.maxchannels, ncp->plot.maxchannels, y, x, dimy, dimx); \
|
||||
ncplane_set_channels(ncp->plot.ncp, channels); \
|
||||
if(egc){ \
|
||||
size_t egcidx = 0, sumidx = 0; \
|
||||
/* if we've got at least one interval's worth on the number of positions \
|
||||
times the number of intervals per position plus the starting offset, \
|
||||
we're going to print *something* */ \
|
||||
for(int i = 0 ; i < scale ; ++i){ \
|
||||
sumidx *= states; \
|
||||
if(intervalbase < gvals[i]){ \
|
||||
if(ncp->plot.exponentiali){ \
|
||||
/* we want the log-base-interval of gvals[i] */ \
|
||||
double scaled = log(gvals[i] - ncp->miny) / log(interval); \
|
||||
double sival = intervalbase ? log(intervalbase) / log(interval) : 0; \
|
||||
egcidx = scaled - sival; \
|
||||
}else{ \
|
||||
egcidx = (gvals[i] - intervalbase) / interval; \
|
||||
} \
|
||||
if(egcidx >= states){ \
|
||||
egcidx = states - 1; \
|
||||
done = false; \
|
||||
} \
|
||||
sumidx += egcidx; \
|
||||
size_t egcidx = 0, sumidx = 0; \
|
||||
/* if we've got at least one interval's worth on the number of positions \
|
||||
times the number of intervals per position plus the starting offset, \
|
||||
we're going to print *something* */ \
|
||||
for(int i = 0 ; i < scale ; ++i){ \
|
||||
sumidx *= states; \
|
||||
if(intervalbase < gvals[i]){ \
|
||||
if(ncp->plot.exponentiali){ \
|
||||
/* we want the log-base-interval of gvals[i] */ \
|
||||
double scaled = log(gvals[i] - ncp->miny) / log(interval); \
|
||||
double sival = intervalbase ? log(intervalbase) / log(interval) : 0; \
|
||||
egcidx = scaled - sival; \
|
||||
}else{ \
|
||||
egcidx = 0; \
|
||||
egcidx = (gvals[i] - intervalbase) / interval; \
|
||||
} \
|
||||
/* printf(stderr, "y: %d i(scale): %d gvals[%d]: %ju egcidx: %zu sumidx: %zu interval: %f intervalbase: %ju\n", y, i, i, gvals[i], egcidx, sumidx, interval, intervalbase); */ \
|
||||
} \
|
||||
/* if we're not UTF8, we can only arrive here via NCBLIT_1x1 (otherwise \
|
||||
we would have errored out during construction). even then, however, \
|
||||
we need handle ASCII differently, since it can't print full block. \
|
||||
in ASCII mode, sumidx != 0 means swap colors and use space. in all \
|
||||
modes, sumidx == 0 means don't do shit, since we erased earlier. */ \
|
||||
/* if(sumidx)fprintf(stderr, "dimy: %d y: %d x: %d sumidx: %zu egc[%zu]: %lc\n", dimy, y, x, sumidx, sumidx, egc[sumidx]); */ \
|
||||
if(sumidx){ \
|
||||
if(notcurses_canutf8(ncplane_notcurses(ncp->plot.ncp))){ \
|
||||
char utf8[MB_CUR_MAX + 1]; \
|
||||
int bytes = wctomb(utf8, egc[sumidx]); \
|
||||
if(bytes < 0){ \
|
||||
return -1; \
|
||||
} \
|
||||
utf8[bytes] = '\0'; \
|
||||
nccell* c = ncplane_cell_ref_yx(ncp->plot.ncp, dimy - y - 1, x); \
|
||||
cell_set_bchannel(c, ncchannels_bchannel(channels)); \
|
||||
cell_set_fchannel(c, ncchannels_fchannel(channels)); \
|
||||
nccell_set_styles(c, NCSTYLE_NONE); \
|
||||
if(pool_blit_direct(&ncp->plot.ncp->pool, c, utf8, bytes, 1) <= 0){ \
|
||||
return -1; \
|
||||
} \
|
||||
}else{ \
|
||||
const uint64_t swapbg = ncchannels_bchannel(channels); \
|
||||
const uint64_t swapfg = ncchannels_fchannel(channels); \
|
||||
ncchannels_set_bchannel(&channels, swapfg); \
|
||||
ncchannels_set_fchannel(&channels, swapbg); \
|
||||
ncplane_set_channels(ncp->plot.ncp, channels); \
|
||||
if(ncplane_putchar_yx(ncp->plot.ncp, dimy - y - 1, x, ' ') <= 0){ \
|
||||
return -1; \
|
||||
} \
|
||||
ncchannels_set_bchannel(&channels, swapbg); \
|
||||
ncchannels_set_fchannel(&channels, swapfg); \
|
||||
ncplane_set_channels(ncp->plot.ncp, channels); \
|
||||
if(egcidx >= states){ \
|
||||
egcidx = states - 1; \
|
||||
done = false; \
|
||||
} \
|
||||
sumidx += egcidx; \
|
||||
}else{ \
|
||||
egcidx = 0; \
|
||||
} \
|
||||
if(done){ \
|
||||
break; \
|
||||
/* printf(stderr, "y: %d i(scale): %d gvals[%d]: %ju egcidx: %zu sumidx: %zu interval: %f intervalbase: %ju\n", y, i, i, gvals[i], egcidx, sumidx, interval, intervalbase); */ \
|
||||
} \
|
||||
/* if we're not UTF8, we can only arrive here via NCBLIT_1x1 (otherwise \
|
||||
we would have errored out during construction). even then, however, \
|
||||
we need handle ASCII differently, since it can't print full block. \
|
||||
in ASCII mode, sumidx != 0 means swap colors and use space. in all \
|
||||
modes, sumidx == 0 means don't do shit, since we erased earlier. */ \
|
||||
/* if(sumidx)fprintf(stderr, "dimy: %d y: %d x: %d sumidx: %zu egc[%zu]: %lc\n", dimy, y, x, sumidx, sumidx, egc[sumidx]); */ \
|
||||
if(sumidx){ \
|
||||
if(notcurses_canutf8(ncplane_notcurses(ncp->plot.ncp))){ \
|
||||
char utf8[MB_CUR_MAX + 1]; \
|
||||
int bytes = wctomb(utf8, egc[sumidx]); \
|
||||
if(bytes < 0){ \
|
||||
return -1; \
|
||||
} \
|
||||
utf8[bytes] = '\0'; \
|
||||
nccell* c = ncplane_cell_ref_yx(ncp->plot.ncp, dimy - y - 1, x); \
|
||||
cell_set_bchannel(c, ncchannels_bchannel(channels)); \
|
||||
cell_set_fchannel(c, ncchannels_fchannel(channels)); \
|
||||
nccell_set_styles(c, NCSTYLE_NONE); \
|
||||
if(pool_blit_direct(&ncp->plot.ncp->pool, c, utf8, bytes, 1) <= 0){ \
|
||||
return -1; \
|
||||
} \
|
||||
}else{ \
|
||||
const uint64_t swapbg = ncchannels_bchannel(channels); \
|
||||
const uint64_t swapfg = ncchannels_fchannel(channels); \
|
||||
ncchannels_set_bchannel(&channels, swapfg); \
|
||||
ncchannels_set_fchannel(&channels, swapbg); \
|
||||
ncplane_set_channels(ncp->plot.ncp, channels); \
|
||||
if(ncplane_putchar_yx(ncp->plot.ncp, dimy - y - 1, x, ' ') <= 0){ \
|
||||
return -1; \
|
||||
} \
|
||||
ncchannels_set_bchannel(&channels, swapbg); \
|
||||
ncchannels_set_fchannel(&channels, swapfg); \
|
||||
ncplane_set_channels(ncp->plot.ncp, channels); \
|
||||
} \
|
||||
} \
|
||||
if(done){ \
|
||||
break; \
|
||||
} \
|
||||
if(ncp->plot.exponentiali){ \
|
||||
intervalbase = ncp->miny + pow(interval, (y + 1) * states - 1); \
|
||||
}else{ \
|
||||
|
Loading…
x
Reference in New Issue
Block a user