config: add ‘dpi-aware’ option, defaulting to enabled

When disabled, foot no longers uses outputs’ DPI to scale the
font. Instead, it uses the outputs’ scaling factor.

That is, instead of appending “:dpi=123” to the fontconfig string,
modify the “:pixelsize” or “:size” attribute.

Closes #206
This commit is contained in:
Daniel Eklöf 2020-11-17 17:59:31 +01:00
parent 587fce68fa
commit 8e7658a135
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
7 changed files with 87 additions and 11 deletions

View file

@ -59,6 +59,10 @@
* **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).
### Changed

View file

@ -578,6 +578,9 @@ 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, "workers") == 0) {
unsigned long count;
if (!str_to_ulong(value, 10, &count)) {
@ -2024,6 +2027,7 @@ config_load(struct config *conf, const char *conf_path,
.bell_is_urgent = false,
.startup_mode = STARTUP_WINDOWED,
.fonts = {tll_init(), tll_init(), tll_init(), tll_init()},
.dpi_aware = true, /* Use DPI by default, not scale factor */
.scrollback = {
.lines = 1000,
.indicator = {

View file

@ -84,6 +84,7 @@ struct config {
enum { STARTUP_WINDOWED, STARTUP_MAXIMIZED, STARTUP_FULLSCREEN } startup_mode;
bool dpi_aware;
config_font_list_t fonts[4];
struct {

View file

@ -45,6 +45,21 @@ in this order:
Default: _monospace_ (*font*), _not set_ (*font-bold*,
*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.
In this mode, the monitor's scale factor is ignored; doubling the
scale 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_
*pad*
Padding between border and glyphs, in pixels (subject to output
scaling), on the form _XxY_. Default: _2x2_.

View file

@ -4,6 +4,7 @@
# font-bold=<bold variant of regular font>
# font-italic=<italic variant of regular font>
# font-bold-italic=<bold+italic variant of regular font>
# dpi-aware=yes
# initial-window-size-pixels=700x500 # Or,
# initial-window-size-chars=<COLSxROWS>
# initial-window-mode=windowed

View file

@ -701,6 +701,31 @@ 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;
assert(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)
{
@ -781,10 +806,14 @@ 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;
if (use_px_size)
snprintf(size, sizeof(size), ":pixelsize=%d", term->font_sizes[i][j].px_size);
snprintf(size, sizeof(size), ":pixelsize=%d",
term->font_sizes[i][j].px_size * scale);
else
snprintf(size, sizeof(size), ":size=%.2f", term->font_sizes[i][j].pt_size);
snprintf(size, sizeof(size), ":size=%.2f",
term->font_sizes[i][j].pt_size * (double)scale);
size_t len = strlen(it->item.pattern) + strlen(size) + 1;
names[i][j] = xmalloc(len);
@ -813,14 +842,24 @@ 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 = term->conf->dpi_aware;
char *attrs[4] = {NULL};
int attr_len[4] = {-1, -1, -1, -1}; /* -1, so that +1 (below) results in 0 */
for (size_t i = 0; i < 2; i++) {
attr_len[0] = snprintf(attrs[0], attr_len[0] + 1, "dpi=%.2f", term->font_dpi);
attr_len[1] = snprintf(attrs[1], attr_len[1] + 1, "dpi=%.2f:%s", term->font_dpi, !custom_bold ? "weight=bold" : "");
attr_len[2] = snprintf(attrs[2], attr_len[2] + 1, "dpi=%.2f:%s", term->font_dpi, !custom_italic ? "slant=italic" : "");
attr_len[3] = snprintf(attrs[3], attr_len[3] + 1, "dpi=%.2f:%s", term->font_dpi, !custom_bold_italic ? "weight=bold:slant=italic" : "");
attr_len[0] = snprintf(
attrs[0], attr_len[0] + 1, "dpi=%.2f",
use_dpi ? term->font_dpi : 75);
attr_len[1] = snprintf(
attrs[1], attr_len[1] + 1, "dpi=%.2f:%s",
use_dpi ? term->font_dpi : 75, !custom_bold ? "weight=bold" : "");
attr_len[2] = snprintf(
attrs[2], attr_len[2] + 1, "dpi=%.2f:%s",
use_dpi ? term->font_dpi : 75, !custom_italic ? "slant=italic" : "");
attr_len[3] = snprintf(
attrs[3], attr_len[3] + 1, "dpi=%.2f:%s",
use_dpi ? term->font_dpi : 75, !custom_bold_italic ? "weight=bold:slant=italic" : "");
if (i > 0)
continue;
@ -973,6 +1012,7 @@ 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),
@ -1619,12 +1659,22 @@ term_font_size_reset(struct terminal *term)
bool
term_font_dpi_changed(struct terminal *term)
{
float dpi = get_font_dpi(term);
if (dpi == term->font_dpi)
return true;
if (term->conf->dpi_aware) {
float dpi = get_font_dpi(term);
if (dpi == term->font_dpi)
return true;
LOG_DBG("DPI changed (%.2f -> %.2f): reloading fonts", term->font_dpi, dpi);
term->font_dpi = dpi;
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;
LOG_DBG("scale factor changed (%d -> %d): reloading fonts",
term->font_scale, scale);
term->font_scale = scale;
}
return reload_fonts(term);
}

View file

@ -227,6 +227,7 @@ struct terminal {
struct fcft_font *fonts[4];
struct config_font *font_sizes[4];
float font_dpi;
int font_scale;
enum fcft_subpixel font_subpixel;
bool is_sending_paste_data;