diff --git a/config.c b/config.c index 14e836c1..41eab603 100644 --- a/config.c +++ b/config.c @@ -1447,6 +1447,9 @@ parse_color_theme(struct context *ctx, struct color_theme *theme) else if (streq(key, "flash")) color = &theme->flash; else if (streq(key, "foreground")) color = &theme->fg; else if (streq(key, "background")) color = &theme->bg; + else if (streq(key, "bold")) color = &theme->bold; + else if (streq(key, "italic")) color = &theme->italic; + else if (streq(key, "underline")) color = &theme->underline; else if (streq(key, "selection-foreground")) color = &theme->selection_fg; else if (streq(key, "selection-background")) color = &theme->selection_bg; @@ -3517,6 +3520,9 @@ config_load(struct config *conf, const char *conf_path, .dim_blend_towards = DIM_BLEND_TOWARDS_BLACK, .selection_fg = 0x80000000, /* Use default bg */ .selection_bg = 0x80000000, /* Use default fg */ + .bold = 0x80000000, /* default: unset */ + .italic = 0x80000000, /* default: unset */ + .underline = 0x80000000, /* default: unset */ .cursor = { .text = 0, .cursor = 0, diff --git a/config.h b/config.h index 9ca47753..c5538187 100644 --- a/config.h +++ b/config.h @@ -141,6 +141,9 @@ struct color_theme { uint32_t selection_fg; uint32_t selection_bg; uint32_t url; + uint32_t bold; + uint32_t italic; + uint32_t underline; uint32_t dim[8]; uint32_t sixel[16]; diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index 8bff9629..69ace850 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -1109,6 +1109,21 @@ The default theme used is *colors-dark*, unless Foreground (text) and background color to use in selected text. Default: _inverse foreground/background_. +*bold* + Specifies the color to use for bold characters when the foreground color is the default (undefined). + This setting applies primarily to legacy applications that utilize SGR 1 codes instead of SGR 9 codes. + If not set, the behavior defaults to the terminal’s standard bold rendering. Default: unset. + +*italic* + Specifies the color to use for italic characters when the foreground color is the default (undefined). + This setting applies primarily to legacy applications that utilize SGR 1 codes instead of SGR 9 codes. + If not set, the behavior defaults to the terminal’s standard italic rendering. Default: unset. + +*underline* + Specifies the color to use for underline characters when the foreground color is the default (undefined). + This setting applies primarily to legacy applications that utilize SGR 1 codes instead of SGR 9 codes. + If not set, the behavior defaults to the terminal’s standard underline rendering. Default: unset. + *jump-labels* Two color values specifying the foreground (text) and background colors to use when rendering jump labels in URL mode. Default: diff --git a/foot.ini b/foot.ini index a9b4b83d..46f33263 100644 --- a/foot.ini +++ b/foot.ini @@ -160,6 +160,11 @@ # sixel14 = 999954 # sixel15 = cccccc +## Attribute colorization +# bold = +# italic = +# underline = + ## Misc colors # selection-foreground= # selection-background= diff --git a/render.c b/render.c index 86244434..97503537 100644 --- a/render.c +++ b/render.c @@ -703,6 +703,7 @@ render_cell(struct terminal *term, pixman_image_t *pix, uint32_t _fg = 0; uint32_t _bg = 0; + bool allow_brighten = true; uint16_t alpha = 0xffff; const bool is_selected = cell->attrs.selected; @@ -720,7 +721,20 @@ render_cell(struct terminal *term, pixman_image_t *pix, break; case COLOR_DEFAULT: - _fg = term->reverse ? term->colors.bg : term->colors.fg; + if (term->reverse) { + _fg = term->colors.bg; + } else if (cell->attrs.bold && term->colors.bold >> 24 == 0) { + _fg = term->colors.bold; + allow_brighten = false; + } else if (cell->attrs.italic && term->colors.italic >> 24 == 0) { + _fg = term->colors.italic; + allow_brighten = false; + } else if (cell->attrs.underline && term->colors.underline >> 24 == 0) { + _fg = term->colors.underline; + allow_brighten = false; + } else { + _fg = term->colors.fg; + } break; } @@ -839,7 +853,7 @@ render_cell(struct terminal *term, pixman_image_t *pix, if (cell->attrs.dim) _fg = color_dim(term, _fg); - if (term->conf->bold_in_bright.enabled && cell->attrs.bold) + if (term->conf->bold_in_bright.enabled && cell->attrs.bold && allow_brighten) _fg = color_brighten(term, _fg); if (cell->attrs.blink && term->blink.state == BLINK_OFF) diff --git a/terminal.c b/terminal.c index b670d606..0a495441 100644 --- a/terminal.c +++ b/terminal.c @@ -1317,6 +1317,9 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, .cursor_bg = (theme->use_custom.cursor ? 1u << 31 : 0) | theme->cursor.cursor, .selection_fg = theme->selection_fg, .selection_bg = theme->selection_bg, + .bold = theme->bold, + .italic = theme->italic, + .underline = theme->underline, .active_theme = conf->initial_color_theme, }, .color_stack = { @@ -2090,6 +2093,9 @@ term_theme_apply(struct terminal *term, const struct color_theme *theme) term->colors.cursor_bg = (theme->use_custom.cursor ? 1u << 31 : 0) | theme->cursor.cursor; term->colors.selection_fg = theme->selection_fg; term->colors.selection_bg = theme->selection_bg; + term->colors.bold = theme->bold; + term->colors.italic = theme->italic; + term->colors.underline = theme->underline; memcpy(term->colors.table, theme->table, sizeof(term->colors.table)); } diff --git a/terminal.h b/terminal.h index fe39341d..69dcdf07 100644 --- a/terminal.h +++ b/terminal.h @@ -404,6 +404,9 @@ struct colors { uint32_t cursor_bg; /* cursor color */ uint32_t selection_fg; uint32_t selection_bg; + uint32_t bold; + uint32_t italic; + uint32_t underline; enum which_color_theme active_theme; }; diff --git a/tests/test-config.c b/tests/test-config.c index f83a9beb..c8bc1756 100644 --- a/tests/test-config.c +++ b/tests/test-config.c @@ -739,6 +739,9 @@ test_section_colors_dark(void) test_color(&ctx, &parse_section_colors_dark, "dim7", false, &conf.colors_dark.dim[7]); test_color(&ctx, &parse_section_colors_dark, "selection-foreground", false, &conf.colors_dark.selection_fg); test_color(&ctx, &parse_section_colors_dark, "selection-background", false, &conf.colors_dark.selection_bg); + test_color(&ctx, &parse_section_colors_dark, "bold", false, &conf.colors_dark.bold); + test_color(&ctx, &parse_section_colors_dark, "italic", false, &conf.colors_dark.italic); + test_color(&ctx, &parse_section_colors_dark, "underline", false, &conf.colors_dark.underline); test_color(&ctx, &parse_section_colors_dark, "urls", false, &conf.colors_dark.url); test_two_colors(&ctx, &parse_section_colors_dark, "jump-labels", false, &conf.colors_dark.jump_label.fg, @@ -818,6 +821,9 @@ test_section_colors_light(void) test_color(&ctx, &parse_section_colors_light, "dim7", false, &conf.colors_light.dim[7]); test_color(&ctx, &parse_section_colors_light, "selection-foreground", false, &conf.colors_light.selection_fg); test_color(&ctx, &parse_section_colors_light, "selection-background", false, &conf.colors_light.selection_bg); + test_color(&ctx, &parse_section_colors_light, "bold", false, &conf.colors_light.bold); + test_color(&ctx, &parse_section_colors_light, "italic", false, &conf.colors_light.italic); + test_color(&ctx, &parse_section_colors_light, "underline", false, &conf.colors_light.underline); test_color(&ctx, &parse_section_colors_light, "urls", false, &conf.colors_light.url); test_two_colors(&ctx, &parse_section_colors_light, "jump-labels", false, &conf.colors_light.jump_label.fg,