mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
config: line-height, letter-spacing: values are in pt by default, but we allow px
If the value is specified without a unit, then the value is assumed to be in points, subject to DPI scaling. The value can optionally have a ‘px’ suffix, in which case the value is treated as a raw pixel count.
This commit is contained in:
parent
4c9f593d91
commit
a6fc8b5da4
6 changed files with 97 additions and 61 deletions
|
|
@ -2064,13 +2064,23 @@ box_drawing(const struct terminal *term, wchar_t wc)
|
|||
};
|
||||
draw_glyph(wc, &buf);
|
||||
|
||||
const struct config *conf = term->conf;
|
||||
|
||||
int x_ofs = conf->horizontal_letter_offset.px > 0
|
||||
? conf->horizontal_letter_offset.px
|
||||
: conf->horizontal_letter_offset.pt * term->font_dpi / 72.;
|
||||
int y_ofs = conf->vertical_letter_offset.px > 0
|
||||
? conf->vertical_letter_offset.px
|
||||
: conf->vertical_letter_offset.pt * term->font_dpi / 72.;
|
||||
|
||||
|
||||
struct fcft_glyph *glyph = xmalloc(sizeof(*glyph));
|
||||
*glyph = (struct fcft_glyph){
|
||||
.wc = wc,
|
||||
.cols = 1,
|
||||
.pix = pix,
|
||||
.x = -term->conf->horizontal_letter_offset,
|
||||
.y = term->conf->vertical_letter_offset + term->fonts[0]->ascent,
|
||||
.x = -x_ofs,
|
||||
.y = y_ofs + term->fonts[0]->ascent,
|
||||
.width = width,
|
||||
.height = height,
|
||||
.advance = {
|
||||
|
|
|
|||
93
config.c
93
config.c
|
|
@ -360,19 +360,6 @@ str_to_bool(const char *s)
|
|||
strtoul(s, NULL, 0) > 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
str_to_long(const char *s, int base, long *res)
|
||||
{
|
||||
if (s == NULL)
|
||||
return false;
|
||||
|
||||
errno = 0;
|
||||
char *end = NULL;
|
||||
|
||||
*res = strtol(s, &end, base);
|
||||
return errno == 0 && *end == '\0';
|
||||
}
|
||||
|
||||
static bool
|
||||
str_to_ulong(const char *s, int base, unsigned long *res)
|
||||
{
|
||||
|
|
@ -422,6 +409,40 @@ str_to_color(const char *s, uint32_t *color, bool allow_alpha,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
str_to_pt_or_px(const char *s, union pt_or_px *res, struct config *conf,
|
||||
const char *path, int lineno, const char *section, const char *key)
|
||||
{
|
||||
size_t len = s != NULL ? strlen(s) : 0;
|
||||
if (len >= 2 && s[len - 2] == 'p' && s[len - 1] == 'x') {
|
||||
errno = 0;
|
||||
char *end = NULL;
|
||||
|
||||
long value = strtol(s, &end, 10);
|
||||
if (!(errno == 0 && end == s + len - 2)) {
|
||||
LOG_AND_NOTIFY_ERR(
|
||||
"%s:%d: [%s]: %s: "
|
||||
"expected an integer directly followed by 'px', got '%s'",
|
||||
path, lineno, section, key, s);
|
||||
return false;
|
||||
}
|
||||
res->pt = 0;
|
||||
res->px = value;
|
||||
} else {
|
||||
double value;
|
||||
if (!str_to_double(s, &value)) {
|
||||
LOG_AND_NOTIFY_ERR(
|
||||
"%s:%d: [%s]: %s: expected a decimal value, got '%s'",
|
||||
path, lineno, section, key, s);
|
||||
return false;
|
||||
}
|
||||
res->pt = value;
|
||||
res->px = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_section_main(const char *key, const char *value, struct config *conf,
|
||||
const char *path, unsigned lineno)
|
||||
|
|
@ -572,47 +593,29 @@ parse_section_main(const char *key, const char *value, struct config *conf,
|
|||
}
|
||||
|
||||
else if (strcmp(key, "line-height") == 0) {
|
||||
unsigned long height;
|
||||
if (!str_to_ulong(value, 10, &height)) {
|
||||
LOG_AND_NOTIFY_ERR(
|
||||
"%s:%d: [default]: line-height: expected an integer, got '%s'",
|
||||
path, lineno, value);
|
||||
if (!str_to_pt_or_px(value, &conf->line_height,
|
||||
conf, path, lineno, "default", "line-height"))
|
||||
return false;
|
||||
}
|
||||
conf->line_height = height;
|
||||
}
|
||||
|
||||
else if (strcmp(key, "letter-spacing") == 0) {
|
||||
long spacing;
|
||||
if (!str_to_long(value, 10, &spacing)) {
|
||||
LOG_AND_NOTIFY_ERR(
|
||||
"%s:%d: [default]: letter-spacing: expected an integer, got '%s'",
|
||||
path, lineno, value);
|
||||
if (!str_to_pt_or_px(value, &conf->letter_spacing,
|
||||
conf, path, lineno, "default", "letter-spacing"))
|
||||
return false;
|
||||
}
|
||||
conf->letter_spacing = spacing;
|
||||
}
|
||||
|
||||
else if (strcmp(key, "horizontal-letter-offset") == 0) {
|
||||
long offset;
|
||||
if (!str_to_long(value, 10, &offset)) {
|
||||
LOG_AND_NOTIFY_ERR(
|
||||
"%s:%d: [default]: horizontal-letter-offset: "
|
||||
"expected an integer, got '%s'", path, lineno, value);
|
||||
if (!str_to_pt_or_px(
|
||||
value, &conf->horizontal_letter_offset,
|
||||
conf, path, lineno, "default", "horizontal-letter-offset"))
|
||||
return false;
|
||||
}
|
||||
conf->horizontal_letter_offset = offset;
|
||||
}
|
||||
|
||||
else if (strcmp(key, "vertical-letter-offset") == 0) {
|
||||
long offset;
|
||||
if (!str_to_long(value, 10, &offset)) {
|
||||
LOG_AND_NOTIFY_ERR(
|
||||
"%s:%d: [default]: horizontal-letter-offset: "
|
||||
"expected an integer, got '%s'", path, lineno, value);
|
||||
if (!str_to_pt_or_px(
|
||||
value, &conf->horizontal_letter_offset,
|
||||
conf, path, lineno, "default", "vertical-letter-offset"))
|
||||
return false;
|
||||
}
|
||||
conf->vertical_letter_offset = offset;
|
||||
}
|
||||
|
||||
else if (strcmp(key, "dpi-aware") == 0) {
|
||||
|
|
@ -2039,10 +2042,10 @@ 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()},
|
||||
.line_height = -1,
|
||||
.letter_spacing = -1,
|
||||
.horizontal_letter_offset = 0,
|
||||
.vertical_letter_offset = 0,
|
||||
.line_height = { .pt = 0, .px = -1, },
|
||||
.letter_spacing = { .pt = 0, .px = 0, },
|
||||
.horizontal_letter_offset = {.pt = 0, .px = 0, },
|
||||
.vertical_letter_offset = {.pt = 0, .px = 0, },
|
||||
.dpi_aware = DPI_AWARE_AUTO, /* DPI-aware when scaling-factor == 1 */
|
||||
.scrollback = {
|
||||
.lines = 1000,
|
||||
|
|
|
|||
14
config.h
14
config.h
|
|
@ -54,6 +54,12 @@ struct config_mouse_binding {
|
|||
} pipe;
|
||||
};
|
||||
|
||||
/* If px == -1, neither px nor pt is valid. If px == 0, pt is valid, else px */
|
||||
union pt_or_px {
|
||||
int16_t px;
|
||||
float pt;
|
||||
};
|
||||
|
||||
struct config {
|
||||
char *term;
|
||||
char *shell;
|
||||
|
|
@ -85,12 +91,12 @@ struct config {
|
|||
config_font_list_t fonts[4];
|
||||
|
||||
/* Custom font metrics (-1 = use real font metrics) */
|
||||
int16_t line_height;
|
||||
int16_t letter_spacing;
|
||||
union pt_or_px line_height;
|
||||
union pt_or_px letter_spacing;
|
||||
|
||||
/* Adjusted letter x/y offsets */
|
||||
int16_t horizontal_letter_offset;
|
||||
int16_t vertical_letter_offset;
|
||||
union pt_or_px horizontal_letter_offset;
|
||||
union pt_or_px vertical_letter_offset;
|
||||
|
||||
struct {
|
||||
int lines;
|
||||
|
|
|
|||
8
render.c
8
render.c
|
|
@ -256,7 +256,7 @@ color_dim_for_search(pixman_color_t *color)
|
|||
static inline int
|
||||
font_baseline(const struct terminal *term)
|
||||
{
|
||||
return term->conf->vertical_letter_offset + term->fonts[0]->ascent;
|
||||
return term->font_y_ofs + term->fonts[0]->ascent;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -541,7 +541,7 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
|||
pixman_image_t *clr_pix = pixman_image_create_solid_fill(&fg);
|
||||
|
||||
if (glyph != NULL) {
|
||||
const int letter_x_ofs = term->conf->horizontal_letter_offset;
|
||||
const int letter_x_ofs = term->font_x_ofs;
|
||||
|
||||
if (unlikely(pixman_image_get_format(glyph->pix) == PIXMAN_a8r8g8b8)) {
|
||||
/* Glyph surface is a pre-rendered image (typically a color emoji...) */
|
||||
|
|
@ -1693,7 +1693,7 @@ render_osd(struct terminal *term,
|
|||
struct fcft_font *font = term->fonts[0];
|
||||
pixman_color_t fg = color_hex_to_pixman(_fg);
|
||||
|
||||
const int x_ofs = term->conf->horizontal_letter_offset;
|
||||
const int x_ofs = term->font_x_ofs;
|
||||
|
||||
for (size_t i = 0; i < wcslen(text); i++) {
|
||||
const struct fcft_glyph *glyph = fcft_glyph_rasterize(
|
||||
|
|
@ -2272,7 +2272,7 @@ render_search_box(struct terminal *term)
|
|||
|
||||
struct fcft_font *font = term->fonts[0];
|
||||
const int x_left = width - visible_width + margin;
|
||||
const int x_ofs = term->conf->horizontal_letter_offset;
|
||||
const int x_ofs = term->font_x_ofs;
|
||||
int x = x_left;
|
||||
int y = margin;
|
||||
pixman_color_t fg = color_hex_to_pixman(term->colors.table[0]);
|
||||
|
|
|
|||
27
terminal.c
27
terminal.c
|
|
@ -629,15 +629,30 @@ term_set_fonts(struct terminal *term, struct fcft_font *fonts[static 4])
|
|||
const int old_cell_width = term->cell_width;
|
||||
const int old_cell_height = term->cell_height;
|
||||
|
||||
term->cell_width = (term->fonts[0]->space_advance.x > 0
|
||||
? term->fonts[0]->space_advance.x
|
||||
: term->fonts[0]->max_advance.x)
|
||||
+ term->conf->letter_spacing;
|
||||
const struct config *conf = term->conf;
|
||||
|
||||
term->cell_height = term->conf->line_height >= 0
|
||||
? term->conf->line_height
|
||||
term->cell_width =
|
||||
(term->fonts[0]->space_advance.x > 0
|
||||
? term->fonts[0]->space_advance.x
|
||||
: term->fonts[0]->max_advance.x)
|
||||
+ (conf->letter_spacing.px > 0
|
||||
? conf->letter_spacing.px
|
||||
: conf->letter_spacing.pt * term->font_dpi / 72.);
|
||||
|
||||
term->cell_height = conf->line_height.px >= 0
|
||||
? (conf->line_height.px > 0
|
||||
? conf->line_height.px
|
||||
: conf->line_height.pt * term->font_dpi / 72.)
|
||||
: max(term->fonts[0]->height,
|
||||
term->fonts[0]->ascent + term->fonts[0]->descent);
|
||||
|
||||
term->font_x_ofs = conf->horizontal_letter_offset.px > 0
|
||||
? conf->horizontal_letter_offset.px
|
||||
: conf->horizontal_letter_offset.pt * term->font_dpi / 72.;
|
||||
term->font_y_ofs = conf->vertical_letter_offset.px > 0
|
||||
? conf->vertical_letter_offset.px
|
||||
: conf->vertical_letter_offset.pt * term->font_dpi / 72.;
|
||||
|
||||
LOG_INFO("cell width=%d, height=%d", term->cell_width, term->cell_height);
|
||||
|
||||
if (term->cell_width < old_cell_width ||
|
||||
|
|
|
|||
|
|
@ -265,6 +265,8 @@ struct terminal {
|
|||
struct config_font *font_sizes[4];
|
||||
float font_dpi;
|
||||
int font_scale;
|
||||
int16_t font_x_ofs;
|
||||
int16_t font_y_ofs;
|
||||
enum fcft_subpixel font_subpixel;
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue