diff --git a/kitty/cell_vertex.glsl b/kitty/cell_vertex.glsl index 0d7dd699b..198623a4a 100644 --- a/kitty/cell_vertex.glsl +++ b/kitty/cell_vertex.glsl @@ -79,8 +79,8 @@ const uint COLOR_MASK = uint(0x4000); const uint ZERO = uint(0); const uint ONE = uint(1); const uint TWO = uint(2); -const uint SIX = uint(6); -const uint SEVEN = uint(7); +const uint STRIKE_SPRITE_INDEX = uint({STRIKE_SPRITE_INDEX}); +const uint DECORATION_MASK = uint({DECORATION_MASK}); vec3 color_to_vec(uint c) { uint r, g, b; @@ -193,8 +193,8 @@ void main() { foreground = choose_color(float(is_selected & ONE), selection_color, foreground); decoration_fg = choose_color(float(is_selected & ONE), selection_color, decoration_fg); // Underline and strike through (rendered via sprites) - underline_pos = choose_color(in_url, to_sprite_pos(pos, url_style, ZERO, ZERO), to_sprite_pos(pos, (text_attrs >> DECORATION_SHIFT) & SEVEN, ZERO, ZERO)); - strike_pos = to_sprite_pos(pos, ((text_attrs >> STRIKE_SHIFT) & ONE) * SIX, ZERO, ZERO); + underline_pos = choose_color(in_url, to_sprite_pos(pos, url_style, ZERO, ZERO), to_sprite_pos(pos, (text_attrs >> DECORATION_SHIFT) & DECORATION_MASK, ZERO, ZERO)); + strike_pos = to_sprite_pos(pos, ((text_attrs >> STRIKE_SHIFT) & ONE) * STRIKE_SPRITE_INDEX, ZERO, ZERO); // Cursor cursor_color_vec = vec4(color_to_vec(cursor_bg), 1.0); diff --git a/kitty/data-types.c b/kitty/data-types.c index 303b63201..f2426a119 100644 --- a/kitty/data-types.c +++ b/kitty/data-types.c @@ -302,6 +302,8 @@ PyInit_fast_data_types(void) { s(STRIKETHROUGH, strike); s(DIM, dim); s(DECORATION, decoration); #undef s PyModule_AddIntConstant(m, "MARK_MASK", MARK_MASK); + PyModule_AddIntConstant(m, "DECORATION_MASK", DECORATION_MASK); + PyModule_AddIntConstant(m, "NUM_UNDERLINE_STYLES", NUM_UNDERLINE_STYLES); PyModule_AddStringMacro(m, ERROR_PREFIX); #ifdef KITTY_VCS_REV PyModule_AddStringMacro(m, KITTY_VCS_REV); diff --git a/kitty/data-types.h b/kitty/data-types.h index b04cb75c2..787452ff8 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -154,6 +154,8 @@ typedef union CellAttrs { } CellAttrs; #define MARK_MASK (3u) #define WIDTH_MASK (3u) +#define DECORATION_MASK (7u) +#define NUM_UNDERLINE_STYLES (5u) #define SGR_MASK (~(((CellAttrs){.width=WIDTH_MASK, .mark=MARK_MASK}).val)) typedef struct { diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index c1bc21069..804b139b6 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -256,6 +256,8 @@ GRAPHICS_PREMULT_PROGRAM: int GRAPHICS_PROGRAM: int MARK: int MARK_MASK: int +DECORATION_MASK: int +NUM_UNDERLINE_STYLES: int OSC: int FILE_TRANSFER_CODE: int REVERSE: int diff --git a/kitty/fonts.c b/kitty/fonts.c index 49c903fe7..b692af854 100644 --- a/kitty/fonts.c +++ b/kitty/fonts.c @@ -13,7 +13,7 @@ #include "charsets.h" #include "glyph-cache.h" -#define MISSING_GLYPH 4 +#define MISSING_GLYPH (NUM_UNDERLINE_STYLES + 2) #define MAX_NUM_EXTRA_GLYPHS_PUA 4u typedef void (*send_sprite_to_gpu_func)(FONTS_DATA_HANDLE fg, unsigned int, unsigned int, unsigned int, pixel*); diff --git a/kitty/fonts/render.py b/kitty/fonts/render.py index e617897a2..f5b2c9fe2 100644 --- a/kitty/fonts/render.py +++ b/kitty/fonts/render.py @@ -14,7 +14,7 @@ from kitty.constants import is_macos from kitty.fast_data_types import ( Screen, create_test_font_group, get_fallback_font, set_font_data, set_options, set_send_sprite_to_gpu, sprite_map_set_limits, - test_render_line, test_shape + test_render_line, test_shape, NUM_UNDERLINE_STYLES ) from kitty.fonts.box_drawing import ( BufType, distribute_dots, render_box_char, render_missing_glyph @@ -400,8 +400,12 @@ def prerender_function( render_cursor, cursor_beam_thickness=cursor_beam_thickness, cursor_underline_thickness=cursor_underline_thickness, cell_width=cell_width, cell_height=cell_height, dpi_x=dpi_x, dpi_y=dpi_y) - cells = f(1), f(2), f(3), f(4), f(5), f(0, strikethrough=True), f(missing=True), c(1), c(2), c(3) - return tuple(map(ctypes.addressof, cells)), cells + cells = list(map(f, range(1, NUM_UNDERLINE_STYLES + 1))) + cells.append(f(0, strikethrough=True)) + cells.append(f(missing=True)) + cells.extend((c(1), c(2), c(3))) + tcells = tuple(cells) + return tuple(map(ctypes.addressof, tcells)), tcells def render_box_drawing(codepoint: int, cell_width: int, cell_height: int, dpi: float) -> Tuple[int, CBufType]: diff --git a/kitty/window.py b/kitty/window.py index a60dfaf51..ca9a123b6 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -23,17 +23,17 @@ from .constants import appname, is_macos, wakeup from .fast_data_types import ( BGIMAGE_PROGRAM, BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_FG_PROGRAM, CELL_PROGRAM, CELL_SPECIAL_PROGRAM, CURSOR_BEAM, CURSOR_BLOCK, - CURSOR_UNDERLINE, DCS, DECORATION, DIM, GLFW_MOD_CONTROL, + CURSOR_UNDERLINE, DCS, DECORATION, DECORATION_MASK, DIM, GLFW_MOD_CONTROL, GRAPHICS_ALPHA_MASK_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_PROGRAM, - MARK, MARK_MASK, NO_CURSOR_SHAPE, OSC, REVERSE, SCROLL_FULL, SCROLL_LINE, - SCROLL_PAGE, STRIKETHROUGH, TINT_PROGRAM, Color, KeyEvent, Screen, - add_timer, add_window, cell_size_for_window, click_mouse_cmd_output, - click_mouse_url, compile_program, current_os_window, encode_key_for_tty, - get_boss, get_click_interval, get_clipboard_string, get_options, - init_cell_program, mark_os_window_dirty, mouse_selection, - move_cursor_to_mouse_if_in_prompt, pt_to_px, set_clipboard_string, - set_titlebar_color, set_window_logo, set_window_padding, - set_window_render_data, update_ime_position_for_window, + MARK, MARK_MASK, NO_CURSOR_SHAPE, NUM_UNDERLINE_STYLES, OSC, REVERSE, + SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, STRIKETHROUGH, TINT_PROGRAM, Color, + KeyEvent, Screen, add_timer, add_window, cell_size_for_window, + click_mouse_cmd_output, click_mouse_url, compile_program, + current_os_window, encode_key_for_tty, get_boss, get_click_interval, + get_clipboard_string, get_options, init_cell_program, mark_os_window_dirty, + mouse_selection, move_cursor_to_mouse_if_in_prompt, pt_to_px, + set_clipboard_string, set_titlebar_color, set_window_logo, + set_window_padding, set_window_render_data, update_ime_position_for_window, update_window_title, update_window_visibility ) from .keys import keyboard_mode_name, mod_mask @@ -228,6 +228,8 @@ class LoadShaderPrograms: 'DECORATION_SHIFT': DECORATION, 'MARK_SHIFT': MARK, 'MARK_MASK': MARK_MASK, + 'DECORATION_MASK': DECORATION_MASK, + 'STRIKE_SPRITE_INDEX': NUM_UNDERLINE_STYLES + 1, }.items(): vv = vv.replace(f'{{{gln}}}', str(pyn), 1) if semi_transparent: