diff --git a/kitty/boss.py b/kitty/boss.py index ea335a0ea..ab8935912 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -135,13 +135,16 @@ class Boss: if new_size == self.current_font_size: return self.current_font_size = new_size + w, h = cell_size.width, cell_size.height + windows = tuple(filter(None, self.window_id_map.values())) cell_size.width, cell_size.height = set_font_family( self.opts, override_font_size=self.current_font_size) layout_sprite_map(cell_size.width, cell_size.height, render_cell_wrapper) + for window in windows: + window.screen.rescale_images(w, h) self.resize_windows_after_font_size_change() - for window in self.window_id_map.values(): - if window is not None: - window.screen.refresh_sprite_positions() + for window in windows: + window.screen.refresh_sprite_positions() self.tab_manager.refresh_sprite_positions() def resize_windows_after_font_size_change(self): diff --git a/kitty/graphics.c b/kitty/graphics.c index bbbb2c233..bb97fc427 100644 --- a/kitty/graphics.c +++ b/kitty/graphics.c @@ -554,6 +554,24 @@ update_src_rect(ImageRef *ref, Image *img) { ref->src_rect.bottom = (float)(ref->src_y + ref->src_height) / (float)img->height; } +static inline void +update_dest_rect(ImageRef *ref, uint32_t num_cols, uint32_t num_rows) { + uint32_t t; + if (num_cols == 0) { + t = ref->src_width + ref->cell_x_offset; + num_cols = t / global_state.cell_width; + if (t > num_cols * global_state.cell_width) num_cols += 1; + } + if (num_rows == 0) { + t = ref->src_height + ref->cell_y_offset; + num_rows = t / global_state.cell_height; + if (t > num_rows * global_state.cell_height) num_rows += 1; + } + ref->effective_num_rows = num_rows; + ref->effective_num_cols = num_cols; +} + + static void handle_put_command(GraphicsManager *self, const GraphicsCommand *g, Cursor *c, bool *is_dirty, Image *img) { has_add_respose = false; @@ -581,22 +599,9 @@ handle_put_command(GraphicsManager *self, const GraphicsCommand *g, Cursor *c, b ref->cell_y_offset = MIN(g->cell_y_offset, global_state.cell_height - 1); ref->num_cols = g->num_cells; ref->num_rows = g->num_lines; update_src_rect(ref, img); - + update_dest_rect(ref, g->num_cells, g->num_lines); // Move the cursor, the screen will take care of ensuring it is in bounds - uint32_t num_cols = g->num_cells, num_rows = g->num_lines, t; - if (num_cols == 0) { - t = ref->src_width + ref->cell_x_offset; - num_cols = t / global_state.cell_width; - if (t > num_cols * global_state.cell_width) num_cols += 1; - } - if (num_rows == 0) { - t = ref->src_height + ref->cell_y_offset; - num_rows = t / global_state.cell_height; - if (t > num_rows * global_state.cell_height) num_rows += 1; - } - c->x += num_cols; c->y += num_rows - 1; - ref->effective_num_rows = num_rows; - ref->effective_num_cols = num_cols; + c->x += ref->effective_num_cols; c->y += ref->effective_num_rows - 1; } static int @@ -819,6 +824,21 @@ grman_resize(GraphicsManager *self, index_type UNUSED old_lines, index_type UNUS self->layers_dirty = true; } +void +grman_rescale(GraphicsManager *self, unsigned int UNUSED old_cell_width, unsigned int UNUSED old_cell_height) { + ImageRef *ref; Image *img; + self->layers_dirty = true; + for (size_t i = self->image_count; i-- > 0;) { + img = self->images + i; + for (size_t j = img->refcnt; j-- > 0;) { + ref = img->refs + j; + ref->cell_x_offset = MIN(ref->cell_x_offset, global_state.cell_width - 1); + ref->cell_y_offset = MIN(ref->cell_y_offset, global_state.cell_height - 1); + update_dest_rect(ref, ref->num_cols, ref->num_rows); + } + } +} + const char* grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_t *payload, Cursor *c, bool *is_dirty) { Image *image; diff --git a/kitty/graphics.h b/kitty/graphics.h index 45a3d7fe4..f7f11da2e 100644 --- a/kitty/graphics.h +++ b/kitty/graphics.h @@ -89,3 +89,4 @@ const char* grman_handle_command(GraphicsManager *self, const GraphicsCommand *g bool grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float screen_left, float screen_top, float dx, float dy, unsigned int num_cols, unsigned int num_rows); void grman_scroll_images(GraphicsManager *self, const ScrollData*); void grman_resize(GraphicsManager*, index_type, index_type, index_type, index_type); +void grman_rescale(GraphicsManager *self, unsigned int old_cell_width, unsigned int old_cell_height); diff --git a/kitty/screen.c b/kitty/screen.c index 8d661ea44..13a2da093 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -181,6 +181,11 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) { return true; } +static void +screen_rescale_images(Screen *self, unsigned int old_cell_width, unsigned int old_cell_height) { + grman_rescale(self->main_grman, old_cell_width, old_cell_height); + grman_rescale(self->alt_grman, old_cell_width, old_cell_height); +} static void screen_refresh_sprite_positions(Screen *self) { @@ -1346,6 +1351,7 @@ WRAP0(linefeed) WRAP0(carriage_return) WRAP2(resize, 1, 1) WRAP2(set_margins, 1, 1) +WRAP2(rescale_images, 1, 1) static PyObject* change_scrollback_size(Screen *self, PyObject *args) { @@ -1557,6 +1563,7 @@ static PyMethodDef methods[] = { MND(mark_as_dirty, METH_NOARGS) MND(resize, METH_VARARGS) MND(set_margins, METH_VARARGS) + MND(rescale_images, METH_VARARGS) MND(text_for_selection, METH_NOARGS) MND(scroll, METH_VARARGS) MND(toggle_alt_screen, METH_NOARGS)