From d20a4d8104a0ca5e436fa3d45a19869a382aff38 Mon Sep 17 00:00:00 2001 From: nick black Date: Mon, 31 May 2021 20:07:10 -0400 Subject: [PATCH] ncdirect: restore colors properly following sgr #1703 --- NEWS.md | 2 ++ USAGE.md | 1 + doc/man/man3/notcurses_direct.3.md | 5 ++++ include/notcurses/direct.h | 2 ++ src/fetch/main.c | 2 ++ src/lib/direct.c | 46 ++++++++++++++++++------------ 6 files changed, 40 insertions(+), 18 deletions(-) diff --git a/NEWS.md b/NEWS.md index 1947f4851..2fedadbb0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,8 @@ rearrangements of Notcurses. * 2.3.2 (not yet released) * Fixed a bug affecting certain scalings of `ncvisual` objects created from memory (e.g. `ncvisual_from_rgba()`). + * Fixed a bug where setting a style in direct mode reset color. Shocked that + such a bug could exist for so long, ugh. * `ncinput_nomod_p()` has been added. This function returns `true` if and only if its `ncinput` argument has no modifiers active. * Added `notcurses_cursor_yx()` to get the current location of the cursor. diff --git a/USAGE.md b/USAGE.md index 8f5b1c91c..f9d1ba040 100644 --- a/USAGE.md +++ b/USAGE.md @@ -408,6 +408,7 @@ int ncdirect_bg_default(struct ncdirect* nc); int ncdirect_styles_set(struct ncdirect* n, unsigned stylebits); int ncdirect_styles_on(struct ncdirect* n, unsigned stylebits); int ncdirect_styles_off(struct ncdirect* n, unsigned stylebits); +unsigned ncdirect_styles(struct ncdirect* n); int ncdirect_clear(struct ncdirect* nc); // clear the screen // Move the cursor in direct mode. -1 to retain current location on that axis. diff --git a/doc/man/man3/notcurses_direct.3.md b/doc/man/man3/notcurses_direct.3.md index e2f5d4268..b8322499d 100644 --- a/doc/man/man3/notcurses_direct.3.md +++ b/doc/man/man3/notcurses_direct.3.md @@ -48,6 +48,8 @@ notcurses_direct - minimal notcurses instances for styling text **int ncdirect_styles_off(struct ncdirect* ***n***, unsigned ***stylebits***);** +**unsigned ncdirect_styles(struct ncdirect* ***n***);** + **int ncdirect_clear(struct ncdirect* ***nc***)** **int ncdirect_stop(struct ncdirect* ***nc***);** @@ -197,6 +199,9 @@ written on success. On failure, they return some negative number. **ncdirect_check_pixel_support** returns -1 on error, 0 if there is no pixel support, and 1 if pixel support is successfully detected. +**ncdirect_styles** returns the current styling, a bitmask over the various +**NCSTYLE_** constants. + All other functions return 0 on success, and non-zero on error. # SEE ALSO diff --git a/include/notcurses/direct.h b/include/notcurses/direct.h index 803a75bc0..117ef6e20 100644 --- a/include/notcurses/direct.h +++ b/include/notcurses/direct.h @@ -190,6 +190,8 @@ API int ncdirect_on_styles(struct ncdirect* n, unsigned stylebits) __attribute__ ((nonnull (1))); API int ncdirect_off_styles(struct ncdirect* n, unsigned stylebits) __attribute__ ((nonnull (1))); +API unsigned ncdirect_styles(struct ncdirect* n) + __attribute__ ((nonnull (1))); // Deprecated forms of above. API int ncdirect_styles_set(struct ncdirect* n, unsigned stylebits) diff --git a/src/fetch/main.c b/src/fetch/main.c index 1a02ddb7f..4240e1af1 100644 --- a/src/fetch/main.c +++ b/src/fetch/main.c @@ -563,11 +563,13 @@ neologo_present(struct ncdirect* nc, const char* nlogo){ } free(lines); ncdirect_set_fg_rgb(nc, 0xba55d3); + ncdirect_on_styles(nc, NCSTYLE_BOLD | NCSTYLE_ITALIC); if(ncdirect_canopen_images(nc)){ ncdirect_printf_aligned(nc, -1, NCALIGN_CENTER, "(no image file is known for your distro)"); }else{ ncdirect_printf_aligned(nc, -1, NCALIGN_CENTER, "(notcurses was compiled without image support)"); } + ncdirect_off_styles(nc, NCSTYLE_BOLD | NCSTYLE_ITALIC); return 0; } diff --git a/src/lib/direct.c b/src/lib/direct.c index 7cc889ec1..2f5f22972 100644 --- a/src/lib/direct.c +++ b/src/lib/direct.c @@ -826,12 +826,18 @@ ncdirect_style_emit(ncdirect* n, unsigned stylebits, FILE* out){ } // sgr resets colors, so set them back up if not defaults if(r == 0){ - // FIXME need to handle palette-indexed colors + // 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. FIXME need to handle palette colors if(!ncdirect_fg_default_p(n)){ - r |= ncdirect_set_fg_rgb(n, ncchannels_fg_rgb(n->channels)); + uint32_t fg = ncchannels_fg_rgb(n->channels); + ncchannels_set_fg_default(&n->channels); + r |= ncdirect_set_fg_rgb(n, fg); } if(!ncdirect_bg_default_p(n)){ - r |= ncdirect_set_bg_rgb(n, ncchannels_bg_rgb(n->channels)); + uint32_t bg = ncchannels_fg_rgb(n->channels); + ncchannels_set_bg_default(&n->channels); + r |= ncdirect_set_bg_rgb(n, bg); } } return r; @@ -865,6 +871,10 @@ int ncdirect_styles_off(ncdirect* n, unsigned stylebits){ return ncdirect_off_styles(n, stylebits); } +unsigned ncdirect_styles(ncdirect* n){ + return n->stylemask; +} + // turn off any specified stylebits int ncdirect_off_styles(ncdirect* n, unsigned stylebits){ uint32_t stylemask = n->stylemask & ~stylebits; @@ -895,22 +905,22 @@ int ncdirect_set_styles(ncdirect* n, unsigned stylebits){ return -1; } uint32_t stylemask = stylebits; - if(ncdirect_style_emit(n, stylemask, n->ttyfp) == 0){ - n->stylemask &= !(NCSTYLE_ITALIC | NCSTYLE_STRUCK); // sgr clears both - if(term_setstyle(n->ttyfp, n->stylemask, stylemask, NCSTYLE_ITALIC, - get_escape(&n->tcache, ESCAPE_SITM), - get_escape(&n->tcache, ESCAPE_RITM))){ - return -1; - } - if(term_setstyle(n->ttyfp, n->stylemask, stylemask, NCSTYLE_STRUCK, - get_escape(&n->tcache, ESCAPE_SMXX), - get_escape(&n->tcache, ESCAPE_RMXX))){ - return -1; - } - n->stylemask = stylemask; - return 0; + if(ncdirect_style_emit(n, stylemask, n->ttyfp)){ + return -1; } - return -1; + n->stylemask &= !(NCSTYLE_ITALIC | NCSTYLE_STRUCK); // sgr clears both + if(term_setstyle(n->ttyfp, n->stylemask, stylemask, NCSTYLE_ITALIC, + get_escape(&n->tcache, ESCAPE_SITM), + get_escape(&n->tcache, ESCAPE_RITM))){ + return -1; + } + if(term_setstyle(n->ttyfp, n->stylemask, stylemask, NCSTYLE_STRUCK, + get_escape(&n->tcache, ESCAPE_SMXX), + get_escape(&n->tcache, ESCAPE_RMXX))){ + return -1; + } + n->stylemask = stylemask; + return 0; } unsigned ncdirect_palette_size(const ncdirect* nc){