notcurses_render(): add term_setstyle() #11

pull/74/head
nick black 5 years ago committed by Nick Black
parent 2dde60c27a
commit bc662e92bb

@ -297,13 +297,20 @@ cell_set_style(cell* c, unsigned stylebits){
((stylebits & 0xffff) << 16u);
}
// Add the specified styles to the cell's existing spec.
// Get the style bits, shifted over into the LSBs.
static inline unsigned
cell_get_style(const cell* c){
return (c->attrword & ~CELL_STYLE_MASK) >> 16u;
}
// Add the specified styles (in the LSBs) to the cell's existing spec, whether
// they're actively supported or not.
static inline void
cell_enable_styles(cell* c, unsigned stylebits){
c->attrword |= ((stylebits & 0xffff) << 16u);
}
// Remove the specified styles from the cell's existing spec.
// Remove the specified styles (in the LSBs) from the cell's existing spec.
static inline void
cell_disable_styles(cell* c, unsigned stylebits){
c->attrword &= ~((stylebits & 0xffff) << 16u);
@ -334,11 +341,12 @@ cell_rgb_blue(uint32_t rgb){
return (rgb & 0xffull);
}
#define CELL_FGDEFAULT_MASK 0x4000000000000000ull
#define CELL_FG_MASK 0x00ffffff00000000ull
#define CELL_WIDEASIAN_MASK 0x2000000000000000ull
#define CELL_BGDEFAULT_MASK 0x0000000040000000ull
#define CELL_BG_MASK 0x0000000000ffffffull
#define CELL_INHERITSTYLE_MASK 0x8000000000000000ull
#define CELL_FGDEFAULT_MASK 0x4000000000000000ull
#define CELL_WIDEASIAN_MASK 0x2000000000000000ull
#define CELL_FG_MASK 0x00ffffff00000000ull
#define CELL_BGDEFAULT_MASK 0x0000000040000000ull
#define CELL_BG_MASK 0x0000000000ffffffull
static inline void
cell_rgb_set_fg(uint64_t* channels, unsigned r, unsigned g, unsigned b){
@ -382,21 +390,32 @@ cell_get_bg(const cell* c, unsigned* r, unsigned* g, unsigned* b){
*b = cell_rgb_blue(cell_bg_rgb(c->channels));
}
// does the cell passively retain the styling of the previously-rendered cell?
static inline bool
cell_inherits_style(const cell* c){
return (c->channels & CELL_INHERITSTYLE_MASK);
}
// is the cell using the terminal's default foreground color for its foreground?
static inline bool
cell_fg_default_p(const cell* c){
return !(c->channels & CELL_FGDEFAULT_MASK);
}
// is the cell using the terminal's default background color for its background?
static inline bool
cell_bg_default_p(const cell* c){
return !(c->channels & CELL_BGDEFAULT_MASK);
}
// does the cell contain an East Asian Wide codepoint?
static inline bool
cell_double_wide_p(const cell* c){
return (c->channels & CELL_WIDEASIAN_MASK);
}
// get the offset into the egcpool for this cell's EGC. returns meaningless and
// unsafe results if called on a simple cell.
static inline uint32_t
cell_egc_idx(const cell* c){
return c->gcluster - 0x80;

@ -76,6 +76,7 @@ typedef struct notcurses {
char* dim; // WA_DIM
char* bold; // WA_BOLD
char* italics; // WA_ITALIC
char* italoff; // WA_ITALIC (disable)
struct termios tpreserved; // terminal state upon entry
bool RGBflag; // terminfo-reported "RGB" flag for 24bpc directcolor
ncplane* top; // the contents of our topmost plane (initially entire screen)
@ -425,6 +426,7 @@ interrogate_terminfo(notcurses* nc, const notcurses_options* opts){
term_verify_seq(&nc->dim, "dim");
term_verify_seq(&nc->bold, "bold");
term_verify_seq(&nc->italics, "sitm");
term_verify_seq(&nc->italoff, "ritm");
term_verify_seq(&nc->op, "op");
term_verify_seq(&nc->clear, "clear");
// Some terminals cannot combine certain styles with colors. Don't advertise
@ -732,6 +734,51 @@ advance_cursor(ncplane* n, int cols){
}
}
// check the current and target style bitmasks against the specified 'stylebit'.
// if they are different, and we have the necessary capability, write the
// applicable terminfo entry to 'out'. returns -1 only on a true error.
static int
term_setstyle(FILE* out, unsigned cur, unsigned targ, unsigned stylebit,
const char* ton, const char* toff){
int ret = 0;
unsigned curon = cur & stylebit;
unsigned targon = targ & stylebit;
if(curon != targon){
if(targon){
if(ton){
ret = term_emit(ton, out, false);
}
}else{
if(toff){ // how did this happen? we can turn it on, but not off?
ret = term_emit(toff, out, false);
}
}
}
if(ret < 0){
return -1;
}
return 0;
}
// write any escape sequences necessary to set the desired style
static int
term_setstyles(const notcurses* nc, FILE* out, uint32_t curattr, const cell* c){
if(cell_inherits_style(c)){
return 0; // change nothing
}
uint32_t cellattr = cell_get_style(c);
if(cellattr == curattr){
return 0; // happy agreement, change nothing
}
int ret = 0;
ret |= term_setstyle(out, curattr, cellattr, WA_ITALIC, nc->italics, nc->italoff);
/*ret |= term_setstyle(out, curattr, cellattr, WA_BOLD, nc->bold, nc->boldoff);
ret |= term_setstyle(out, curattr, cellattr, WA_UNDERLINE, nc->uline, nc->ulineoff);
ret |= term_setstyle(out, curattr, cellattr, WA_BLINK, nc->blink, nc->blinkoff);*/
// FIXME a few others
return ret;
}
// FIXME this needs to keep an invalidation bitmap, rather than blitting the
// world every time
int notcurses_render(notcurses* nc){
@ -745,6 +792,7 @@ int notcurses_render(notcurses* nc){
if(out == NULL){
return -1;
}
uint32_t curattr = 0; // current attributes set (does not include colors)
term_emit(nc->clear, out, false);
for(y = 0 ; y < nc->stdscr->leny ; ++y){
// FIXME previous line could have ended halfway through multicol. what happens?
@ -767,6 +815,7 @@ int notcurses_render(notcurses* nc){
cell_get_bg(c, &br, &bg, &bb);
term_bg_rgb8(nc, out, br, bg, bb);
}
term_setstyles(nc, out, curattr, c);
// FIXME what to do if we're at the last cell, and it's wide?
// fprintf(stderr, "[%02d/%02d] ", y, x);
term_putc(out, nc->stdscr, c);

Loading…
Cancel
Save