pt-or-px: heed the dpi-aware setting

Before this patch, pt-or-px values, like letter-spacing, were *always*
scaled using the current DPI value.

This is wrong; if the fonts are scaled using the output’s scaling
factor, then so should all other point values.

This also fixes an issue where e.g. letter-spacing would use one DPI
value at startup, but then when increasing/decreasing or resetting the
font size, would be re-calculated using a different DPI value, leading
to completely different spacing.

This happened when there were multiple monitors, with different DPI
values, and foot guessed the initial DPI value wrong. Normally, foot
would correct itself as soon as the window was mapped, and the
“correct” DPI value known. But if the fonts were scaled using the
scaling factor, it was possible that the font reload never happened.

This patch also updates the thickness calculation (for LIGHT and HEAVY
box drawing characters) to use the scaling factor when appropriate.

Closes #680
This commit is contained in:
Daniel Eklöf 2021-08-13 17:38:56 +02:00
parent a37109e5f6
commit f6f8f2b35e
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
4 changed files with 62 additions and 46 deletions

View file

@ -25,9 +25,6 @@ struct buf {
int width;
int height;
int stride;
int dpi;
float cell_size;
float base_thickness;
bool solid_shades;
int thickness[2];
@ -63,17 +60,15 @@ change_buffer_format(struct buf *buf, pixman_format_code_t new_format)
}
static int NOINLINE
_thickness(struct buf *buf, enum thickness thick)
_thickness(int base_thickness, enum thickness thick)
{
int multiplier = thick * 2 + 1;
xassert(base_thickness >= 1);
xassert((thick == LIGHT && multiplier == 1) ||
(thick == HEAVY && multiplier == 3));
return
max(
(int)(buf->base_thickness * buf->dpi / 72.0 * buf->cell_size), 1)
* multiplier;
return base_thickness * multiplier;
}
#define thickness(thick) buf->thickness[thick]
@ -2751,25 +2746,13 @@ box_drawing(const struct terminal *term, wchar_t wc)
abort();
}
struct buf buf = {
.data = data,
.pix = pix,
.format = fmt,
.width = width,
.height = height,
.stride = stride,
.dpi = term->font_dpi,
.cell_size = sqrt(pow(term->cell_width, 2) + pow(term->cell_height, 2)),
.base_thickness = term->conf->tweak.box_drawing_base_thickness,
.solid_shades = term->conf->tweak.box_drawing_solid_shades,
};
double dpi = term_font_sized_by_dpi(term, term->scale) ? term->font_dpi : 96.;
double scale = term_font_sized_by_scale(term, term->scale) ? term->scale : 1.;
double cell_size = sqrt(pow(term->cell_width, 2) + pow(term->cell_height, 2));
buf.thickness[LIGHT] = _thickness(&buf, LIGHT);
buf.thickness[HEAVY] = _thickness(&buf, HEAVY);
/* Overlap when width is odd */
buf.x_halfs[0] = round(width / 2.); /* Endpoint first half */
buf.x_halfs[1] = width / 2; /* Startpoint second half */
int base_thickness =
(double)term->conf->tweak.box_drawing_base_thickness * scale * cell_size * dpi / 72.0;
base_thickness = max(base_thickness, 1);
int y0 = 0, y1 = 0;
switch (height % 3) {
@ -2789,8 +2772,31 @@ box_drawing(const struct terminal *term, wchar_t wc)
break;
}
buf.y_thirds[0] = y0; /* Endpoint first third, start point second third */
buf.y_thirds[1] = y1; /* Endpoint second third, start point last third */
struct buf buf = {
.data = data,
.pix = pix,
.format = fmt,
.width = width,
.height = height,
.stride = stride,
.solid_shades = term->conf->tweak.box_drawing_solid_shades,
.thickness = {
[LIGHT] = _thickness(base_thickness, LIGHT),
[HEAVY] = _thickness(base_thickness, HEAVY),
},
/* Overlap when width is odd */
.x_halfs = {
round(width / 2.), /* Endpoint first half */
width / 2, /* Startpoint second half */
},
.y_thirds = {
y0, /* Endpoint first third, start point second third */
y1, /* Endpoint second third, start point last third */
},
};
LOG_DBG("LIGHT=%d, HEAVY=%d",
_thickness(&buf, LIGHT), _thickness(&buf, HEAVY));