Render known country flags designated by a pair of unicode codepoints in two cells instead of four.
This commit is contained in:
parent
9bc2ab3245
commit
24197dc422
@ -16,6 +16,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
|||||||
|
|
||||||
- Update to Unicode 13.0 (:iss:`2513`)
|
- Update to Unicode 13.0 (:iss:`2513`)
|
||||||
|
|
||||||
|
- Render known country flags designated by a pair of unicode codepoints
|
||||||
|
in two cells instead of four.
|
||||||
|
|
||||||
|
|
||||||
0.17.2 [2020-03-29]
|
0.17.2 [2020-03-29]
|
||||||
--------------------
|
--------------------
|
||||||
|
|||||||
@ -51,7 +51,8 @@ all_symbols: Set[int] = set()
|
|||||||
name_map: Dict[int, str] = {}
|
name_map: Dict[int, str] = {}
|
||||||
word_search_map: DefaultDict[str, Set[int]] = defaultdict(set)
|
word_search_map: DefaultDict[str, Set[int]] = defaultdict(set)
|
||||||
zwj = 0x200d
|
zwj = 0x200d
|
||||||
marks = set(emoji_skin_tone_modifiers) | {zwj}
|
flag_codepoints = frozenset(range(0x1F1E6, 0x1F1E6 + 26))
|
||||||
|
marks = set(emoji_skin_tone_modifiers) | {zwj} | flag_codepoints
|
||||||
not_assigned = set(range(0, sys.maxunicode))
|
not_assigned = set(range(0, sys.maxunicode))
|
||||||
|
|
||||||
|
|
||||||
@ -278,7 +279,7 @@ def gen_emoji() -> None:
|
|||||||
p(comma, '{', ', '.join(map(str, arr)), '}')
|
p(comma, '{', ', '.join(map(str, arr)), '}')
|
||||||
p('};')
|
p('};')
|
||||||
p('if (a < 0x1F1E6 || b < 0x1F1E6 || a >= 0x1F1E6 + 26 || b >= 0x1F1E6 + 26) return false;')
|
p('if (a < 0x1F1E6 || b < 0x1F1E6 || a >= 0x1F1E6 + 26 || b >= 0x1F1E6 + 26) return false;')
|
||||||
p('return flag_combinations[a][b];')
|
p('return flag_combinations[a - 0x1F1E6][b - 0x1F1E6];')
|
||||||
p('};')
|
p('};')
|
||||||
|
|
||||||
|
|
||||||
@ -486,7 +487,7 @@ def gen_names() -> None:
|
|||||||
def gen_wcwidth() -> None:
|
def gen_wcwidth() -> None:
|
||||||
seen: Set[int] = set()
|
seen: Set[int] = set()
|
||||||
|
|
||||||
def add(p: Callable, comment: str, chars_: Set[int], ret: int) -> None:
|
def add(p: Callable, comment: str, chars_: Union[Set[int], FrozenSet[int]], ret: int) -> None:
|
||||||
chars = chars_ - seen
|
chars = chars_ - seen
|
||||||
seen.update(chars)
|
seen.update(chars)
|
||||||
p(f'\t\t// {comment} ({len(chars)} codepoints)' + ' {{' '{')
|
p(f'\t\t// {comment} ({len(chars)} codepoints)' + ' {{' '{')
|
||||||
@ -500,6 +501,7 @@ def gen_wcwidth() -> None:
|
|||||||
p('\tswitch(code) {')
|
p('\tswitch(code) {')
|
||||||
|
|
||||||
non_printing = class_maps['Cc'] | class_maps['Cf'] | class_maps['Cs']
|
non_printing = class_maps['Cc'] | class_maps['Cf'] | class_maps['Cs']
|
||||||
|
add(p, 'Flags', flag_codepoints, 2)
|
||||||
add(p, 'Marks', marks | {0}, 0)
|
add(p, 'Marks', marks | {0}, 0)
|
||||||
add(p, 'Non-printing characters', non_printing, -1)
|
add(p, 'Non-printing characters', non_printing, -1)
|
||||||
add(p, 'Private use', class_maps['Co'], -3)
|
add(p, 'Private use', class_maps['Co'], -3)
|
||||||
|
|||||||
2
kitty/emoji.h
generated
2
kitty/emoji.h
generated
@ -811,7 +811,7 @@ static const unsigned char flag_combinations[26][26] = {
|
|||||||
, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }
|
, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
if (a < 0x1F1E6 || b < 0x1F1E6 || a >= 0x1F1E6 + 26 || b >= 0x1F1E6 + 26) return false;
|
if (a < 0x1F1E6 || b < 0x1F1E6 || a >= 0x1F1E6 + 26 || b >= 0x1F1E6 + 26) return false;
|
||||||
return flag_combinations[a][b];
|
return flag_combinations[a - 0x1F1E6][b - 0x1F1E6];
|
||||||
};
|
};
|
||||||
|
|
||||||
END_ALLOW_CASE_RANGE
|
END_ALLOW_CASE_RANGE
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
#include "fonts.h"
|
#include "fonts.h"
|
||||||
#include "lineops.h"
|
#include "lineops.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
#include "emoji.h"
|
||||||
#include <structmember.h>
|
#include <structmember.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -357,6 +358,27 @@ selection_has_screen_line(Selection *s, int y) {
|
|||||||
return top <= y && y <= bottom;
|
return top <= y && y <= bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
draw_second_flag_codepoint(Screen *self, char_type ch) {
|
||||||
|
index_type xpos = 0, ypos = 0;
|
||||||
|
if (self->cursor->x > 1) {
|
||||||
|
ypos = self->cursor->y;
|
||||||
|
xpos = self->cursor->x - 2;
|
||||||
|
} else if (self->cursor->y > 0 && self->columns > 1) {
|
||||||
|
ypos = self->cursor->y - 1;
|
||||||
|
xpos = self->columns - 2;
|
||||||
|
} else return false;
|
||||||
|
|
||||||
|
linebuf_init_line(self->linebuf, ypos);
|
||||||
|
CPUCell *cell = self->linebuf->line->cpu_cells + xpos;
|
||||||
|
if (!is_flag_pair(cell->ch, ch) || cell->cc_idx[0]) return false;
|
||||||
|
line_add_combining_char(self->linebuf->line, ch, xpos);
|
||||||
|
self->is_dirty = true;
|
||||||
|
if (selection_has_screen_line(&self->selection, ypos)) self->selection = EMPTY_SELECTION;
|
||||||
|
linebuf_mark_line_dirty(self->linebuf, ypos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
draw_combining_char(Screen *self, char_type ch) {
|
draw_combining_char(Screen *self, char_type ch) {
|
||||||
bool has_prev_char = false;
|
bool has_prev_char = false;
|
||||||
@ -372,6 +394,17 @@ draw_combining_char(Screen *self, char_type ch) {
|
|||||||
xpos = self->columns - 1;
|
xpos = self->columns - 1;
|
||||||
has_prev_char = true;
|
has_prev_char = true;
|
||||||
}
|
}
|
||||||
|
if (self->cursor->x > 0) {
|
||||||
|
ypos = self->cursor->y;
|
||||||
|
linebuf_init_line(self->linebuf, ypos);
|
||||||
|
xpos = self->cursor->x - 1;
|
||||||
|
has_prev_char = true;
|
||||||
|
} else if (self->cursor->y > 0) {
|
||||||
|
ypos = self->cursor->y - 1;
|
||||||
|
linebuf_init_line(self->linebuf, ypos);
|
||||||
|
xpos = self->columns - 1;
|
||||||
|
has_prev_char = true;
|
||||||
|
}
|
||||||
if (has_prev_char) {
|
if (has_prev_char) {
|
||||||
line_add_combining_char(self->linebuf->line, ch, xpos);
|
line_add_combining_char(self->linebuf->line, ch, xpos);
|
||||||
self->is_dirty = true;
|
self->is_dirty = true;
|
||||||
@ -412,6 +445,10 @@ screen_draw(Screen *self, uint32_t och) {
|
|||||||
draw_combining_char(self, ch);
|
draw_combining_char(self, ch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
bool is_flag = is_flag_codepoint(ch);
|
||||||
|
if (UNLIKELY(is_flag)) {
|
||||||
|
if (draw_second_flag_codepoint(self, ch)) return;
|
||||||
|
}
|
||||||
int char_width = wcwidth_std(ch);
|
int char_width = wcwidth_std(ch);
|
||||||
if (UNLIKELY(char_width < 1)) {
|
if (UNLIKELY(char_width < 1)) {
|
||||||
if (char_width == 0) return;
|
if (char_width == 0) return;
|
||||||
|
|||||||
7
kitty/unicode-data.c
generated
7
kitty/unicode-data.c
generated
File diff suppressed because one or more lines are too long
9
kitty/wcwidth-std.h
generated
9
kitty/wcwidth-std.h
generated
@ -8,6 +8,11 @@ START_ALLOW_CASE_RANGE
|
|||||||
static int
|
static int
|
||||||
wcwidth_std(int32_t code) {
|
wcwidth_std(int32_t code) {
|
||||||
switch(code) {
|
switch(code) {
|
||||||
|
// Flags (26 codepoints) {{{
|
||||||
|
case 0x1f1e6 ... 0x1f1ff:
|
||||||
|
return 2;
|
||||||
|
// }}}
|
||||||
|
|
||||||
// Marks (2302 codepoints) {{{
|
// Marks (2302 codepoints) {{{
|
||||||
case 0x0:
|
case 0x0:
|
||||||
return 0;
|
return 0;
|
||||||
@ -1494,9 +1499,7 @@ wcwidth_std(int32_t code) {
|
|||||||
return 2;
|
return 2;
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// Emoji Presentation (26 codepoints) {{{
|
// Emoji Presentation (0 codepoints) {{{
|
||||||
case 0x1f1e6 ... 0x1f1ff:
|
|
||||||
return 2;
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// Not assigned in the unicode character database (765365 codepoints) {{{
|
// Not assigned in the unicode character database (765365 codepoints) {{{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user