From b409205dd88ab147770b1b06d2b02b655a3dc9e1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 21 Dec 2024 17:12:36 +0530 Subject: [PATCH] More box chars --- kitty/decorations.c | 73 +++++++++++++++++++++++++++++++++++--- kitty/fonts/box_drawing.py | 6 ++-- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/kitty/decorations.c b/kitty/decorations.c index d45e4c912..476117346 100644 --- a/kitty/decorations.c +++ b/kitty/decorations.c @@ -447,8 +447,8 @@ typedef struct StraightLine { static StraightLine -line_from_points(int x1, int y1, int x2, int y2) { - StraightLine ans = {.m = (y2 - y1) / ((double)(x2 - x1))}; +line_from_points(double x1, double y1, double x2, double y2) { + StraightLine ans = {.m = (y2 - y1) / (x2 - x1)}; ans.c = y1 - ans.m * x1; return ans; } @@ -977,6 +977,19 @@ quads(Canvas *self, ...) { va_end(args); } +static void +smooth_mosaic(Canvas *self, bool lower, double ax, double ay, double bx, double by) { + StraightLine l = line_from_points( + ax * minus(self->width, 1), ay * minus(self->height, 1), bx * minus(self->width, 1), by * minus(self->height, 1)); + for (uint y = 0; y < self->height; y++) { + uint offset = y * self->width; + for (uint x = 0; x < self->width; x++) { + double edge = line_y(l, x); + if ((lower && y >= edge) || (!lower && y <= edge)) self->mask[offset + x] = 255; + } + } +} + 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; @@ -1155,12 +1168,64 @@ render_box_char(char_type ch, uint8_t *buf, unsigned width, unsigned height, dou C(L'▜', quads, TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT, 0); C(L'▞', quads, TOP_RIGHT, BOTTOM_LEFT, 0); C(L'▟', quads, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, 0); + + S(L'🬼', smooth_mosaic, true, 0, 2. / 3, 0.5, 1); + S(L'🬽', smooth_mosaic, true, 0, 2. / 3, 1, 1); + S(L'🬾', smooth_mosaic, true, 0, 1. / 3, 0.5, 1); + S(L'🬿', smooth_mosaic, true, 0, 1. / 3, 1, 1); + S(L'🭀', smooth_mosaic, true, 0, 0, 0.5, 1); + + S(L'🭁', smooth_mosaic, true, 0, 1. / 3, 0.5, 0); + S(L'🭂', smooth_mosaic, true, 0, 1. / 3, 1, 0); + S(L'🭃', smooth_mosaic, true, 0, 2. / 3, 0.5, 0); + S(L'🭄', smooth_mosaic, true, 0, 2. / 3, 1, 0); + S(L'🭅', smooth_mosaic, true, 0, 1, 0.5, 0); + S(L'🭆', smooth_mosaic, true, 0, 2. / 3, 1, 1. / 3); + + S(L'🭇', smooth_mosaic, true, 0.5, 1, 1, 2. / 3); + S(L'🭈', smooth_mosaic, true, 0, 1, 1, 2. / 3); + S(L'🭉', smooth_mosaic, true, 0.5, 1, 1, 1. / 3); + S(L'🭊', smooth_mosaic, true, 0, 1, 1, 1. / 3); + S(L'🭋', smooth_mosaic, true, 0.5, 1, 1, 0); + + S(L'🭌', smooth_mosaic, true, 0.5, 0, 1, 1. / 3); + S(L'🭍', smooth_mosaic, true, 0, 0, 1, 1. / 3); + S(L'🭎', smooth_mosaic, true, 0.5, 0, 1, 2. / 3); + S(L'🭏', smooth_mosaic, true, 0, 0, 1, 2. / 3); + S(L'🭐', smooth_mosaic, true, 0.5, 0, 1, 1); + S(L'🭑', smooth_mosaic, true, 0, 1. / 3, 1, 2. / 3); + + S(L'🭒', smooth_mosaic, false, 0, 2. / 3, 0.5, 1); + S(L'🭓', smooth_mosaic, false, 0, 2. / 3, 1, 1); + S(L'🭔', smooth_mosaic, false, 0, 1. / 3, 0.5, 1); + S(L'🭕', smooth_mosaic, false, 0, 1. / 3, 1, 1); + S(L'🭖', smooth_mosaic, false, 0, 0, 0.5, 1); + + S(L'🭗', smooth_mosaic, false, 0, 1. / 3, 0.5, 0); + S(L'🭘', smooth_mosaic, false, 0, 1. / 3, 1, 0); + S(L'🭙', smooth_mosaic, false, 0, 2. / 3, 0.5, 0); + S(L'🭚', smooth_mosaic, false, 0, 2. / 3, 1, 0); + S(L'🭛', smooth_mosaic, false, 0, 1, 0.5, 0); + + S(L'🭜', smooth_mosaic, false, 0, 2. / 3, 1, 1. / 3); + S(L'🭝', smooth_mosaic, false, 0.5, 1, 1, 2. / 3); + S(L'🭞', smooth_mosaic, false, 0, 1, 1, 2. / 3); + S(L'🭟', smooth_mosaic, false, 0.5, 1, 1, 1. / 3); + S(L'🭠', smooth_mosaic, false, 0, 1, 1, 1. / 3); + S(L'🭡', smooth_mosaic, false, 0.5, 1, 1, 0); + + S(L'🭢', smooth_mosaic, false, 0.5, 0, 1, 1. / 3); + S(L'🭣', smooth_mosaic, false, 0, 0, 1, 1. / 3); + S(L'🭤', smooth_mosaic, false, 0.5, 0, 1, 2. / 3); + S(L'🭥', smooth_mosaic, false, 0, 0, 1, 2. / 3); + S(L'🭦', smooth_mosaic, false, 0.5, 0, 1, 1); + S(L'🭧', smooth_mosaic, false, 0, 1. / 3, 1, 2. / 3); } + free(canvas.holes); free(canvas.y_limits); + free(ss.holes); free(ss.y_limits); #undef CC #undef SS #undef C #undef S #undef SB - free(canvas.holes); free(canvas.y_limits); - free(ss.holes); free(ss.y_limits); } diff --git a/kitty/fonts/box_drawing.py b/kitty/fonts/box_drawing.py index 6020929f6..f35f5c02b 100644 --- a/kitty/fonts/box_drawing.py +++ b/kitty/fonts/box_drawing.py @@ -206,7 +206,7 @@ def fill_region(buf: BufType, width: int, height: int, xlimits: Iterable[Iterabl buf[x + offset] = full if upper <= y <= lower else empty -def line_equation(x1: int, y1: int, x2: int, y2: int) -> Callable[[int], float]: +def line_equation(x1: int | float, y1: int | float, x2: int | float, y2: int | float) -> Callable[[int], float]: m = (y2 - y1) / (x2 - x1) c = y1 - m * x1 @@ -936,8 +936,8 @@ def smooth_mosaic( buf: SSByteArray, width: int, height: int, level: int = 1, lower: bool = True, a: tuple[float, float] = (0, 0), b: tuple[float, float] = (0, 0) ) -> None: - ax, ay = int(a[0] * (width - 1)), int(a[1] * (height - 1)) - bx, by = int(b[0] * (width - 1)), int(b[1] * (height - 1)) + ax, ay = (a[0] * (width - 1)), (a[1] * (height - 1)) + bx, by = (b[0] * (width - 1)), (b[1] * (height - 1)) line = line_equation(ax, ay, bx, by) def lower_condition(x: int, y: int) -> bool: