From 77e25ae50c83d333165e0e1209063f868df3648c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 25 Dec 2024 09:28:53 +0530 Subject: [PATCH] Scale multicell box char line thickness --- kitty/decorations.c | 7 ++++--- kitty/decorations.h | 2 +- kitty/fast_data_types.pyi | 2 +- kitty/fonts.c | 10 +++++----- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/kitty/decorations.c b/kitty/decorations.c index 7e09474d436..e49d872fe4f 100644 --- a/kitty/decorations.c +++ b/kitty/decorations.c @@ -229,6 +229,7 @@ typedef struct Canvas { uint8_t *mask; uint width, height, supersample_factor; struct { double x, y; } dpi; + double scale; // used to scale line thickness with font size for multicell rendering Range *holes; uint holes_count, holes_capacity; Limit *y_limits; uint y_limits_count, y_limits_capacity; } Canvas; @@ -255,7 +256,7 @@ thickness(Canvas *self, uint level, bool horizontal) { level = min(level, arraysz(OPT(box_drawing_scale))); double pts = OPT(box_drawing_scale)[level]; double dpi = horizontal ? self->dpi.x : self->dpi.y; - return self->supersample_factor * (uint)ceil(pts * dpi / 72.0); + return (uint)ceil(self->supersample_factor * self->scale * pts * dpi / 72.0); } static uint @@ -1338,8 +1339,8 @@ sextant(Canvas *self, uint which) { } void -render_box_char(char_type ch, uint8_t *buf, unsigned width, unsigned height, double dpi_x, double dpi_y) { - Canvas canvas = {.mask=buf, .width = width, .height = height, .dpi={.x=dpi_x, .y=dpi_y}, .supersample_factor=1u}, ss = canvas; +render_box_char(char_type ch, uint8_t *buf, unsigned width, unsigned height, double dpi_x, double dpi_y, double scale) { + Canvas canvas = {.mask=buf, .width = width, .height = height, .dpi={.x=dpi_x, .y=dpi_y}, .supersample_factor=1u, .scale=scale}, ss = canvas; ss.mask = buf + width*height; ss.supersample_factor = SUPERSAMPLE_FACTOR; ss.width *= SUPERSAMPLE_FACTOR; ss.height *= SUPERSAMPLE_FACTOR; fill_canvas(&canvas, 0); Canvas *c = &canvas; diff --git a/kitty/decorations.h b/kitty/decorations.h index 8d47281f707..89055db3874 100644 --- a/kitty/decorations.h +++ b/kitty/decorations.h @@ -23,5 +23,5 @@ DecorationGeometry add_missing_glyph(uint8_t *buf, FontCellMetrics fcm); DecorationGeometry add_beam_cursor(uint8_t *buf, FontCellMetrics fcm, double dpi_x); DecorationGeometry add_underline_cursor(uint8_t *buf, FontCellMetrics fcm, double dpi_y); DecorationGeometry add_hollow_cursor(uint8_t *buf, FontCellMetrics fcm, double dpi_x, double dpi_y); -void render_box_char(char_type ch, uint8_t *buf, unsigned width, unsigned height, double dpi_x, double dpi_y); +void render_box_char(char_type ch, uint8_t *buf, unsigned width, unsigned height, double dpi_x, double dpi_y, double scale); #define SUPERSAMPLE_FACTOR 4u diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index 770bab10755..5d582e06f2f 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -1717,7 +1717,7 @@ def glfw_get_system_color_theme(query_if_unintialized: bool = True) -> Literal[' def set_redirect_keys_to_overlay(os_window_id: int, tab_id: int, window_id: int, overlay_window_id: int) -> None: ... def buffer_keys_in_window(os_window_id: int, tab_id: int, window_id: int, enabled: bool = True) -> bool: ... def sprite_idx_to_pos(idx: int, xnum: int, ynum: int) -> tuple[int, int, int]: ... -def render_box_char(ch: int, width: int, height: int, dpi_x: float = 96.0, dpi_y: float = 96.0) -> bytes: ... +def render_box_char(ch: int, width: int, height: int, scale: float = 1.0, dpi_x: float = 96.0, dpi_y: float = 96.0) -> bytes: ... class MousePosition(TypedDict): cell_x: int diff --git a/kitty/fonts.c b/kitty/fonts.c index 6effc0c9bd0..ca4adf21d2a 100644 --- a/kitty/fonts.c +++ b/kitty/fonts.c @@ -1041,7 +1041,7 @@ render_box_cell(FontGroup *fg, RunFont rf, CPUCell *cpu_cell, GPUCell *gpu_cell, uint8_t *alpha_mask = NULL; ensure_canvas_can_fit(fg, num_glyphs + 1, rf.scale); if (num_glyphs == 1) { - render_box_char(ch, fg->canvas.alpha_mask, width, height, fg->logical_dpi_x, fg->logical_dpi_y); + render_box_char(ch, fg->canvas.alpha_mask, width, height, fg->logical_dpi_x, fg->logical_dpi_y, scale); alpha_mask = fg->canvas.alpha_mask; } else { alpha_mask = ((uint8_t*)fg->canvas.buf) + fg->canvas.size_in_bytes - (num_glyphs * width * height); @@ -1049,7 +1049,7 @@ render_box_cell(FontGroup *fg, RunFont rf, CPUCell *cpu_cell, GPUCell *gpu_cell, for (unsigned i = 0; i < num_glyphs; i++) { unsigned int ch = global_glyph_render_scratch.lc->chars[cnum++]; while (!ch) ch = global_glyph_render_scratch.lc->chars[cnum++]; - render_box_char(ch, fg->canvas.alpha_mask, width, height, fg->logical_dpi_x, fg->logical_dpi_y); + render_box_char(ch, fg->canvas.alpha_mask, width, height, fg->logical_dpi_x, fg->logical_dpi_y, scale); uint8_t *src = fg->canvas.alpha_mask; for (unsigned y = 0; y < height; y++) { uint8_t *dest_row = alpha_mask + y*num_glyphs*width + i*width; @@ -2303,11 +2303,11 @@ sprite_idx_to_pos(PyObject *self UNUSED, PyObject *args) { static PyObject* pyrender_box_char(PyObject *self UNUSED, PyObject *args) { unsigned int ch; - unsigned long width, height; double dpi_x = 96., dpi_y = 96.; - if (!PyArg_ParseTuple(args, "Ikk|dd", &ch, &width, &height, &dpi_x, &dpi_y)) return NULL; + unsigned long width, height; double dpi_x = 96., dpi_y = 96., scale = 1.; + if (!PyArg_ParseTuple(args, "Ikk|ddd", &ch, &width, &height, &scale, &dpi_x, &dpi_y)) return NULL; RAII_PyObject(ans, PyBytes_FromStringAndSize(NULL, width*16 * height*16)); if (!ans) return NULL; - render_box_char(ch, (uint8_t*)PyBytes_AS_STRING(ans), width, height, dpi_x, dpi_y); + render_box_char(ch, (uint8_t*)PyBytes_AS_STRING(ans), width, height, dpi_x, dpi_y, scale); if (_PyBytes_Resize(&ans, width * height) != 0) return NULL; return Py_NewRef(ans); }