From 09354286955a6a7eb05e0e336ce7fc9cc43cb5f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 13 May 2021 00:15:00 +0200 Subject: [PATCH 1/4] term: remove get_font_scale() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit get_font_scale() was used to get the new scaling factor when loading fonts. This was then compared to the last seen font scaling factor. If there was no difference, the fonts were not reloaded. The problem was, the initial term->scale was set differently. This sometimes led to term->scale=2, while get_font_scale() return 1. That meant, fonts were initially scaled by 2 (when dpi-aware=no). Later, when mapped on an output (and thus term->scale being set to 1), the fonts weren’t reloaded with the correct scaling factor since the cached term->font_scale value was already 1. Since term->scale always reflects the *new* scaling factor when term_font_dpi_changed() is called, use that directly, and remove get_font_scale(). Also rename the following functions: * font_should_size_by_dpi() -> font_size_by_dpi_for_scale() * font_size_by_dpi() -> font_sized_by_dpi() * font_size_by_scale() -> font_sized_by_scale() --- terminal.c | 51 +++++++++++++-------------------------------------- terminal.h | 2 +- 2 files changed, 14 insertions(+), 39 deletions(-) diff --git a/terminal.c b/terminal.c index b4abbb0f..7fd6f551 100644 --- a/terminal.c +++ b/terminal.c @@ -724,31 +724,6 @@ get_font_dpi(const struct terminal *term) return dpi; } -static int -get_font_scale(const struct terminal *term) -{ - /* Same as get_font_dpi(), but returns output scale factor instead */ - int scale = 0; - - xassert(term->window != NULL); - tll_foreach(term->window->on_outputs, it) { - if (it->item->scale > scale) - scale = it->item->scale; - } - - if (scale == 0) { - tll_foreach(term->wl->monitors, it) { - scale = it->item.scale; - break; - } - } - - if (scale == 0) - scale = 1; - - return scale; -} - static enum fcft_subpixel get_font_subpixel(const struct terminal *term) { @@ -794,22 +769,22 @@ get_font_subpixel(const struct terminal *term) } static bool -font_should_size_by_dpi(const struct terminal *term, int new_scale) +font_size_by_dpi_for_scale(const struct terminal *term, int new_scale) { return term->conf->dpi_aware == DPI_AWARE_YES || (term->conf->dpi_aware == DPI_AWARE_AUTO && new_scale <= 1); } static bool -font_size_by_dpi(const struct terminal *term) +font_sized_by_dpi(const struct terminal *term) { - return font_should_size_by_dpi(term, term->font_scale); + return font_size_by_dpi_for_scale(term, term->font_scale); } static bool -font_size_by_scale(const struct terminal *term) +font_sized_by_scale(const struct terminal *term) { - return !font_size_by_dpi(term); + return !font_sized_by_dpi(term); } @@ -849,7 +824,7 @@ reload_fonts(struct terminal *term) bool use_px_size = term->font_sizes[i][j].px_size > 0; char size[64]; - const int scale = font_size_by_scale(term) ? term->scale : 1; + const int scale = font_sized_by_scale(term) ? term->scale : 1; if (use_px_size) snprintf(size, sizeof(size), ":pixelsize=%d", @@ -885,7 +860,7 @@ reload_fonts(struct terminal *term) const size_t count_bold_italic = custom_bold_italic ? counts[3] : counts[0]; const char **names_bold_italic = (const char **)(custom_bold_italic ? names[3] : names[0]); - const bool use_dpi = font_size_by_dpi(term); + const bool use_dpi = font_sized_by_dpi(term); char *attrs[4] = {NULL}; int attr_len[4] = {-1, -1, -1, -1}; /* -1, so that +1 (below) results in 0 */ @@ -1798,16 +1773,16 @@ bool term_font_dpi_changed(struct terminal *term) { float dpi = get_font_dpi(term); - int scale = get_font_scale(term); + xassert(term->scale > 0); - bool was_scaled_using_dpi = font_size_by_dpi(term); - bool will_scale_using_dpi = font_should_size_by_dpi(term, scale); + bool was_scaled_using_dpi = font_sized_by_dpi(term); + bool will_scale_using_dpi = font_size_by_dpi_for_scale(term, term->scale); bool need_font_reload = was_scaled_using_dpi != will_scale_using_dpi || (will_scale_using_dpi ? term->font_dpi != dpi - : term->font_scale != scale); + : term->font_scale != term->scale); if (need_font_reload) { LOG_DBG("DPI/scale change: DPI-awareness=%s, " @@ -1815,12 +1790,12 @@ term_font_dpi_changed(struct terminal *term) "sizing font based on monitor's %s", term->conf->dpi_aware == DPI_AWARE_AUTO ? "auto" : term->conf->dpi_aware == DPI_AWARE_YES ? "yes" : "no", - term->font_dpi, dpi, term->font_scale, scale, + term->font_dpi, dpi, term->font_scale, term->scale, will_scale_using_dpi ? "DPI" : "scaling factor"); } term->font_dpi = dpi; - term->font_scale = scale; + term->font_scale = term->scale; if (!need_font_reload) return true; diff --git a/terminal.h b/terminal.h index 85ba90eb..42e2fd2a 100644 --- a/terminal.h +++ b/terminal.h @@ -320,7 +320,7 @@ struct terminal { struct config_font *font_sizes[4]; struct pt_or_px font_line_height; float font_dpi; - int font_scale; + int font_scale; /* scaling factor last time we loaded fonts */ int16_t font_x_ofs; int16_t font_y_ofs; enum fcft_subpixel font_subpixel; From 0e7e7b769b7e702176727aa1d73de054456fe96c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 13 May 2021 00:19:54 +0200 Subject: [PATCH 2/4] render: simply check for an invalid (not set) scaling factor --- render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/render.c b/render.c index 3f6e5637..a418db7b 100644 --- a/render.c +++ b/render.c @@ -3101,7 +3101,7 @@ maybe_resize(struct terminal *term, int width, int height, bool force) scale = it->item->scale; } - if (scale == -1) { + if (scale < 0) { /* Haven't 'entered' an output yet? */ scale = term->scale; } From e7c01f3e52d886f36c8b072323f6209e67b5927b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 13 May 2021 00:21:22 +0200 Subject: [PATCH 3/4] changelog: fonts sometimes not being reloaded with the correct scaling factor --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34c12bf0..10ea7595 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,9 @@ (https://codeberg.org/dnkl/foot/issues/503). * Sixels with transparent bottom border being resized below the size specified in _”Set Raster Attributes”_. +* Fonts sometimes not being reloaded with the correct scaling factor + when `dpi-aware=no`, or `dpi-aware=auto` with monitor(s) with a + scaling factor > 1 (https://codeberg.org/dnkl/foot/issues/509). ### Security From 2afc6782361d0deaa443234466775b1121feec8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 13 May 2021 11:10:51 +0200 Subject: [PATCH 4/4] term: get rid of term->font_scale, use term->scale only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We only needed term->font_scale to be able to detect scaling factor changes (term->font_scale != term->scale). But, we already have the old scaling factor in all places where term_font_dpi_changed() is called, so let’s pass the old scaling factor as an argument instead. --- terminal.c | 31 ++++++++++++------------------- terminal.h | 3 +-- wayland.c | 4 +++- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/terminal.c b/terminal.c index 7fd6f551..4a39b659 100644 --- a/terminal.c +++ b/terminal.c @@ -769,22 +769,16 @@ get_font_subpixel(const struct terminal *term) } static bool -font_size_by_dpi_for_scale(const struct terminal *term, int new_scale) +font_sized_by_dpi(const struct terminal *term, int scale) { return term->conf->dpi_aware == DPI_AWARE_YES || - (term->conf->dpi_aware == DPI_AWARE_AUTO && new_scale <= 1); + (term->conf->dpi_aware == DPI_AWARE_AUTO && scale <= 1); } static bool -font_sized_by_dpi(const struct terminal *term) +font_sized_by_scale(const struct terminal *term, int scale) { - return font_size_by_dpi_for_scale(term, term->font_scale); -} - -static bool -font_sized_by_scale(const struct terminal *term) -{ - return !font_sized_by_dpi(term); + return !font_sized_by_dpi(term, scale); } @@ -824,7 +818,8 @@ reload_fonts(struct terminal *term) bool use_px_size = term->font_sizes[i][j].px_size > 0; char size[64]; - const int scale = font_sized_by_scale(term) ? term->scale : 1; + const int scale = + font_sized_by_scale(term, term->scale) ? term->scale : 1; if (use_px_size) snprintf(size, sizeof(size), ":pixelsize=%d", @@ -860,7 +855,7 @@ reload_fonts(struct terminal *term) const size_t count_bold_italic = custom_bold_italic ? counts[3] : counts[0]; const char **names_bold_italic = (const char **)(custom_bold_italic ? names[3] : names[0]); - const bool use_dpi = font_sized_by_dpi(term); + const bool use_dpi = font_sized_by_dpi(term, term->scale); char *attrs[4] = {NULL}; int attr_len[4] = {-1, -1, -1, -1}; /* -1, so that +1 (below) results in 0 */ @@ -1043,7 +1038,6 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, xmalloc(sizeof(term->font_sizes[3][0]) * tll_length(conf->fonts[3])), }, .font_dpi = 0., - .font_scale = 0, .font_subpixel = (conf->colors.alpha == 0xffff /* Can't do subpixel rendering on transparent background */ ? FCFT_SUBPIXEL_DEFAULT : FCFT_SUBPIXEL_NONE), @@ -1169,7 +1163,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, goto err; /* Load fonts */ - if (!term_font_dpi_changed(term)) + if (!term_font_dpi_changed(term, 0)) goto err; term->font_subpixel = get_font_subpixel(term); @@ -1770,19 +1764,19 @@ term_font_size_reset(struct terminal *term) } bool -term_font_dpi_changed(struct terminal *term) +term_font_dpi_changed(struct terminal *term, int old_scale) { float dpi = get_font_dpi(term); xassert(term->scale > 0); - bool was_scaled_using_dpi = font_sized_by_dpi(term); - bool will_scale_using_dpi = font_size_by_dpi_for_scale(term, term->scale); + bool was_scaled_using_dpi = font_sized_by_dpi(term, old_scale); + bool will_scale_using_dpi = font_sized_by_dpi(term, term->scale); bool need_font_reload = was_scaled_using_dpi != will_scale_using_dpi || (will_scale_using_dpi ? term->font_dpi != dpi - : term->font_scale != term->scale); + : old_scale != term->scale); if (need_font_reload) { LOG_DBG("DPI/scale change: DPI-awareness=%s, " @@ -1795,7 +1789,6 @@ term_font_dpi_changed(struct terminal *term) } term->font_dpi = dpi; - term->font_scale = term->scale; if (!need_font_reload) return true; diff --git a/terminal.h b/terminal.h index 42e2fd2a..472b4938 100644 --- a/terminal.h +++ b/terminal.h @@ -320,7 +320,6 @@ struct terminal { struct config_font *font_sizes[4]; struct pt_or_px font_line_height; float font_dpi; - int font_scale; /* scaling factor last time we loaded fonts */ int16_t font_x_ofs; int16_t font_y_ofs; enum fcft_subpixel font_subpixel; @@ -614,7 +613,7 @@ bool term_paste_data_to_slave( bool term_font_size_increase(struct terminal *term); bool term_font_size_decrease(struct terminal *term); bool term_font_size_reset(struct terminal *term); -bool term_font_dpi_changed(struct terminal *term); +bool term_font_dpi_changed(struct terminal *term, int old_scale); void term_font_subpixel_changed(struct terminal *term); int term_pt_or_px_as_pixels( const struct terminal *term, const struct pt_or_px *pt_or_px); diff --git a/wayland.c b/wayland.c index 24d22359..e1055101 100644 --- a/wayland.c +++ b/wayland.c @@ -285,8 +285,10 @@ update_term_for_output_change(struct terminal *term) if (tll_length(term->window->on_outputs) == 0) return; + int old_scale = term->scale; + render_resize(term, term->width / term->scale, term->height / term->scale); - term_font_dpi_changed(term); + term_font_dpi_changed(term, old_scale); term_font_subpixel_changed(term); }