From bbcb7dc24c43f1428443d96e909b925423b2f2e2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 19 Dec 2024 05:51:23 +0530 Subject: [PATCH] Fix cursor rendering when on first cell of multicell --- kitty/cell_vertex.glsl | 24 +++++++++++------------- kitty/line.h | 1 - kitty/shaders.c | 37 ++++++++++++++++++++++++++----------- kitty_tests/multicell.py | 2 +- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/kitty/cell_vertex.glsl b/kitty/cell_vertex.glsl index d96e7a840..a567119e5 100644 --- a/kitty/cell_vertex.glsl +++ b/kitty/cell_vertex.glsl @@ -9,7 +9,8 @@ layout(std140) uniform CellRenderData { uint default_fg, highlight_fg, highlight_bg, cursor_fg, cursor_bg, url_color, url_style, inverted; uint xnum, ynum, sprites_xnum, sprites_ynum, cursor_fg_sprite_idx, cell_height; - float cursor_x, cursor_y, cursor_w, cursor_opacity; + uint cursor_x1, cursor_x2, cursor_y1, cursor_y2; + float cursor_opacity; // must have unique entries with 0 being default_bg and unset being UINT32_MAX uint bg_colors0, bg_colors1, bg_colors2, bg_colors3, bg_colors4, bg_colors5, bg_colors6, bg_colors7; @@ -81,6 +82,11 @@ float one_if_equal_zero_otherwise(int a, int b) { return 1.0f - clamp(abs(float(a) - float(b)), 0.0f, 1.0f); } +float one_if_equal_zero_otherwise(uint a, uint b) { + return 1.0f - clamp(abs(float(a) - float(b)), 0.0f, 1.0f); +} + + uint resolve_color(uint c, uint defval) { // Convert a cell color to an actual color based on the color table int t = int(c & BYTE_MASK); @@ -144,18 +150,10 @@ vec3 choose_color(float q, vec3 a, vec3 b) { return mix(b, a, q); } -float are_integers_equal(float a, float b) { // return 1 if equal otherwise 0 - float delta = abs(a - b); // delta can be 0, 1 or larger - return step(delta, 0.5); // 0 if 0.5 < delta else 1 -} - -float is_cursor(uint xi, uint y) { - float x = float(xi); - float y_equal = are_integers_equal(float(y), cursor_y); - float x1_equal = are_integers_equal(x, cursor_x); - float x2_equal = are_integers_equal(x, cursor_w); - float x_equal = step(0.5, x1_equal + x2_equal); - return step(2.0, x_equal + y_equal); +float is_cursor(uint x, uint y) { + uint clamped_x = clamp(x, cursor_x1, cursor_x2); + uint clamped_y = clamp(y, cursor_y1, cursor_y2); + return one_if_equal_zero_otherwise(x, clamped_x) * one_if_equal_zero_otherwise(y, clamped_y); } // }}} diff --git a/kitty/line.h b/kitty/line.h index 981324ceb..7ca36f2c6 100644 --- a/kitty/line.h +++ b/kitty/line.h @@ -13,7 +13,6 @@ // TODO: Test handling of calt ligatures with scale see is_group_calt_ligature() // TODO: Handle selection with multicell // TODO: URL detection with multicell -// TODO: Cursor rendering over multicell // TODO: Wrapping of multicell draw commands // TODO: Handle rewrap and restitch of multiline chars // TODO: Handle rewrap when a character is too wide/tall to fit on resized screen diff --git a/kitty/shaders.c b/kitty/shaders.c index db690a13d..40ba8e9eb 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -369,7 +369,9 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c GLuint default_fg, highlight_fg, highlight_bg, cursor_fg, cursor_bg, url_color, url_style, inverted; GLuint xnum, ynum, sprites_xnum, sprites_ynum, cursor_fg_sprite_idx, cell_height; - GLfloat cursor_x, cursor_y, cursor_w, cursor_opacity; + GLuint cursor_x1, cursor_x2, cursor_y1, cursor_y2; + GLfloat cursor_opacity; + GLuint bg_colors0, bg_colors1, bg_colors2, bg_colors3, bg_colors4, bg_colors5, bg_colors6, bg_colors7; GLfloat bg_opacities0, bg_opacities1, bg_opacities2, bg_opacities3, bg_opacities4, bg_opacities5, bg_opacities6, bg_opacities7; }; @@ -402,7 +404,8 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c enum { BLOCK_IDX = 0, BEAM_IDX = 2, UNDERLINE_IDX = 3, UNFOCUSED_IDX = 4 }; Line *line_for_cursor = NULL; if (cursor->opacity > 0) { - rd->cursor_x = cursor->x, rd->cursor_y = cursor->y; + rd->cursor_x1 = cursor->x, rd->cursor_y1 = cursor->y; + rd->cursor_x2 = cursor->x, rd->cursor_y2 = cursor->y; rd->cursor_opacity = cursor->opacity; CursorShape cs = (cursor->is_focused || OPT(cursor_shape_unfocused) == NO_CURSOR_SHAPE) ? cursor->shape : OPT(cursor_shape_unfocused); switch(cs) { @@ -427,6 +430,24 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c } if (line_for_cursor) { colors_for_cell(line_for_cursor, cp, &cell_color_x, &cell_fg, &cell_bg, &reversed); + const CPUCell *cursor_cell; + const bool large_cursor = ((cursor_cell = &line_for_cursor->cpu_cells[cursor->x])->is_multicell) && cursor_cell->x == 0 && cursor_cell->y == 0; + if (large_cursor) { + switch(cs) { + case CURSOR_BEAM: + rd->cursor_y2 += cursor_cell->scale - 1; break; + case CURSOR_UNDERLINE: + rd->cursor_y1 += cursor_cell->scale - 1; + rd->cursor_y2 = rd->cursor_y1; + rd->cursor_x2 += mcd_x_limit(cursor_cell) - 1; + break; + case CURSOR_BLOCK: + rd->cursor_y2 += cursor_cell->scale - 1; + rd->cursor_x2 += mcd_x_limit(cursor_cell) - 1; + break; + case CURSOR_HOLLOW: case NUM_OF_CURSOR_SHAPES: case NO_CURSOR_SHAPE: break; + }; + } } if (IS_SPECIAL_COLOR(cursor_color)) { if (line_for_cursor) pick_cursor_color(line_for_cursor, cp, cell_fg, cell_bg, cell_color_x, &rd->cursor_fg, &rd->cursor_bg, rd->default_fg, rd->bg_colors0); @@ -441,15 +462,9 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c } // store last rendered cursor color for trail rendering screen->last_rendered.cursor_bg = rd->cursor_bg; - } else rd->cursor_x = screen->columns, rd->cursor_y = screen->lines; - rd->cursor_w = rd->cursor_x; - const CPUCell *cursor_cell; - if ( - (rd->cursor_fg_sprite_idx == BLOCK_IDX || rd->cursor_fg_sprite_idx == UNDERLINE_IDX) && - line_for_cursor && (cursor_cell = line_for_cursor->cpu_cells + cursor->x)->is_multicell && - cursor_cell->x == 0 - ) { - rd->cursor_w = mcd_x_limit(cursor_cell); + } else { + rd->cursor_x1 = screen->columns + 1; rd->cursor_x2 = screen->columns; + rd->cursor_y1 = screen->lines + 1; rd->cursor_y2 = screen->lines; } rd->xnum = screen->columns; rd->ynum = screen->lines; diff --git a/kitty_tests/multicell.py b/kitty_tests/multicell.py index b74748f4b..0817a4ef9 100644 --- a/kitty_tests/multicell.py +++ b/kitty_tests/multicell.py @@ -2,7 +2,7 @@ # License: GPLv3 Copyright: 2024, Kovid Goyal -from kitty.fast_data_types import TEXT_SIZE_CODE, wcswidth, test_ch_and_idx +from kitty.fast_data_types import TEXT_SIZE_CODE, test_ch_and_idx, wcswidth from . import BaseTest, parse_bytes from . import draw_multicell as multicell