mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
osc: wip: kitty text size protocol
This brings initial support for the new kitty text-sizing
protocol. Note hat only the width-parameter ('w') is supported. That
is, no font scaling, and no multi-line cells.
For now, only explicit widths are supported. That is, w=0 does not yet
work.
There are a couple of changes to the renderer, to handle e.g.
OSC 66 ; w=6 ; foobar ST
There are two ways this can get rendered, depending on whether
grapheme shaping has been enabled. We either shape it, and get an
array of glyphs back that we render. Or, we rasterize each codepoint
ourselves, and render each resulting glyph.
The two cases ends up in two different renderer loops, that worked
somewhat different. In particular, the first case has probably never
been tested/used at all...
With this patch, both are changed, and now uses some heuristic to
differentiate between multi-cell text strings (like in the example
above), or single-cell combining characters. The difference is mainly
in which offset to use for the secondary glyphs.
In a multi-cell string, each glyph is mapped to its own cell, while in
the combining case, we try to map all glyphs to the same cell.
This commit is contained in:
parent
1111f7e918
commit
7a8d2b5e01
2 changed files with 104 additions and 14 deletions
81
osc.c
81
osc.c
|
|
@ -610,7 +610,6 @@ verify_kitty_id_is_valid(const char *id)
|
|||
}
|
||||
UNIGNORE_WARNINGS
|
||||
|
||||
|
||||
static void
|
||||
kitty_notification(struct terminal *term, char *string)
|
||||
{
|
||||
|
|
@ -1135,6 +1134,82 @@ out:
|
|||
free(sound_name);
|
||||
}
|
||||
|
||||
static void
|
||||
kitty_text_size(struct terminal *term, char *string)
|
||||
{
|
||||
char *text = strchr(string, ';');
|
||||
if (text == NULL)
|
||||
return;
|
||||
|
||||
char *parameters = string;
|
||||
*text = '\0';
|
||||
text++;
|
||||
|
||||
char32_t *wchars = ambstoc32(text);
|
||||
if (wchars == NULL)
|
||||
return;
|
||||
|
||||
int width = 0;
|
||||
|
||||
char *ctx = NULL;
|
||||
for (char *param = strtok_r(parameters, ":", &ctx);
|
||||
param != NULL;
|
||||
param = strtok_r(NULL, ":", &ctx))
|
||||
{
|
||||
/* All parameters are on the form X=value, where X is always
|
||||
exactly one character */
|
||||
if (param[0] == '\0' || param[1] != '=')
|
||||
continue;
|
||||
|
||||
char *value = ¶m[2];
|
||||
|
||||
switch (param[0]) {
|
||||
case 'w': {
|
||||
errno = 0;
|
||||
char *end = NULL;
|
||||
unsigned long w = strtoul(value, &end, 10);
|
||||
|
||||
if (*end == '\0' && errno == 0 && w <= 7) {
|
||||
width = (int)w;
|
||||
break;
|
||||
} else
|
||||
LOG_ERR("OSC-66: invalid 'w' value, ignoring");
|
||||
break;
|
||||
}
|
||||
|
||||
case 's':
|
||||
case 'n':
|
||||
case 'd':
|
||||
case 'v':
|
||||
LOG_WARN("OSC-66: unsupported: '%c' parameter, ignoring", param[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t len = c32len(wchars);
|
||||
uint32_t key = composed_key_from_chars(wchars, len);
|
||||
|
||||
const struct composed *composed = composed_lookup_without_collision(
|
||||
term->composed, &key, wchars, len - 1, wchars[len - 1], width);
|
||||
|
||||
if (composed == NULL) {
|
||||
struct composed *new_cc = xmalloc(sizeof(*new_cc));
|
||||
new_cc->chars = wchars;
|
||||
new_cc->count = len;
|
||||
new_cc->key = key;
|
||||
new_cc->width = width;
|
||||
new_cc->forced_width = width;
|
||||
|
||||
term->composed_count++;
|
||||
composed_insert(&term->composed, new_cc);
|
||||
composed = new_cc;
|
||||
} else if (composed->width == width) {
|
||||
free(wchars);
|
||||
}
|
||||
|
||||
term_print(term, CELL_COMB_CHARS_LO + composed->key, composed->forced_width > 0 ? composed->forced_width : composed->width);
|
||||
}
|
||||
|
||||
void
|
||||
osc_dispatch(struct terminal *term)
|
||||
{
|
||||
|
|
@ -1371,6 +1446,10 @@ osc_dispatch(struct terminal *term)
|
|||
osc_selection(term, string);
|
||||
break;
|
||||
|
||||
case 66: /* text-size protocol (kitty) */
|
||||
kitty_text_size(term, string);
|
||||
break;
|
||||
|
||||
case 99: /* Kitty notifications */
|
||||
kitty_notification(term, string);
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue