diff --git a/CHANGELOG.md b/CHANGELOG.md index 5051283d..3afa2ccb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,10 +78,13 @@ means foot can be PGO:d in e.g. sandboxed build scripts. See * **bold-text-in-bright** option to `foot.ini`. When enabled, bold text is rendered in a brighter color (https://codeberg.org/dnkl/foot/issues/199). -* **dpi-aware** option to `foot.ini`. The default, **enabled**, - implements foot's old font sizing behavior. But, when **disabled**, - foot will ignore the monitors' DPI and instead size fonts using the - scale factor alone (https://codeberg.org/dnkl/foot/issues/206). +* **dpi-aware** option to `foot.ini`. The default, `auto`, sizes fonts + using the monitor’s DPI when output scaling has been + **disabled**. If output scaling has been **enabled**, fonts are + sized using the scaling factor. DPI-only font sizing can be forced + by setting `dpi-aware=yes`. Setting `dpi-aware=no` forces font + sizing to be based on the scaling factor. + (https://codeberg.org/dnkl/foot/issues/206). * `-w,--window-size-pixels` and `-W,--window-size-chars` command line options to `footclient` (https://codeberg.org/dnkl/foot/issues/189). * Short command line options for `--title`, `--maximized`, diff --git a/config.c b/config.c index 7434896a..bf184a16 100644 --- a/config.c +++ b/config.c @@ -548,8 +548,12 @@ parse_section_main(const char *key, const char *value, struct config *conf, free(copy); } - else if (strcmp(key, "dpi-aware") == 0) - conf->dpi_aware = str_to_bool(value); + else if (strcmp(key, "dpi-aware") == 0) { + if (strcmp(value, "auto") == 0) + conf->dpi_aware = DPI_AWARE_AUTO; + else + conf->dpi_aware = str_to_bool(value) ? DPI_AWARE_YES : DPI_AWARE_NO; + } else if (strcmp(key, "workers") == 0) { unsigned long count; @@ -1959,7 +1963,7 @@ config_load(struct config *conf, const char *conf_path, .bell_action = BELL_ACTION_NONE, .startup_mode = STARTUP_WINDOWED, .fonts = {tll_init(), tll_init(), tll_init(), tll_init()}, - .dpi_aware = true, /* Use DPI by default, not scale factor */ + .dpi_aware = DPI_AWARE_AUTO, /* DPI-aware when scaling-factor == 1 */ .scrollback = { .lines = 1000, .indicator = { diff --git a/config.h b/config.h index 57af908e..a1b27c04 100644 --- a/config.h +++ b/config.h @@ -80,7 +80,7 @@ struct config { enum { STARTUP_WINDOWED, STARTUP_MAXIMIZED, STARTUP_FULLSCREEN } startup_mode; - bool dpi_aware; + enum {DPI_AWARE_AUTO, DPI_AWARE_YES, DPI_AWARE_NO} dpi_aware; config_font_list_t fonts[4]; struct { diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index 8397b118..c03342cf 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -44,19 +44,24 @@ in this order: *font-italic*, *font-bold-italic*). *dpi-aware* - Boolean. When enabled, fonts are sized using the monitor's DPI, - making a font of a given size have the same physical size, - regardless of monitor. In other words, if you drag a foot window - between different monitors, the font size remains the same. + *auto*, *yes*, or *no*. When set to *yes*, fonts are sized using + the monitor's DPI, making a font of a given size have the same + physical size, regardless of monitor. In other words, if you drag + a foot window between different monitors, the font size remains + the same. - In this mode, the monitor's scale factor is ignored; doubling the - scale factor will *not* double the font size. + In this mode, the monitor's scaling factor is ignored; doubling + the scaling factor will *not* double the font size. - When disabled, the monitor's DPI is ignored. The font is instead - sized using the monitor's scale factor; doubling the scale factor - *does* double the font size. - - Default: _yes_ + When set to *no*, the monitor's DPI is ignored. The font is + instead sized using the monitor's scaling factor; doubling the + scaling factor *does* double the font size. + + Finally, if set to *auto*, fonts will be sized using the monitor's + DPI on monitors with a scaling factor of 1, but otherwise size + fonts using the scaling factor. + + Default: _auto_ *pad* Padding between border and glyphs, in pixels (subject to output diff --git a/terminal.c b/terminal.c index 5223982e..489d7e3c 100644 --- a/terminal.c +++ b/terminal.c @@ -776,6 +776,26 @@ get_font_subpixel(const struct terminal *term) return FCFT_SUBPIXEL_DEFAULT; } +static bool +font_should_size_by_dpi(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) +{ + return font_should_size_by_dpi(term, term->font_scale); +} + +static bool +font_size_by_scale(const struct terminal *term) +{ + return !font_size_by_dpi(term); +} + + struct font_load_data { size_t count; const char **names; @@ -812,7 +832,7 @@ reload_fonts(struct terminal *term) bool use_px_size = term->font_sizes[i][j].px_size > 0; char size[64]; - const int scale = term->conf->dpi_aware ? 1 : term->scale; + const int scale = font_size_by_scale(term) ? term->scale : 1; if (use_px_size) snprintf(size, sizeof(size), ":pixelsize=%d", @@ -843,12 +863,12 @@ reload_fonts(struct terminal *term) const char **names_bold = (const char **)(custom_bold ? names[1] : names[0]); const size_t count_italic = custom_italic ? counts[2] : counts[0]; - const char **names_italic = (const char **)(custom_italic ? names[2] : names[0]); + const char **names_italic = (const char **)(custom_italic ? names[2] : names[0]); 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 = term->conf->dpi_aware; + const bool use_dpi = font_size_by_dpi(term); char *attrs[4] = {NULL}; int attr_len[4] = {-1, -1, -1, -1}; /* -1, so that +1 (below) results in 0 */ @@ -1673,23 +1693,34 @@ term_font_size_reset(struct terminal *term) bool term_font_dpi_changed(struct terminal *term) { - if (term->conf->dpi_aware) { - float dpi = get_font_dpi(term); - if (dpi == term->font_dpi) - return true; + float dpi = get_font_dpi(term); + int scale = get_font_scale(term); - LOG_DBG("DPI changed (%.2f -> %.2f): reloading fonts", term->font_dpi, dpi); - term->font_dpi = dpi; - } else { - int scale = get_font_scale(term); - if (scale == term->font_scale) - return true; + bool was_scaled_using_dpi = font_size_by_dpi(term); + bool will_scale_using_dpi = font_should_size_by_dpi(term, scale); - LOG_DBG("scale factor changed (%d -> %d): reloading fonts", - term->font_scale, scale); - term->font_scale = 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); + + if (need_font_reload) { + LOG_DBG("DPI/scale change: DPI-awareness=%s, " + "DPI: %.2f -> %.2f, scale: %d -> %d, " + "sizing font based on monitor's %s", + term->conf->dpi_aware == DPI_AWARE_AUTO ? "auto" : + term->conf->dpi_aware == DPI_AWARE_ON ? "yes" : "no", + term->font_dpi, dpi, term->font_scale, scale, + will_scale_using_dpi ? "DPI" : "scaling factor"); } + term->font_dpi = dpi; + term->font_scale = scale; + + if (!need_font_reload) + return true; + return reload_fonts(term); }