From 1b5c8499947b2bb9fa9fe17af6540444984a5949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 18 May 2021 18:52:10 +0200 Subject: [PATCH] config: add cursor.underline-thickness MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Works in pretty much the same way as ‘beam-thickness’, except that the default value is “the font’s underline thickness”. This means, that when unset, the cursor underline thickness scales with the font size. But, when explicitly set, either to a point size value, or a pixel size, it remains fixed at that size. Closes #524 --- CHANGELOG.md | 2 ++ config.c | 8 ++++++ config.h | 1 + doc/foot.ini.5.scd | 18 +++++++++++--- foot.ini | 1 + render.c | 62 ++++++++++++++++++++++++++++++++-------------- 6 files changed, 71 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fd34734..7b991c58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,8 @@ (https://codeberg.org/dnkl/foot/issues/459). * `cursor.beam-thickness` option to `foot.ini` (https://codeberg.org/dnkl/foot/issues/464). +* `cursor.underline-thickness` option to `foot.ini` + (https://codeberg.org/dnkl/foot/issues/524). * Unicode 13 characters U+1FB70 - U+1FB8B to list of box drawing characters rendered by foot itself (rather than using font glyphs) (https://codeberg.org/dnkl/foot/issues/471). diff --git a/config.c b/config.c index 7159d299..563130a7 100644 --- a/config.c +++ b/config.c @@ -1059,6 +1059,13 @@ parse_section_cursor(const char *key, const char *value, struct config *conf, return false; } + else if (strcmp(key, "underline-thickness") == 0) { + if (!str_to_pt_or_px( + value, &conf->cursor.underline_thickness, + conf, path, lineno, "cursor", "underline-thickness")) + return false; + } + else { LOG_AND_NOTIFY_ERR("%s:%d: [cursor]: %s: invalid key", path, lineno, key); return false; @@ -2373,6 +2380,7 @@ config_load(struct config *conf, const char *conf_path, .cursor = 0, }, .beam_thickness = {.pt = 1.5}, + .underline_thickness = {.pt = 0., .px = -1}, }, .mouse = { .hide_when_typing = false, diff --git a/config.h b/config.h index a5a47ce6..e95e7ead 100644 --- a/config.h +++ b/config.h @@ -157,6 +157,7 @@ struct config { uint32_t cursor; } color; struct pt_or_px beam_thickness; + struct pt_or_px underline_thickness; } cursor; struct { diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index cb4b4f08..eb55ba80 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -344,9 +344,21 @@ applications can change these at runtime. *beam-thickness* Thickness (width) of the beam styled cursor. The value is in - _points_, and its exact value thus depends on the monitor's - DPI. To instead specify a thickness in _pixels_, use the *px* - suffix: e.g. *beam-thickness=2px*. Default: _1.5_ + points, and its exact value thus depends on the monitor's DPI. To + instead specify a thickness in pixels, use the *px* suffix: + e.g. *beam-thickness=2px*. Default: _1.5_ + +*underline-thickness* + Thickness (height) of the underline styled cursor. The value is in + points, and its exact value thus depends on the monitor's DPI. + + To instead specify a thickness in pixels, use the *px* suffix: + e.g. *underline-thickness=2px*. + + Note that if left unset, the cursor's thickness will scale with + the font size, while if set, the size is fixed. + + Default: _font underline thickness_. # SECTION: mouse diff --git a/foot.ini b/foot.ini index 9e5c4e79..c037007c 100644 --- a/foot.ini +++ b/foot.ini @@ -49,6 +49,7 @@ # color=111111 dcdccc # blink=no # beam-thickness=1.5 +# underline-thickness= [mouse] # hide-when-typing=no diff --git a/render.c b/render.c index 300a83e3..5ca64738 100644 --- a/render.c +++ b/render.c @@ -299,9 +299,9 @@ draw_unfocused_block(const struct terminal *term, pixman_image_t *pix, } static void -draw_beam(const struct terminal *term, pixman_image_t *pix, - const struct fcft_font *font, - const pixman_color_t *color, int x, int y) +draw_beam_cursor(const struct terminal *term, pixman_image_t *pix, + const struct fcft_font *font, + const pixman_color_t *color, int x, int y) { int baseline = y + font_baseline(term) - term->fonts[0]->ascent; pixman_image_fill_rectangles( @@ -313,18 +313,43 @@ draw_beam(const struct terminal *term, pixman_image_t *pix, } static void -draw_underline(const struct terminal *term, pixman_image_t *pix, - const struct fcft_font *font, - const pixman_color_t *color, int x, int y, int cols) +draw_underline_with_thickness( + const struct terminal *term, pixman_image_t *pix, + const struct fcft_font *font, + const pixman_color_t *color, int x, int y, int cols, int thickness) { /* Make sure the line isn't positioned below the cell */ int y_ofs = font_baseline(term) - font->underline.position; - y_ofs = min(y_ofs, term->cell_height - font->underline.thickness); + y_ofs = min(y_ofs, term->cell_height - thickness); pixman_image_fill_rectangles( PIXMAN_OP_SRC, pix, color, 1, &(pixman_rectangle16_t){ - x, y + y_ofs, cols * term->cell_width, font->underline.thickness}); + x, y + y_ofs, cols * term->cell_width, thickness}); +} + +static void +draw_underline_cursor(const struct terminal *term, pixman_image_t *pix, + const struct fcft_font *font, + const pixman_color_t *color, int x, int y, int cols) +{ + int thickness = term->conf->cursor.underline_thickness.px >= 0 + ? term_pt_or_px_as_pixels( + term, &term->conf->cursor.underline_thickness) + : font->underline.thickness; + + draw_underline_with_thickness( + term, pix, font, color, x, y + font->underline.thickness, cols, + thickness); +} + +static void +draw_underline(const struct terminal *term, pixman_image_t *pix, + const struct fcft_font *font, + const pixman_color_t *color, int x, int y, int cols) +{ + draw_underline_with_thickness( + term, pix, font, color, x, y, cols, font->underline.thickness); } static void @@ -394,7 +419,7 @@ draw_cursor(const struct terminal *term, const struct cell *cell, if (likely(term->cursor_blink.state == CURSOR_BLINK_ON || !term->kbd_focus)) { - draw_beam(term, pix, font, &cursor_color, x, y); + draw_beam_cursor(term, pix, font, &cursor_color, x, y); } break; @@ -402,10 +427,7 @@ draw_cursor(const struct terminal *term, const struct cell *cell, if (likely(term->cursor_blink.state == CURSOR_BLINK_ON || !term->kbd_focus)) { - struct fcft_font *font = attrs_to_font(term, &cell->attrs); - draw_underline( - term, pix, font, &cursor_color, - x, y + font->underline.thickness, cols); + draw_underline_cursor(term, pix, font, &cursor_color, x, y, cols); } break; } @@ -1303,7 +1325,7 @@ render_ime_preedit_for_seat(struct terminal *term, struct seat *seat, /* Bar */ if (start >= 0) { struct fcft_font *font = attrs_to_font(term, &start_cell->attrs); - draw_beam(term, buf->pix[0], font, &cursor_color, x, y); + draw_beam_cursor(term, buf->pix[0], font, &cursor_color, x, y); } term_ime_set_cursor_rect(term, x, y, 1, term->cell_height); } @@ -2645,8 +2667,12 @@ render_search_box(struct terminal *term) draw_underline(term, buf->pix[0], font, &fg, x, y, count); /* Bar-styled cursor, if in the visible area */ - if (start >= 0 && start <= visible_cells) - draw_beam(term, buf->pix[0], font, &fg, x + start * term->cell_width, y); + if (start >= 0 && start <= visible_cells) { + draw_beam_cursor( + term, buf->pix[0], font, &fg, + x + start * term->cell_width, y); + } + term_ime_set_cursor_rect(term, WINDOW_X(x + start * term->cell_width), WINDOW_Y(y), 1, term->cell_height); @@ -2675,7 +2701,7 @@ render_search_box(struct terminal *term) /* Cursor *should* be in the visible area */ xassert(cell_idx >= glyph_offset); xassert(cell_idx <= glyph_offset + visible_cells); - draw_beam(term, buf->pix[0], font, &fg, x, y); + draw_beam_cursor(term, buf->pix[0], font, &fg, x, y); term_ime_set_cursor_rect( term, WINDOW_X(x), WINDOW_Y(y), 1, term->cell_height); } @@ -2731,7 +2757,7 @@ render_search_box(struct terminal *term) else #endif if (term->search.cursor >= term->search.len) { - draw_beam(term, buf->pix[0], font, &fg, x, y); + draw_beam_cursor(term, buf->pix[0], font, &fg, x, y); term_ime_set_cursor_rect( term, WINDOW_X(x), WINDOW_Y(y), 1, term->cell_height); }