config: add ‘font-size-adjustment=N[px|%]’ option

This patch adds a new config option, font-size-adjustment.

It lets you configure how much the font size should be
incremented/decremented when zooming in or out (ctrl-+, ctrl+-).

Values can be specified in points, pixels or percent.

Closes #1188
This commit is contained in:
Daniel Eklöf 2022-12-15 11:10:32 +01:00
parent 7bb5c80d04
commit f6ca8c90e1
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
6 changed files with 120 additions and 19 deletions

View file

@ -52,10 +52,14 @@
* String values in `foot.ini` may now be quoted. This can be used to
set a value to the empty string, for example.
* Environment variables can now be **unset**, by setting
`[environment].<variable>=""` (quotes are required) ([#1225][1225])
`[environment].<variable>=""` (quotes are required) ([#1225][1225]).
* `font-size-adjustment=N[px]` option, letting you configure how much
to increment/decrement the font size when zooming in or out
([#1188][1188]).
[1136]: https://codeberg.org/dnkl/foot/issues/1136
[1225]: https://codeberg.org/dnkl/foot/issues/1225
[1188]: https://codeberg.org/dnkl/foot/issues/1188
### Changed

View file

@ -925,6 +925,31 @@ parse_section_main(struct context *ctx)
return true;
}
else if (strcmp(key, "font-size-adjustment") == 0) {
const size_t len = strlen(ctx->value);
if (len >= 1 && ctx->value[len - 1] == '%') {
errno = 0;
char *end = NULL;
float percent = strtof(ctx->value, &end);
if (!(errno == 0 && end == ctx->value + len - 1)) {
LOG_CONTEXTUAL_ERR(
"invalid percent value (must be in the form 10.5%%)");
return false;
}
conf->font_size_adjustment.percent = percent / 100.;
conf->font_size_adjustment.pt_or_px.pt = 0;
conf->font_size_adjustment.pt_or_px.px = 0;
return true;
} else {
bool ret = value_to_pt_or_px(ctx, &conf->font_size_adjustment.pt_or_px);
if (ret)
conf->font_size_adjustment.percent = 0.;
return ret;
}
}
else if (strcmp(key, "line-height") == 0)
return value_to_pt_or_px(ctx, &conf->line_height);
@ -2886,6 +2911,7 @@ config_load(struct config *conf, const char *conf_path,
},
.startup_mode = STARTUP_WINDOWED,
.fonts = {{0}},
.font_size_adjustment = {.percent = 0., .pt_or_px = {.pt = 0.5, .px = 0}},
.line_height = {.pt = 0, .px = -1},
.letter_spacing = {.pt = 0, .px = 0},
.horizontal_letter_offset = {.pt = 0, .px = 0},

View file

@ -22,6 +22,11 @@ struct pt_or_px {
float pt;
};
struct font_size_adjustment {
struct pt_or_px pt_or_px;
float percent;
};
enum cursor_style { CURSOR_BLOCK, CURSOR_UNDERLINE, CURSOR_BEAM };
enum conf_size_type {CONF_SIZE_PX, CONF_SIZE_CELLS};
@ -139,6 +144,7 @@ struct config {
enum {DPI_AWARE_AUTO, DPI_AWARE_YES, DPI_AWARE_NO} dpi_aware;
struct config_font_list fonts[4];
struct font_size_adjustment font_size_adjustment;
/* Custom font metrics (-1 = use real font metrics) */
struct pt_or_px line_height;

View file

@ -80,6 +80,19 @@ empty string to be set, but it must be quoted: *KEY=""*)
Default: _monospace:size=8_ (*font*), _not set_ (*font-bold*,
*font-italic*, *font-bold-italic*).
*font-size-adjustment*
Amount, in _points_, _pixels_ or _percent_, to increment/decrement
the font size when zooming in our out.
Examples:
```
font-size-adjustment=0.5 # Adjust by 0.5 points
font-size-adjustment=10xp # Adjust by 10 pixels
font-size-adjustment=7.5% # Adjust by 7.5 percent
```
Default: _0.5_
*include*
Absolute path to configuration file to import.

View file

@ -2035,29 +2035,70 @@ term_reset(struct terminal *term, bool hard)
}
static bool
term_font_size_adjust(struct terminal *term, double amount)
term_font_size_adjust_by_points(struct terminal *term, float amount)
{
const struct config *conf = term->conf;
const float dpi = term->font_is_sized_by_dpi ? term->font_dpi : 96.;
for (size_t i = 0; i < 4; i++) {
const struct config_font_list *font_list = &conf->fonts[i];
for (size_t j = 0; j < font_list->count; j++) {
float old_pt_size = term->font_sizes[i][j].pt_size;
struct config_font *font = &term->font_sizes[i][j];
float old_pt_size = font->pt_size;
/*
* To ensure primary and user-configured fallback fonts are
* resizes by the same amount, convert pixel sizes to point
* sizes, and to the adjustment on point sizes only.
*/
if (font->px_size > 0)
old_pt_size = font->px_size * 72. / dpi;
if (term->font_sizes[i][j].px_size > 0)
old_pt_size = term->font_sizes[i][j].px_size * 72. / dpi;
font->pt_size = fmaxf(old_pt_size + amount, 0.);
font->px_size = -1;
}
}
term->font_sizes[i][j].pt_size = fmaxf(old_pt_size + amount, 0.);
term->font_sizes[i][j].px_size = -1;
return reload_fonts(term);
}
static bool
term_font_size_adjust_by_pixels(struct terminal *term, int amount)
{
const struct config *conf = term->conf;
const float dpi = term->font_is_sized_by_dpi ? term->font_dpi : 96.;
for (size_t i = 0; i < 4; i++) {
const struct config_font_list *font_list = &conf->fonts[i];
for (size_t j = 0; j < font_list->count; j++) {
struct config_font *font = &term->font_sizes[i][j];
int old_px_size = font->px_size;
if (font->px_size <= 0)
old_px_size = font->pt_size * dpi / 72.;
font->px_size = max(old_px_size + amount, 1);
}
}
return reload_fonts(term);
}
static bool
term_font_size_adjust_by_percent(struct terminal *term, bool increment, float percent)
{
const struct config *conf = term->conf;
const float multiplier = increment
? 1. + percent
: 1. / (1. + percent);
for (size_t i = 0; i < 4; i++) {
const struct config_font_list *font_list = &conf->fonts[i];
for (size_t j = 0; j < font_list->count; j++) {
struct config_font *font = &term->font_sizes[i][j];
if (font->px_size > 0)
font->px_size = max(font->px_size * multiplier, 1);
else
font->pt_size = fmax(font->pt_size * multiplier, 0);
}
}
@ -2067,19 +2108,29 @@ term_font_size_adjust(struct terminal *term, double amount)
bool
term_font_size_increase(struct terminal *term)
{
if (!term_font_size_adjust(term, 0.5))
return false;
const struct config *conf = term->conf;
const struct font_size_adjustment *inc_dec = &conf->font_size_adjustment;
return true;
if (inc_dec->percent > 0.)
return term_font_size_adjust_by_percent(term, true, inc_dec->percent);
else if (inc_dec->pt_or_px.px > 0)
return term_font_size_adjust_by_pixels(term, inc_dec->pt_or_px.px);
else
return term_font_size_adjust_by_points(term, inc_dec->pt_or_px.pt);
}
bool
term_font_size_decrease(struct terminal *term)
{
if (!term_font_size_adjust(term, -0.5))
return false;
const struct config *conf = term->conf;
const struct font_size_adjustment *inc_dec = &conf->font_size_adjustment;
return true;
if (inc_dec->percent > 0.)
return term_font_size_adjust_by_percent(term, false, inc_dec->percent);
else if (inc_dec->pt_or_px.px > 0)
return term_font_size_adjust_by_pixels(term, -inc_dec->pt_or_px.px);
else
return term_font_size_adjust_by_points(term, -inc_dec->pt_or_px.pt);
}
bool

View file

@ -467,6 +467,7 @@ test_section_main(void)
test_boolean(&ctx, &parse_section_main, "locked-title", &conf.locked_title);
test_boolean(&ctx, &parse_section_main, "notify-focus-inhibit", &conf.notify_focus_inhibit);
test_pt_or_px(&ctx, &parse_section_main, "font-size-adjustment", &conf.font_size_adjustment.pt_or_px); /* TODO: test N% values too */
test_pt_or_px(&ctx, &parse_section_main, "line-height", &conf.line_height);
test_pt_or_px(&ctx, &parse_section_main, "letter-spacing", &conf.letter_spacing);
test_pt_or_px(&ctx, &parse_section_main, "horizontal-letter-offset", &conf.horizontal_letter_offset);