mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-17 05:33:52 -04:00
Merge branch 'scale-fonts-using-logical-dpi-plus-scale-factor'
This commit is contained in:
commit
59a1204c50
4 changed files with 82 additions and 23 deletions
|
|
@ -18,6 +18,8 @@
|
||||||
* Window size doubling when moving window between outputs with
|
* Window size doubling when moving window between outputs with
|
||||||
different scaling factors (https://codeberg.org/dnkl/foot/issues/3).
|
different scaling factors (https://codeberg.org/dnkl/foot/issues/3).
|
||||||
* Sixel images moved or deleted on window resize.
|
* Sixel images moved or deleted on window resize.
|
||||||
|
* Font being too small on monitors with fractional scaling
|
||||||
|
(https://codeberg.org/dnkl/foot/issues/5).
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
|
|
|
||||||
27
terminal.c
27
terminal.c
|
|
@ -532,18 +532,39 @@ term_set_fonts(struct terminal *term, struct font *fonts[static 4])
|
||||||
static unsigned
|
static unsigned
|
||||||
get_font_dpi(const struct terminal *term)
|
get_font_dpi(const struct terminal *term)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Use output's DPI to scale font. This is to ensure the font has
|
||||||
|
* the same physical height (if measured by a ruler) regardless of
|
||||||
|
* monitor.
|
||||||
|
*
|
||||||
|
* Conceptually, we use the physical monitor specs to calculate
|
||||||
|
* the DPI, and we ignore the output's scaling factor.
|
||||||
|
*
|
||||||
|
* However, to deal with fractional scaling, where we're told to
|
||||||
|
* render at e.g. 2x, but are then downscaled by the compositor to
|
||||||
|
* e.g. 1.25, we use the scaled DPI value multiplied by the scale
|
||||||
|
* factor instead.
|
||||||
|
*
|
||||||
|
* For integral scaling factors the resulting DPI is the same as
|
||||||
|
* if we had used the physical DPI.
|
||||||
|
*
|
||||||
|
* For fractional scaling factors we'll get a DPI *larger* than
|
||||||
|
* the physical DPI, that ends up being right when later
|
||||||
|
* downscaled by the compositor.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Use highest DPI from outputs we're mapped on */
|
/* Use highest DPI from outputs we're mapped on */
|
||||||
unsigned dpi = 0;
|
unsigned dpi = 0;
|
||||||
assert(term->window != NULL);
|
assert(term->window != NULL);
|
||||||
tll_foreach(term->window->on_outputs, it) {
|
tll_foreach(term->window->on_outputs, it) {
|
||||||
if (it->item->y_ppi > dpi)
|
if (it->item->ppi.scaled.y > dpi)
|
||||||
dpi = it->item->y_ppi;
|
dpi = it->item->ppi.scaled.y * term->scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're not mapped, use DPI from first monitor. Hopefully this is where we'll get mapped later... */
|
/* If we're not mapped, use DPI from first monitor. Hopefully this is where we'll get mapped later... */
|
||||||
if (dpi == 0) {
|
if (dpi == 0) {
|
||||||
tll_foreach(term->wl->monitors, it) {
|
tll_foreach(term->wl->monitors, it) {
|
||||||
dpi = it->item.y_ppi;
|
dpi = it->item.ppi.scaled.y * term->scale;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
39
wayland.c
39
wayland.c
|
|
@ -169,10 +169,16 @@ update_terms_on_monitor(struct monitor *mon)
|
||||||
static void
|
static void
|
||||||
output_update_ppi(struct monitor *mon)
|
output_update_ppi(struct monitor *mon)
|
||||||
{
|
{
|
||||||
int x_inches = mon->width_mm * 0.03937008;
|
if (mon->dim.mm.width == 0 || mon->dim.mm.height == 0)
|
||||||
int y_inches = mon->height_mm * 0.03937008;
|
return;
|
||||||
mon->x_ppi = mon->width_px / x_inches;
|
|
||||||
mon->y_ppi = mon->height_px / y_inches;
|
int x_inches = mon->dim.mm.width * 0.03937008;
|
||||||
|
int y_inches = mon->dim.mm.height * 0.03937008;
|
||||||
|
mon->ppi.real.x = mon->dim.px_real.width / x_inches;
|
||||||
|
mon->ppi.real.y = mon->dim.px_real.height / y_inches;
|
||||||
|
|
||||||
|
mon->ppi.scaled.x = mon->dim.px_scaled.width / x_inches;
|
||||||
|
mon->ppi.scaled.y = mon->dim.px_scaled.height / y_inches;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -182,9 +188,9 @@ output_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y,
|
||||||
int32_t transform)
|
int32_t transform)
|
||||||
{
|
{
|
||||||
struct monitor *mon = data;
|
struct monitor *mon = data;
|
||||||
mon->width_mm = physical_width;
|
mon->dim.mm.width = physical_width;
|
||||||
mon->height_mm = physical_height;
|
mon->dim.mm.height = physical_height;
|
||||||
mon->inch = sqrt(pow(mon->width_mm, 2) + pow(mon->height_mm, 2)) * 0.03937008;
|
mon->inch = sqrt(pow(mon->dim.mm.width, 2) + pow(mon->dim.mm.height, 2)) * 0.03937008;
|
||||||
mon->make = make != NULL ? strdup(make) : NULL;
|
mon->make = make != NULL ? strdup(make) : NULL;
|
||||||
mon->model = model != NULL ? strdup(model) : NULL;
|
mon->model = model != NULL ? strdup(model) : NULL;
|
||||||
output_update_ppi(mon);
|
output_update_ppi(mon);
|
||||||
|
|
@ -199,8 +205,8 @@ output_mode(void *data, struct wl_output *wl_output, uint32_t flags,
|
||||||
|
|
||||||
struct monitor *mon = data;
|
struct monitor *mon = data;
|
||||||
mon->refresh = (float)refresh / 1000;
|
mon->refresh = (float)refresh / 1000;
|
||||||
mon->width_px = width;
|
mon->dim.px_real.width = width;
|
||||||
mon->height_px = height;
|
mon->dim.px_real.height = height;
|
||||||
output_update_ppi(mon);
|
output_update_ppi(mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,6 +244,10 @@ static void
|
||||||
xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output,
|
xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output,
|
||||||
int32_t width, int32_t height)
|
int32_t width, int32_t height)
|
||||||
{
|
{
|
||||||
|
struct monitor *mon = data;
|
||||||
|
mon->dim.px_scaled.width = width;
|
||||||
|
mon->dim.px_scaled.height = height;
|
||||||
|
output_update_ppi(mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -786,11 +796,12 @@ wayl_init(const struct config *conf, struct fdm *fdm)
|
||||||
|
|
||||||
tll_foreach(wayl->monitors, it) {
|
tll_foreach(wayl->monitors, it) {
|
||||||
LOG_INFO(
|
LOG_INFO(
|
||||||
"%s: %dx%d+%dx%d@%dHz %s (%.2f\", PPI=%dx%d, scale=%d)",
|
"%s: %dx%d+%dx%d@%dHz %s %.2f\" scale=%d PPI=%dx%d (physical) PPI=%dx%d (logical)",
|
||||||
it->item.name, it->item.width_px, it->item.height_px,
|
it->item.name, it->item.dim.px_real.width, it->item.dim.px_real.height,
|
||||||
it->item.x, it->item.y, (int)round(it->item.refresh), it->item.model, it->item.inch,
|
it->item.x, it->item.y, (int)round(it->item.refresh),
|
||||||
it->item.x_ppi, it->item.y_ppi,
|
it->item.model, it->item.inch, it->item.scale,
|
||||||
it->item.scale);
|
it->item.ppi.real.x, it->item.ppi.real.y,
|
||||||
|
it->item.ppi.scaled.x, it->item.ppi.scaled.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clipboard */
|
/* Clipboard */
|
||||||
|
|
|
||||||
37
wayland.h
37
wayland.h
|
|
@ -24,14 +24,39 @@ struct monitor {
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
int width_mm;
|
struct {
|
||||||
int height_mm;
|
/* Physical size, in mm */
|
||||||
|
struct {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
} mm;
|
||||||
|
|
||||||
int width_px;
|
/* Physical size, in pixels */
|
||||||
int height_px;
|
struct {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
} px_real;
|
||||||
|
|
||||||
int x_ppi;
|
/* Scaled size, in pixels */
|
||||||
int y_ppi;
|
struct {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
} px_scaled;
|
||||||
|
} dim;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
/* PPI, based on physical size */
|
||||||
|
struct {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
} real;
|
||||||
|
|
||||||
|
/* PPI, logical, based on scaled size */
|
||||||
|
struct {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
} scaled;
|
||||||
|
} ppi;
|
||||||
|
|
||||||
int scale;
|
int scale;
|
||||||
float refresh;
|
float refresh;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue