unify style backends for direct+rendered modes #1818

pull/1838/head
nick black 3 years ago
parent 5c4e8f8536
commit 8a265920b7
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -877,46 +877,10 @@ char* ncdirect_readline(ncdirect* n, const char* prompt){
static inline int
ncdirect_style_emit(ncdirect* n, unsigned stylebits, FILE* out){
int r = -1;
const char* esc;
if(stylebits == 0 && (esc = get_escape(&n->tcache, ESCAPE_SGR0))){
r = term_emit(esc, out, false);
}else if( (esc = get_escape(&n->tcache, ESCAPE_SGR)) ){
r = term_emit(tiparm(esc,
0, // standout
stylebits & NCSTYLE_UNDERLINE,
0, // reverse
0, // blink
0, // dim
stylebits & NCSTYLE_BOLD,
0, // invisible
0, // protect //
0), out, false);
}else{
// no sgr, interesting. return failure if our stylebits were provided?
// back off to individual enablers? FIXME
return 0;
}
// sgr will blow away non-sgr properties if they were set beforehand
n->stylemask &= ~(NCSTYLE_ITALIC | NCSTYLE_STRUCK | NCSTYLE_UNDERCURL);
if(term_setstyle(n->ttyfp, n->stylemask, stylebits, NCSTYLE_ITALIC,
get_escape(&n->tcache, ESCAPE_SITM),
get_escape(&n->tcache, ESCAPE_RITM))){
return -1;
}
if(term_setstyle(n->ttyfp, n->stylemask, stylebits, NCSTYLE_STRUCK,
get_escape(&n->tcache, ESCAPE_SMXX),
get_escape(&n->tcache, ESCAPE_RMXX))){
return -1;
}
if(term_setstyle(n->ttyfp, n->stylemask, stylebits, NCSTYLE_UNDERCURL,
get_escape(&n->tcache, ESCAPE_SMULX),
get_escape(&n->tcache, ESCAPE_SMULNOX))){
return -1;
}
n->stylemask = stylebits;
// sgr resets colors, so set them back up if not defaults
if(r == 0){
unsigned normalized = 0;
int r = coerce_styles(out, &n->tcache, &n->stylemask, stylebits, &normalized);
// sgr0 resets colors, so set them back up if not defaults and it was used
if(normalized){
// emitting an sgr resets colors. if we want to be default, that's no
// problem, and our channels remain correct. otherwise, clear our
// channel, and set them back up.

@ -259,13 +259,13 @@ typedef struct rasterstate {
// modified by: output, cursor moves, clearing the screen (during refresh).
int y, x;
uint32_t curattr;// current attributes set (does not include colors)
unsigned lastr; // foreground rgb, overloaded for palindexed fg
unsigned lastr; // foreground rgb, overloaded for palindexed fg
unsigned lastg;
unsigned lastb;
unsigned lastbr; // background rgb, overloaded for palindexed bg
unsigned lastbr; // background rgb, overloaded for palindexed bg
unsigned lastbg;
unsigned lastbb;
uint16_t curattr; // current attributes set (does not include colors)
// we elide a color escape iff the color has not changed between two cells
bool fgelidable;
bool bgelidable;
@ -1237,8 +1237,61 @@ term_fg_palindex(const notcurses* nc, FILE* out, unsigned pal){
return 0;
}
int term_setstyle(FILE* out, unsigned cur, unsigned targ, unsigned stylebit,
const char* ton, const char* toff);
// 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;
}
// emit escapes such that the current style is equal to newstyle. if this
// required an sgr0 (which resets colors), normalized will be non-zero upon
// a successful return.
static inline int
coerce_styles(FILE* out, const tinfo* ti, uint16_t* curstyle,
uint16_t newstyle, unsigned* normalized){
*normalized = 0; // we never currently use sgr0
int ret = 0;
ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_BOLD,
get_escape(ti, ESCAPE_BOLD), get_escape(ti, ESCAPE_NOBOLD));
ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_ITALIC,
get_escape(ti, ESCAPE_SITM), get_escape(ti, ESCAPE_RITM));
ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_STRUCK,
get_escape(ti, ESCAPE_SMXX), get_escape(ti, ESCAPE_RMXX));
// underline and undercurl are exclusive. if we set one, don't go unsetting
// the other.
if(newstyle & NCSTYLE_UNDERLINE){ // turn on underline, or do nothing
ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_UNDERLINE,
get_escape(ti, ESCAPE_SMUL), get_escape(ti, ESCAPE_RMUL));
}else if(newstyle & NCSTYLE_UNDERCURL){ // turn on undercurl, or do nothing
ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_UNDERCURL,
get_escape(ti, ESCAPE_SMULX), get_escape(ti, ESCAPE_SMULNOX));
}else{ // turn off any underlining
ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_UNDERCURL | NCSTYLE_UNDERLINE,
NULL, get_escape(ti, ESCAPE_RMUL));
}
*curstyle = newstyle;
return ret;
}
// how many edges need touch a corner for it to be printed?
static inline unsigned

@ -545,61 +545,6 @@ term_putc(FILE* out, const egcpool* e, const nccell* c){
return 0;
}
// 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.
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;
}
// emit escapes such that the current style is equal to newstyle. if this
// required an sgr0 (which resets colors), normalized will be non-zero upon
// a successful return.
static inline int
coerce_styles(FILE* out, const tinfo* ti, uint32_t* curstyle,
uint32_t newstyle, unsigned* normalized){
*normalized = 0; // we never currently use sgr0
int ret = 0;
ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_BOLD,
get_escape(ti, ESCAPE_BOLD), get_escape(ti, ESCAPE_NOBOLD));
ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_ITALIC,
get_escape(ti, ESCAPE_SITM), get_escape(ti, ESCAPE_RITM));
ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_STRUCK,
get_escape(ti, ESCAPE_SMXX), get_escape(ti, ESCAPE_RMXX));
// underline and undercurl are exclusive. if we set one, don't go unsetting
// the other.
if(newstyle & NCSTYLE_UNDERLINE){ // turn on underline, or do nothing
ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_UNDERLINE,
get_escape(ti, ESCAPE_SMUL), get_escape(ti, ESCAPE_RMUL));
}else if(newstyle & NCSTYLE_UNDERCURL){ // turn on undercurl, or do nothing
ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_UNDERCURL,
get_escape(ti, ESCAPE_SMULX), get_escape(ti, ESCAPE_SMULNOX));
}else{ // turn off any underlining
ret |= term_setstyle(out, *curstyle, newstyle, NCSTYLE_UNDERCURL | NCSTYLE_UNDERLINE,
NULL, get_escape(ti, ESCAPE_RMUL));
}
*curstyle = newstyle;
return ret;
}
// write any escape sequences necessary to set the desired style
static inline int
term_setstyles(FILE* out, notcurses* nc, const nccell* c){

@ -469,7 +469,7 @@ int interrogate_terminfo(tinfo* ti, int fd, const char* termname, unsigned utf8,
{ NCSTYLE_STRUCK, "smxx", 0 },
{ 0, NULL, 0 }
};
if(get_escape(ti, ESCAPE_BOLD) == NULL){
if(get_escape(ti, ESCAPE_BOLD)){
if(grow_esc_table(ti, "\e[22m", ESCAPE_NOBOLD, &tablelen, &tableused)){
goto err;
}

Loading…
Cancel
Save