mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
scaling: always round the scaling factor when converting to int
* In all calls to wl_subsurface_set_position() * (wp_viewport_set_destination() already does this) * Whenever we use the scale to calculate margins (search box, scrollback indicator etc) * Since the scaling factor is stored as a float (and not a double), use roundf() instead of round()
This commit is contained in:
parent
391bc119de
commit
613c61abb4
5 changed files with 104 additions and 80 deletions
12
csi.c
12
csi.c
|
|
@ -1208,8 +1208,8 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
char reply[64];
|
||||
size_t n = xsnprintf(
|
||||
reply, sizeof(reply), "\033[4;%d;%dt",
|
||||
(int)round(height / term->scale),
|
||||
(int)(width / term->scale));
|
||||
(int)roundf(height / term->scale),
|
||||
(int)roundf((width / term->scale)));
|
||||
term_to_slave(term, reply, n);
|
||||
}
|
||||
break;
|
||||
|
|
@ -1233,8 +1233,8 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
char reply[64];
|
||||
size_t n = xsnprintf(
|
||||
reply, sizeof(reply), "\033[6;%d;%dt",
|
||||
(int)round(term->cell_height / term->scale),
|
||||
(int)round(term->cell_width / term->scale));
|
||||
(int)roundf(term->cell_height / term->scale),
|
||||
(int)roundf(term->cell_width / term->scale));
|
||||
term_to_slave(term, reply, n);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1252,8 +1252,8 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
char reply[64];
|
||||
size_t n = xsnprintf(
|
||||
reply, sizeof(reply), "\033[9;%d;%dt",
|
||||
(int)round(it->item->dim.px_real.height / term->cell_height / term->scale),
|
||||
(int)round(it->item->dim.px_real.width / term->cell_width / term->scale));
|
||||
(int)roundf(it->item->dim.px_real.height / term->cell_height / term->scale),
|
||||
(int)roundf(it->item->dim.px_real.width / term->cell_width / term->scale));
|
||||
term_to_slave(term, reply, n);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
113
render.c
113
render.c
|
|
@ -306,7 +306,7 @@ static void
|
|||
draw_unfocused_block(const struct terminal *term, pixman_image_t *pix,
|
||||
const pixman_color_t *color, int x, int y, int cell_cols)
|
||||
{
|
||||
const int scale = round(term->scale);
|
||||
const int scale = (int)roundf(term->scale);
|
||||
const int width = min(min(scale, term->cell_width), term->cell_height);
|
||||
|
||||
pixman_image_fill_rectangles(
|
||||
|
|
@ -2022,8 +2022,8 @@ render_csd_border(struct terminal *term, enum csd_surface surf_idx,
|
|||
*/
|
||||
|
||||
float scale = term->scale;
|
||||
int bwidth = round(term->conf->csd.border_width * scale);
|
||||
int vwidth = round(term->conf->csd.border_width_visible * scale); /* Visible size */
|
||||
int bwidth = (int)roundf(term->conf->csd.border_width * scale);
|
||||
int vwidth = (int)roundf(term->conf->csd.border_width_visible * scale); /* Visible size */
|
||||
|
||||
xassert(bwidth >= vwidth);
|
||||
|
||||
|
|
@ -2396,7 +2396,10 @@ render_csd(struct terminal *term)
|
|||
widths[i] = width;
|
||||
heights[i] = height;
|
||||
|
||||
wl_subsurface_set_position(sub, x / term->scale, y / term->scale);
|
||||
wl_subsurface_set_position(
|
||||
sub,
|
||||
(int32_t)roundf(x / term->scale),
|
||||
(int32_t)roundf(y / term->scale));
|
||||
}
|
||||
|
||||
struct buffer *bufs[CSD_SURF_COUNT];
|
||||
|
|
@ -2487,7 +2490,7 @@ render_scrollback_position(struct terminal *term)
|
|||
char lineno_str[64];
|
||||
snprintf(lineno_str, sizeof(lineno_str), "%d", rebased_view + 1);
|
||||
mbstoc32(_text, lineno_str, ALEN(_text));
|
||||
cell_count = ceil(log10(term->grid->num_rows));
|
||||
cell_count = (int)ceilf(log10f(term->grid->num_rows));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2497,13 +2500,16 @@ render_scrollback_position(struct terminal *term)
|
|||
break;
|
||||
}
|
||||
|
||||
const int scale = term->scale;
|
||||
const int margin = 3 * scale;
|
||||
const int iscale = (int)ceilf(term->scale);
|
||||
const int margin = (int)roundf(3. * term->scale);
|
||||
|
||||
const int width =
|
||||
(2 * margin + cell_count * term->cell_width + scale - 1) / scale * scale;
|
||||
const int height =
|
||||
(2 * margin + term->cell_height + scale - 1) / scale * scale;
|
||||
int width = margin + cell_count * term->cell_width + margin;
|
||||
int height = margin + term->cell_height + margin;
|
||||
|
||||
if (!term_fractional_scaling(term)) {
|
||||
width = (width + iscale - 1) / iscale * iscale;
|
||||
height = (height + iscale - 1) / iscale * iscale;
|
||||
}
|
||||
|
||||
/* *Where* to render - parent relative coordinates */
|
||||
int surf_top = 0;
|
||||
|
|
@ -2531,8 +2537,13 @@ render_scrollback_position(struct terminal *term)
|
|||
}
|
||||
}
|
||||
|
||||
const int x = (term->width - margin - width) / scale * scale;
|
||||
const int y = (term->margins.top + surf_top) / scale * scale;
|
||||
int x = term->width - margin - width;
|
||||
int y = term->margins.top + surf_top;
|
||||
|
||||
if (!term_fractional_scaling(term)) {
|
||||
x = (x + iscale - 1) / iscale * iscale;
|
||||
y = (y + iscale - 1) / iscale * iscale;
|
||||
}
|
||||
|
||||
if (y + height > term->height) {
|
||||
wl_surface_attach(win->scrollback_indicator.surface.surf, NULL, 0, 0);
|
||||
|
|
@ -2544,7 +2555,9 @@ render_scrollback_position(struct terminal *term)
|
|||
struct buffer *buf = shm_get_buffer(chain, width, height);
|
||||
|
||||
wl_subsurface_set_position(
|
||||
win->scrollback_indicator.sub, x / scale, y / scale);
|
||||
win->scrollback_indicator.sub,
|
||||
(int32_t)roundf(x / term->scale),
|
||||
(int32_t)roundf(y / term->scale));
|
||||
|
||||
uint32_t fg = term->colors.table[0];
|
||||
uint32_t bg = term->colors.table[8 + 4];
|
||||
|
|
@ -2573,21 +2586,25 @@ render_render_timer(struct terminal *term, struct timespec render_time)
|
|||
char32_t text[256];
|
||||
mbstoc32(text, usecs_str, ALEN(text));
|
||||
|
||||
const int scale = round(term->scale);
|
||||
const int iscale = (int)ceilf(term->scale);
|
||||
const int cell_count = c32len(text);
|
||||
const int margin = 3 * scale;
|
||||
const int width =
|
||||
(2 * margin + cell_count * term->cell_width + scale - 1) / scale * scale;
|
||||
const int height =
|
||||
(2 * margin + term->cell_height + scale - 1) / scale * scale;
|
||||
const int margin = (int)roundf(3. * term->scale);
|
||||
|
||||
int width = margin + cell_count * term->cell_width + margin;
|
||||
int height = margin + term->cell_height + margin;
|
||||
|
||||
if (!term_fractional_scaling(term)) {
|
||||
width = (width + iscale - 1) / iscale * iscale;
|
||||
height = (height + iscale - 1) / iscale * iscale;
|
||||
}
|
||||
|
||||
struct buffer_chain *chain = term->render.chains.render_timer;
|
||||
struct buffer *buf = shm_get_buffer(chain, width, height);
|
||||
|
||||
wl_subsurface_set_position(
|
||||
win->render_timer.sub,
|
||||
margin / term->scale,
|
||||
(term->margins.top + term->cell_height - margin) / term->scale);
|
||||
(int32_t)roundf(margin / term->scale),
|
||||
(int32_t)roundf((term->margins.top + term->cell_height - margin) / term->scale));
|
||||
|
||||
render_osd(
|
||||
term,
|
||||
|
|
@ -3132,19 +3149,24 @@ render_search_box(struct terminal *term)
|
|||
const size_t total_cells = c32swidth(text, text_len);
|
||||
const size_t wanted_visible_cells = max(20, total_cells);
|
||||
|
||||
xassert(term->scale >= 1);
|
||||
const int rounded_scale = round(term->scale);
|
||||
|
||||
const size_t margin = 3 * rounded_scale;
|
||||
xassert(term->scale >= 1.);
|
||||
const size_t margin = (size_t)roundf(3 * term->scale);
|
||||
|
||||
const size_t width = term->width - 2 * margin;
|
||||
const size_t visible_width = min(
|
||||
size_t visible_width = min(
|
||||
term->width - 2 * margin,
|
||||
(2 * margin + wanted_visible_cells * term->cell_width + rounded_scale - 1) / rounded_scale * rounded_scale);
|
||||
const size_t height = min(
|
||||
term->height - 2 * margin,
|
||||
(2 * margin + 1 * term->cell_height + rounded_scale - 1) / rounded_scale * rounded_scale);
|
||||
margin + wanted_visible_cells * term->cell_width + margin);
|
||||
|
||||
size_t height = min(
|
||||
term->height - 2 * margin,
|
||||
margin + 1 * term->cell_height + margin);
|
||||
|
||||
if (!term_fractional_scaling(term)) {
|
||||
const int iscale = (int)ceilf(term->scale);
|
||||
visible_width = (visible_width + iscale - 1) / iscale * iscale;
|
||||
height = (height + iscale - 1) / iscale * iscale;
|
||||
}
|
||||
|
||||
const size_t visible_cells = (visible_width - 2 * margin) / term->cell_width;
|
||||
size_t glyph_offset = term->render.search_glyph_offset;
|
||||
|
||||
|
|
@ -3390,8 +3412,8 @@ render_search_box(struct terminal *term)
|
|||
/* TODO: this is only necessary on a window resize */
|
||||
wl_subsurface_set_position(
|
||||
term->window->search.sub,
|
||||
margin / term->scale,
|
||||
max(0, (int32_t)term->height - height - margin) / term->scale);
|
||||
(int32_t)roundf(margin / term->scale),
|
||||
(int32_t)roundf(max(0, (int32_t)term->height - height - margin) / term->scale));
|
||||
|
||||
wayl_surface_scale(term->window, &term->window->search.surface, buf, term->scale);
|
||||
wl_surface_attach(term->window->search.surface.surf, buf->wl_buf, 0, 0);
|
||||
|
|
@ -3420,9 +3442,8 @@ render_urls(struct terminal *term)
|
|||
struct wl_window *win = term->window;
|
||||
xassert(tll_length(win->urls) > 0);
|
||||
|
||||
const int scale = round(term->scale);
|
||||
const int x_margin = 2 * scale;
|
||||
const int y_margin = 1 * scale;
|
||||
const int x_margin = (int)roundf(2 * term->scale);
|
||||
const int y_margin = (int)roundf(1 * term->scale);
|
||||
|
||||
/* Calculate view start, counted from the *current* scrollback start */
|
||||
const int scrollback_end
|
||||
|
|
@ -3592,10 +3613,14 @@ render_urls(struct terminal *term)
|
|||
if (cols == 0)
|
||||
continue;
|
||||
|
||||
const int width =
|
||||
(2 * x_margin + cols * term->cell_width + scale - 1) / scale * scale;
|
||||
const int height =
|
||||
(2 * y_margin + term->cell_height + scale - 1) / scale * scale;
|
||||
int width = x_margin + cols * term->cell_width + x_margin;
|
||||
int height = y_margin + term->cell_height + y_margin;
|
||||
|
||||
if (!term_fractional_scaling(term)) {
|
||||
const int iscale = (int)ceilf(term->scale);
|
||||
width = (width + iscale - 1) / iscale * iscale;
|
||||
height = (height + iscale - 1) / iscale * iscale;
|
||||
}
|
||||
|
||||
info[render_count].url = &it->item;
|
||||
info[render_count].text = xc32dup(label);
|
||||
|
|
@ -3631,8 +3656,8 @@ render_urls(struct terminal *term)
|
|||
|
||||
wl_subsurface_set_position(
|
||||
sub_surf->sub,
|
||||
(term->margins.left + x) / term->scale,
|
||||
(term->margins.top + y) / term->scale);
|
||||
(int32_t)roundf((term->margins.left + x) / term->scale),
|
||||
(int32_t)roundf((term->margins.top + y) / term->scale));
|
||||
|
||||
render_osd(
|
||||
term, sub_surf, term->fonts[0], bufs[i], label,
|
||||
|
|
@ -3909,8 +3934,8 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
|
|||
* Ensure we can scale to logical size, and back to
|
||||
* pixels without truncating.
|
||||
*/
|
||||
if (wayl_fractional_scaling(term->wl)) {
|
||||
xassert((int)round(scale) == (int)scale);
|
||||
if (!term_fractional_scaling(term)) {
|
||||
xassert((int)ceilf(scale) == (int)scale);
|
||||
|
||||
int iscale = scale;
|
||||
if (width % iscale)
|
||||
|
|
|
|||
28
terminal.c
28
terminal.c
|
|
@ -784,8 +784,8 @@ term_set_fonts(struct terminal *term, struct fcft_font *fonts[static 4],
|
|||
/* Use force, since cell-width/height may have changed */
|
||||
render_resize_force(
|
||||
term,
|
||||
round(term->width / term->scale),
|
||||
round(term->height / term->scale));
|
||||
(int)roundf(term->width / term->scale),
|
||||
(int)roundf(term->height / term->scale));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -825,7 +825,7 @@ get_font_dpi(const struct terminal *term)
|
|||
? tll_back(win->on_outputs)
|
||||
: &tll_front(term->wl->monitors);
|
||||
|
||||
if (wayl_fractional_scaling(term->wl))
|
||||
if (term_fractional_scaling(term))
|
||||
return mon->dpi.physical;
|
||||
else
|
||||
return mon->dpi.scaled;
|
||||
|
|
@ -880,12 +880,12 @@ int
|
|||
term_pt_or_px_as_pixels(const struct terminal *term,
|
||||
const struct pt_or_px *pt_or_px)
|
||||
{
|
||||
double scale = !term->font_is_sized_by_dpi ? term->scale : 1.;
|
||||
double dpi = term->font_is_sized_by_dpi ? term->font_dpi : 96.;
|
||||
float scale = !term->font_is_sized_by_dpi ? term->scale : 1.;
|
||||
float dpi = term->font_is_sized_by_dpi ? term->font_dpi : 96.;
|
||||
|
||||
return pt_or_px->px == 0
|
||||
? round(pt_or_px->pt * scale * dpi / 72)
|
||||
: pt_or_px->px * scale;
|
||||
? (int)roundf(pt_or_px->pt * scale * dpi / 72)
|
||||
: (int)roundf(pt_or_px->px * scale);
|
||||
}
|
||||
|
||||
struct font_load_data {
|
||||
|
|
@ -932,7 +932,7 @@ reload_fonts(struct terminal *term, bool resize_grid)
|
|||
|
||||
if (use_px_size)
|
||||
snprintf(size, sizeof(size), ":pixelsize=%d",
|
||||
(int)round(term->font_sizes[i][j].px_size * scale));
|
||||
(int)roundf(term->font_sizes[i][j].px_size * scale));
|
||||
else
|
||||
snprintf(size, sizeof(size), ":size=%.2f",
|
||||
term->font_sizes[i][j].pt_size * scale);
|
||||
|
|
@ -2077,6 +2077,16 @@ term_font_size_reset(struct terminal *term)
|
|||
return load_fonts_from_conf(term);
|
||||
}
|
||||
|
||||
bool
|
||||
term_fractional_scaling(const struct terminal *term)
|
||||
{
|
||||
#if defined(HAVE_FRACTIONAL_SCALE)
|
||||
return term->wl->fractional_scale_manager != NULL && term->window->scale > 0.;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
term_update_scale(struct terminal *term)
|
||||
{
|
||||
|
|
@ -2093,7 +2103,7 @@ term_update_scale(struct terminal *term)
|
|||
* - if there aren’t any outputs available, use 1.0
|
||||
*/
|
||||
const float new_scale =
|
||||
(wayl_fractional_scaling(term->wl) && win->scale > 0.
|
||||
(term_fractional_scaling(term)
|
||||
? win->scale
|
||||
: (tll_length(win->on_outputs) > 0
|
||||
? tll_back(win->on_outputs)->scale
|
||||
|
|
|
|||
|
|
@ -736,6 +736,7 @@ bool term_to_slave(struct terminal *term, const void *data, size_t len);
|
|||
bool term_paste_data_to_slave(
|
||||
struct terminal *term, const void *data, size_t len);
|
||||
|
||||
bool term_fractional_scaling(const struct terminal *term);
|
||||
bool term_update_scale(struct terminal *term);
|
||||
bool term_font_size_increase(struct terminal *term);
|
||||
bool term_font_size_decrease(struct terminal *term);
|
||||
|
|
|
|||
30
wayland.c
30
wayland.c
|
|
@ -57,7 +57,7 @@ csd_reload_font(struct wl_window *win, float old_scale)
|
|||
|
||||
char pixelsize[32];
|
||||
snprintf(pixelsize, sizeof(pixelsize), "pixelsize=%u",
|
||||
(int)round(conf->csd.title_height * scale * 1 / 2));
|
||||
(int)roundf(conf->csd.title_height * scale * 1 / 2));
|
||||
|
||||
LOG_DBG("loading CSD font \"%s:%s\" (old-scale=%.2f, scale=%.2f)",
|
||||
patterns[0], pixelsize, old_scale, scale);
|
||||
|
|
@ -416,7 +416,7 @@ update_term_for_output_change(struct terminal *term)
|
|||
* buffer dimensions may not have been updated (in which case
|
||||
* render_size() normally shortcuts and returns early).
|
||||
*/
|
||||
render_resize_force(term, round(logical_width), round(logical_height));
|
||||
render_resize_force(term, (int)roundf(logical_width), (int)roundf(logical_height));
|
||||
}
|
||||
|
||||
else if (scale_updated) {
|
||||
|
|
@ -425,7 +425,7 @@ update_term_for_output_change(struct terminal *term)
|
|||
* been updated, even though the window logical dimensions
|
||||
* haven’t changed.
|
||||
*/
|
||||
render_resize(term, round(logical_width), round(logical_height));
|
||||
render_resize(term, (int)roundf(logical_width), (int)roundf(logical_height));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1528,7 +1528,7 @@ wayl_init(struct fdm *fdm, struct key_binding_manager *key_binding_manager,
|
|||
LOG_INFO(
|
||||
"%s: %dx%d+%dx%d@%dHz %s %.2f\" scale=%d, DPI=%.2f/%.2f (physical/scaled)",
|
||||
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.x, it->item.y, (int)roundf(it->item.refresh),
|
||||
it->item.model != NULL ? it->item.model : it->item.description,
|
||||
it->item.inch, it->item.scale,
|
||||
it->item.dpi.physical, it->item.dpi.scaled);
|
||||
|
|
@ -1996,24 +1996,12 @@ wayl_roundtrip(struct wayland *wayl)
|
|||
wayl_flush(wayl);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
wayl_fractional_scaling(const struct wayland *wayl)
|
||||
{
|
||||
#if defined(HAVE_FRACTIONAL_SCALE)
|
||||
return wayl->fractional_scale_manager != NULL;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
wayl_surface_scale_explicit_width_height(
|
||||
const struct wl_window *win, const struct wayl_surface *surf,
|
||||
int width, int height, float scale)
|
||||
{
|
||||
|
||||
if (wayl_fractional_scaling(win->term->wl) && win->scale > 0.) {
|
||||
if (term_fractional_scaling(win->term)) {
|
||||
#if defined(HAVE_FRACTIONAL_SCALE)
|
||||
LOG_DBG("scaling by a factor of %.2f using fractional scaling "
|
||||
"(width=%d, height=%d) ", scale, width, height);
|
||||
|
|
@ -2021,8 +2009,8 @@ wayl_surface_scale_explicit_width_height(
|
|||
wl_surface_set_buffer_scale(surf->surf, 1);
|
||||
wp_viewport_set_destination(
|
||||
surf->viewport,
|
||||
round((float)width / scale),
|
||||
round((float)height / scale));
|
||||
(int32_t)roundf((float)width / scale),
|
||||
(int32_t)roundf((float)height / scale));
|
||||
#else
|
||||
BUG("wayl_fraction_scaling() returned true, "
|
||||
"but fractional scaling was not available at compile time");
|
||||
|
|
@ -2031,9 +2019,9 @@ wayl_surface_scale_explicit_width_height(
|
|||
LOG_DBG("scaling by a factor of %.2f using legacy mode "
|
||||
"(width=%d, height=%d)", scale, width, height);
|
||||
|
||||
xassert(scale == floor(scale));
|
||||
xassert(scale == floorf(scale));
|
||||
|
||||
const int iscale = (int)scale;
|
||||
const int iscale = (int)floorf(scale);
|
||||
xassert(width % iscale == 0);
|
||||
xassert(height % iscale == 0);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue