diff --git a/CHANGELOG.md b/CHANGELOG.md index 671fb78b..b415d051 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,11 @@ * Foot now sends `SIGTERM`/`SIGKILL` to the client application’s process group, instead of just to the client application’s process. * `kmous` terminfo capability from `\E[M` to `\E[<`. +* pt-or-px values (`letter-spacing`, etc) and the line thickness + (`tweak.box-drawing-base-thickness`) in box drawing characters are + now translated to pixel values using the monitor’s scaling factor + when `dpi-aware=no`, or `dpi-aware=auto` and the scaling factor is + larger than 1 (https://codeberg.org/dnkl/foot/issues/680). ### Deprecated diff --git a/box-drawing.c b/box-drawing.c index 62716106..f246fd01 100644 --- a/box-drawing.c +++ b/box-drawing.c @@ -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)); diff --git a/terminal.c b/terminal.c index de397ec1..2be92dda 100644 --- a/terminal.c +++ b/terminal.c @@ -627,15 +627,6 @@ err_sem_destroy: return false; } -int -term_pt_or_px_as_pixels(const struct terminal *term, - const struct pt_or_px *pt_or_px) -{ - return pt_or_px->px == 0 - ? round(pt_or_px->pt * term->font_dpi / 72) - : pt_or_px->px; -} - static void free_box_drawing(struct fcft_glyph **box_drawing) { @@ -802,19 +793,30 @@ get_font_subpixel(const struct terminal *term) return FCFT_SUBPIXEL_DEFAULT; } -static bool -font_sized_by_dpi(const struct terminal *term, int scale) +bool +term_font_sized_by_dpi(const struct terminal *term, int scale) { return term->conf->dpi_aware == DPI_AWARE_YES || (term->conf->dpi_aware == DPI_AWARE_AUTO && scale <= 1); } -static bool -font_sized_by_scale(const struct terminal *term, int scale) +bool +term_font_sized_by_scale(const struct terminal *term, int scale) { - return !font_sized_by_dpi(term, scale); + return !term_font_sized_by_dpi(term, scale); } +int +term_pt_or_px_as_pixels(const struct terminal *term, + const struct pt_or_px *pt_or_px) +{ + double scale = term_font_sized_by_scale(term, term->scale) ? term->scale : 1.; + double dpi = term_font_sized_by_dpi(term, term->scale) ? term->font_dpi : 96.; + + return pt_or_px->px == 0 + ? round(pt_or_px->pt * scale * dpi / 72) + : pt_or_px->px; +} struct font_load_data { size_t count; @@ -857,7 +859,7 @@ reload_fonts(struct terminal *term) char size[64]; const int scale = - font_sized_by_scale(term, term->scale) ? term->scale : 1; + term_font_sized_by_scale(term, term->scale) ? term->scale : 1; if (use_px_size) snprintf(size, sizeof(size), ":pixelsize=%d", @@ -892,7 +894,7 @@ 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 = font_sized_by_dpi(term, term->scale); + const bool use_dpi = term_font_sized_by_dpi(term, term->scale); char *attrs[4] = {NULL}; int attr_len[4] = {-1, -1, -1, -1}; /* -1, so that +1 (below) results in 0 */ @@ -1981,8 +1983,8 @@ term_font_dpi_changed(struct terminal *term, int old_scale) float dpi = get_font_dpi(term); xassert(term->scale > 0); - bool was_scaled_using_dpi = font_sized_by_dpi(term, old_scale); - bool will_scale_using_dpi = font_sized_by_dpi(term, term->scale); + bool was_scaled_using_dpi = term_font_sized_by_dpi(term, old_scale); + bool will_scale_using_dpi = term_font_sized_by_dpi(term, term->scale); bool need_font_reload = was_scaled_using_dpi != will_scale_using_dpi || diff --git a/terminal.h b/terminal.h index 74a8f2de..f394a5b0 100644 --- a/terminal.h +++ b/terminal.h @@ -643,6 +643,9 @@ bool term_font_size_decrease(struct terminal *term); bool term_font_size_reset(struct terminal *term); bool term_font_dpi_changed(struct terminal *term, int old_scale); void term_font_subpixel_changed(struct terminal *term); + +bool term_font_sized_by_dpi(const struct terminal *term, int scale); +bool term_font_sized_by_scale(const struct terminal *term, int scale); int term_pt_or_px_as_pixels( const struct terminal *term, const struct pt_or_px *pt_or_px);