From b71016c25dc18a2c098a87439046873c6c9ddb30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 3 Sep 2020 17:37:44 +0200 Subject: [PATCH 1/2] render: optionally enable heuristics that deal with private usage area chars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Try to detect double-width *glyphs* for single-width *characters*, and allow them to overflow into the next cell. This is only done for single-width chars with a glyph width that is at least 1.5 cells wide, but at most 3 cells. The feature is gated by the new ‘tweak.allow-overflowing-double-width-glyphs’, and is disabled by default. Closes #116 --- CHANGELOG.md | 4 ++++ config.c | 6 +++++- config.h | 1 + doc/foot.ini.5.scd | 17 +++++++++++++++++ render.c | 25 +++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 537e7d88..05133296 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,10 @@ Ps r` (https://codeberg.org/dnkl/foot/issues/91). * `$COLORTERM` is now set to `truecolor` at startup, to indicate support for 24-bit RGB colors. +* Experimental support for rendering double-width glyphs with a + character width of 1. Must be explicitly enabled with + `tweak.allow-overflowing-double-width-glyphs` + (https://codeberg.org/dnkl/foot/issues/116). ### Deprecated diff --git a/config.c b/config.c index 83a0ef4d..56e5af12 100644 --- a/config.c +++ b/config.c @@ -1358,7 +1358,10 @@ parse_section_tweak( const char *key, const char *value, struct config *conf, const char *path, unsigned lineno) { - if (strcmp(key, "render-timer") == 0) { + if (strcmp(key, "allow-overflowing-double-width-glyphs") == 0) + conf->tweak.allow_overflowing_double_width_glyphs = str_to_bool(value); + + else if (strcmp(key, "render-timer") == 0) { if (strcmp(value, "none") == 0) { conf->tweak.render_timer_osd = false; conf->tweak.render_timer_log = false; @@ -1792,6 +1795,7 @@ config_load(struct config *conf, const char *conf_path, bool errors_are_fatal) .hold_at_exit = false, .tweak = { + .allow_overflowing_double_width_glyphs = false, .delayed_render_lower_ns = 500000, /* 0.5ms */ .delayed_render_upper_ns = 16666666 / 2, /* half a frame period (60Hz) */ .max_shm_pool_size = 512 * 1024 * 1024, diff --git a/config.h b/config.h index fac5ea89..2368e53c 100644 --- a/config.h +++ b/config.h @@ -144,6 +144,7 @@ struct config { bool hold_at_exit; struct { + bool allow_overflowing_double_width_glyphs; bool render_timer_osd; bool render_timer_log; uint64_t delayed_render_lower_ns; diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index 9f8c6cbb..87a81a4e 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -440,6 +440,23 @@ foot. When reporting bugs, please mention if, and to what, you have changed any of these options. +*allow-overflowing-double-width-glyphs* + + When enabled, double width glyphs with a character width of 1 are + allowed to overflow into the neighbouring cell. + + One use case for this is fonts "icon" characters in the Unicode + private usage area, e.g. Nerd Fonts, or Powerline Fonts. Without + this option, such glyphs will appear "cut off". + + Another use case are legacy emoji characters like *WHITE FROWNING + FACE*. + + Note: this feature uses _heuristics_ to determine *which* glyphs + should be allowed to overflow. + + Default: _false_. + *render-timer* Enables a frame rendering timer, that prints the time it takes to render each frame, in microseconds, either on-screen, to stderr, diff --git a/render.c b/render.c index 08caabc7..ea21b808 100644 --- a/render.c +++ b/render.c @@ -433,6 +433,31 @@ render_cell(struct terminal *term, pixman_image_t *pix, const int cols_left = term->cols - col; int cell_cols = glyph != NULL ? max(1, min(glyph->cols, cols_left)) : 1; + /* + * Hack! + * + * Deal with double-width glyphs for which wcwidth() returns + * 1. Typically Unicode private usage area characters, + * e.g. powerline, or nerd hack fonts. + * + * Users can enable a tweak option that lets this glyphs + * overflow/bleed into the neighbouring cell. + * + * We only apply this workaround if: + * - the user has explicitly enabled this feature + * - the *character* width is 1 + * - the *glyph* width is at least 1.5 cells + * - the *glyph* width is less than 3 cells + */ + if (term->conf->tweak.allow_overflowing_double_width_glyphs && + glyph != NULL && + glyph->cols == 1 && + glyph->width >= term->cell_width * 15 / 10 && + glyph->width < 3 * term->cell_width) + { + cell_cols = min(2, cols_left); + } + pixman_region32_t clip; pixman_region32_init_rect( &clip, x, y, From 123c94379b5237fea5308ebc345af4fb2001adc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 5 Sep 2020 09:38:48 +0200 Subject: [PATCH 2/2] doc: foot.ini: remove empty lines after option name --- doc/foot.ini.5.scd | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index 87a81a4e..59f11fce 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -441,14 +441,13 @@ When reporting bugs, please mention if, and to what, you have changed any of these options. *allow-overflowing-double-width-glyphs* - When enabled, double width glyphs with a character width of 1 are allowed to overflow into the neighbouring cell. One use case for this is fonts "icon" characters in the Unicode private usage area, e.g. Nerd Fonts, or Powerline Fonts. Without this option, such glyphs will appear "cut off". - + Another use case are legacy emoji characters like *WHITE FROWNING FACE*. @@ -530,7 +529,6 @@ any of these options. frame interval). *max-shm-pool-size-mb* - This option controls the amount of *virtual* memory used by the pixmap memory to which the terminal screen content is rendered.