diff --git a/kitty/cell_vertex.glsl b/kitty/cell_vertex.glsl index 45098c46e..636b2b76d 100644 --- a/kitty/cell_vertex.glsl +++ b/kitty/cell_vertex.glsl @@ -62,6 +62,7 @@ const uint ZERO = uint(0); const uint ONE = uint(1); const uint TWO = uint(2); const uint THREE = uint(3); +const uint FOUR = uint(4); const uint DECORATION_MASK = uint(3); const uint STRIKE_MASK = uint(1); const uint REVERSE_MASK = uint(1); @@ -159,8 +160,8 @@ void main() { // Underline and strike through (rendered via sprites) float in_url = in_range(c, r); decoration_fg = choose_color(in_url, color_to_vec(url_color), to_color(colors[2], resolved_fg)); - underline_pos = choose_color(in_url, to_sprite_pos(pos, TWO, ZERO, ZERO), to_sprite_pos(pos, (text_attrs >> 2) & DECORATION_MASK, ZERO, ZERO)); - strike_pos = to_sprite_pos(pos, ((text_attrs >> 7) & STRIKE_MASK) * THREE, ZERO, ZERO); + underline_pos = choose_color(in_url, to_sprite_pos(pos, THREE, ZERO, ZERO), to_sprite_pos(pos, (text_attrs >> 2) & DECORATION_MASK, ZERO, ZERO)); + strike_pos = to_sprite_pos(pos, ((text_attrs >> 7) & STRIKE_MASK) * FOUR, ZERO, ZERO); // Cursor foreground = choose_color(cursor, bg, foreground); diff --git a/kitty/cursor.c b/kitty/cursor.c index e09dcbf6c..8413b0c7d 100644 --- a/kitty/cursor.c +++ b/kitty/cursor.c @@ -80,9 +80,9 @@ cursor_from_sgr(Cursor *self, unsigned int *params, unsigned int count) { case 3: self->italic = true; break; case 4: - self->decoration = 1; break; - case UNDERCURL_CODE: - self->decoration = 2; break; + if (i < count) { self->decoration = MIN(3, params[i]); i++; } + else self->decoration = 1; + break; case 7: self->reverse = true; break; case 9: @@ -143,7 +143,8 @@ static inline const char* decoration_as_sgr(uint8_t decoration) { switch(decoration) { case 1: return "4"; - case 2: return "6"; // UNDERCURL_CODE + case 2: return "4:2"; + case 3: return "4:3"; default: return "24"; } } diff --git a/kitty/data-types.h b/kitty/data-types.h index 4ce6f8db1..84da9640c 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -58,7 +58,6 @@ typedef enum MouseShapes { BEAM, HAND, ARROW } MouseShape; #define CC_SHIFT 16 #define UTF8_ACCEPT 0 #define UTF8_REJECT 1 -#define UNDERCURL_CODE 6 #define DECORATION_FG_CODE 58 #define CHAR_IS_BLANK(ch) ((ch) == 32 || (ch) == 0) #define CONTINUED_MASK 1 diff --git a/kitty/fonts/render.py b/kitty/fonts/render.py index 2fbce2ba9..095740f64 100644 --- a/kitty/fonts/render.py +++ b/kitty/fonts/render.py @@ -74,12 +74,17 @@ def add_line(buf, cell_width, position, thickness, cell_height): y = position - thickness // 2 while thickness: thickness -= 1 - offset = cell_width * y - for x in range(cell_width): - buf[offset + x] = 255 + ctypes.memset(ctypes.addressof(buf) + (cell_width * y), 255, cell_width) y += 1 +def add_dline(buf, cell_width, position, thickness, cell_height): + bottom = min(position - thickness, cell_height - 1) + top = min(position, cell_height - 1) + for y in {top, bottom}: + ctypes.memset(ctypes.addressof(buf) + (cell_width * y), 255, cell_width) + + def add_curl(buf, cell_width, position, thickness, cell_height): xfactor = 2.0 * pi / cell_width yfactor = thickness @@ -119,12 +124,9 @@ def render_special(underline=0, strikethrough=False, missing=False): if underline: t = underline_thickness - if underline == 2: + if underline > 1: t = max(1, min(cell_height - underline_position - 1, t)) - dl( - add_curl - if underline == 2 else add_line, underline_position, t, cell_height - ) + dl([None, add_line, add_dline, add_curl][underline], underline_position, t, cell_height) if strikethrough: pos = int(0.65 * baseline) dl(add_line, pos, underline_thickness, cell_height) @@ -138,7 +140,7 @@ def render_special(underline=0, strikethrough=False, missing=False): def prerender(): # Pre-render the special blank, underline and strikethrough cells - cells = render_special(1), render_special(2), render_special(0, True), render_special(missing=True) + cells = render_special(1), render_special(2), render_special(3), render_special(0, True), render_special(missing=True) if send_prerendered_sprites(*map(ctypes.addressof, cells)) != len(cells): raise RuntimeError('Your GPU has too small a max texture size') diff --git a/protocol-extensions.asciidoc b/protocol-extensions.asciidoc index eb6930bdf..2e0364e6d 100644 --- a/protocol-extensions.asciidoc +++ b/protocol-extensions.asciidoc @@ -28,11 +28,15 @@ in terminal editors such as vim and emacs to display red, wavy underlines under mis-spelled words and/or syntax errors. This is done by re-purposing some SGR escape codes that are not used in modern terminals (https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes) -To change the underline style from straight line to curl (this used to be the -code for rapid blinking text, only previous use I know of was in MS-DOS ANSI.sys): +To set the underline style: ``` -[6m +[4:0m # this is no underline +[4:1m # this is a straight underline +[4:2m # this is a double underline +[4:3m # this is a curly underline +[4m # this is a straight underline (for backwards compat) +[24m # this is no underline (for backwards compat) ``` To set the underline color (this is reserved and as far as I can tell not actually used for anything):