Skip to content

Commit

Permalink
Scale multicell box char line thickness
Browse files Browse the repository at this point in the history
  • Loading branch information
kovidgoyal committed Dec 25, 2024
1 parent 6a9a7c2 commit 9abee1f
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 10 deletions.
7 changes: 4 additions & 3 deletions kitty/decorations.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion kitty/decorations.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion kitty/fast_data_types.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions kitty/fonts.c
Original file line number Diff line number Diff line change
Expand Up @@ -1041,15 +1041,15 @@ 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);
unsigned cnum = 0;
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;
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit 9abee1f

Please sign in to comment.