mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-11-13 12:09:35 +03:00
Clean up font features merge
This commit is contained in:
parent
db85e07d41
commit
14560b008a
@ -4,6 +4,13 @@ Changelog
|
||||
|kitty| is a feature full, cross-platform, *fast*, GPU based terminal emulator.
|
||||
To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
|
||||
0.15.12 [future]
|
||||
--------------------
|
||||
|
||||
- Allow choosing OpenType features for individual fonts via the
|
||||
:opt:`font_features` option.
|
||||
|
||||
|
||||
0.15.1 [2019-12-21]
|
||||
--------------------
|
||||
|
||||
|
@ -411,16 +411,13 @@ def handle_symbol_map(key, val, ans):
|
||||
|
||||
|
||||
@special_handler
|
||||
def handle_font_feature_settings(key, val, ans):
|
||||
parts = val.split(':', maxsplit=2)
|
||||
if len(parts) != 2:
|
||||
if parts[0] == "none":
|
||||
return
|
||||
def handle_font_features(key, val, ans):
|
||||
if val != 'none':
|
||||
parts = val.split()
|
||||
if len(parts) < 2:
|
||||
log_error("Ignoring invalid font_features {}".format(val))
|
||||
else:
|
||||
log_error("Ignoring invalid font_feature_settings for font {}".format(parts[0]))
|
||||
else:
|
||||
font, features = parts
|
||||
ans['font_feature_settings'].update({font.strip(): features.strip().split()})
|
||||
ans['font_features'][parts[0]] = parts[1:]
|
||||
|
||||
|
||||
@special_handler
|
||||
@ -508,7 +505,7 @@ def option_names_for_completion():
|
||||
|
||||
|
||||
def parse_config(lines, check_keys=True, accumulate_bad_lines=None):
|
||||
ans = {'symbol_map': {}, 'keymap': {}, 'sequence_map': {}, 'key_definitions': [], 'env': {}, 'kitten_aliases': {}, 'font_feature_settings': {}}
|
||||
ans = {'symbol_map': {}, 'keymap': {}, 'sequence_map': {}, 'key_definitions': [], 'env': {}, 'kitten_aliases': {}, 'font_features': {}}
|
||||
parse_config_base(
|
||||
lines,
|
||||
defaults,
|
||||
|
@ -277,23 +277,21 @@ or by defining shortcuts for it in kitty.conf, for example::
|
||||
map alt+2 disable_ligatures_in all never
|
||||
map alt+3 disable_ligatures_in tab cursor
|
||||
|
||||
Note: This function is equivalent to setting :code:`font_feature_settings` to
|
||||
:code:`-liga -dlig -calt`.
|
||||
'''))
|
||||
|
||||
o('font_feature_settings', 'none', long_text=_('''
|
||||
o('font_features', 'none', long_text=_('''
|
||||
Choose exactly which OpenType features to enable or disable. This is useful as
|
||||
some fonts might have many features worthwhile in a terminal—for example, Fira
|
||||
some fonts might have features worthwhile in a terminal. For example, Fira
|
||||
Code Retina includes a discretionary feature, :code:`zero`, which in that font
|
||||
changes the appearance of the zero (0), to make it more easily distinguishable
|
||||
from Ø. Fira Code Retina also includes other discretionary features known as
|
||||
Stylistic Sets which have the tags :code:`ss01` through :code:`ss20`.
|
||||
|
||||
Note that this code is indexed by PostScript name, and not TTF name or font
|
||||
family; this allows you to define very precise feature settings; e.g. you can
|
||||
Note that this code is indexed by PostScript name, and not the font
|
||||
family. This allows you to define very precise feature settings; e.g. you can
|
||||
disable a feature in the italic font but not in the regular font.
|
||||
|
||||
To get the PostScript name for a font, ask Fontconfig for it, using your family
|
||||
To get the PostScript name for a font, ask Fontconfig for it, using the family
|
||||
name::
|
||||
|
||||
$ fc-match "Fira Code" postscriptname
|
||||
@ -305,16 +303,16 @@ name::
|
||||
|
||||
Enable alternate zero and oldstyle numerals::
|
||||
|
||||
font_feature_settings FiraCode-Retina: +zero +onum
|
||||
font_features FiraCode-Retina +zero +onum
|
||||
|
||||
Enable only alternate zero::
|
||||
|
||||
font_feature_settings FiraCode-Retina: +zero
|
||||
font_features FiraCode-Retina +zero
|
||||
|
||||
Disable the normal ligatures, but keep the :code:`calt` feature which (in this
|
||||
font) breaks up monotony::
|
||||
|
||||
font_feature_settings TT2020StyleB-Regular: -liga +calt
|
||||
font_features TT2020StyleB-Regular -liga +calt
|
||||
'''))
|
||||
|
||||
|
||||
|
@ -76,9 +76,7 @@ typedef struct {
|
||||
PyObject *face;
|
||||
// Map glyphs to sprite map co-ords
|
||||
SpritePosition sprite_map[1024];
|
||||
hb_feature_t hb_features[8];
|
||||
hb_feature_t* ffs_hb_features;
|
||||
size_t num_hb_features;
|
||||
size_t num_ffs_hb_features;
|
||||
SpecialGlyphCache special_glyph_cache[SPECIAL_GLYPH_CACHE_SIZE];
|
||||
bool bold, italic, emoji_presentation;
|
||||
@ -349,45 +347,47 @@ desc_to_face(PyObject *desc, FONTS_DATA_HANDLE fg) {
|
||||
return ans;
|
||||
}
|
||||
|
||||
static inline void
|
||||
copy_hb_feature(Font *f, HBFeature which) {
|
||||
memcpy(f->hb_features + f->num_hb_features++, hb_features + which, sizeof(hb_features[0]));
|
||||
}
|
||||
|
||||
static inline bool
|
||||
init_font(Font *f, PyObject *face, bool bold, bool italic, bool emoji_presentation) {
|
||||
f->face = face; Py_INCREF(f->face);
|
||||
f->bold = bold; f->italic = italic; f->emoji_presentation = emoji_presentation;
|
||||
f->num_hb_features = 0;
|
||||
f->num_ffs_hb_features = 0;
|
||||
const char *psname = postscript_name_for_face(face);
|
||||
copy_hb_feature(f, LIGA_FEATURE);
|
||||
copy_hb_feature(f, DLIG_FEATURE);
|
||||
copy_hb_feature(f, CALT_FEATURE);
|
||||
if (font_feature_settings != NULL){
|
||||
PyObject* o = PyDict_GetItemString(font_feature_settings, psname);
|
||||
if (o != NULL) {
|
||||
long len = PyList_Size(o);
|
||||
if (len==0) return true;
|
||||
f->num_ffs_hb_features = len + f->num_hb_features;
|
||||
hb_feature_t* hb_feat = calloc(f->num_ffs_hb_features, sizeof(hb_feature_t));
|
||||
for (long i = len-1; i >= 0; i--) {
|
||||
PyObject* item = PyList_GetItem(o, i);
|
||||
const char* feat = PyUnicode_AsUTF8(item);
|
||||
hb_feature_from_string(feat, -1, &hb_feat[i]);
|
||||
Py_ssize_t len = PySequence_Size(o);
|
||||
if (len > 0) {
|
||||
f->num_ffs_hb_features = len + 1;
|
||||
f->ffs_hb_features = calloc(f->num_ffs_hb_features, sizeof(hb_feature_t));
|
||||
if (!f->ffs_hb_features) return false;
|
||||
for (Py_ssize_t i = 0; i < len; i++) {
|
||||
PyObject* item = PySequence_GetItem(o, i);
|
||||
if (!PyUnicode_Check(item)) fatal("A font feature is not a unicode string");
|
||||
if (!hb_feature_from_string(PyUnicode_AsUTF8(item), -1, &f->ffs_hb_features[i])) {
|
||||
fatal("Invalid font feature: %s", PyUnicode_AsUTF8(item));
|
||||
}
|
||||
}
|
||||
memcpy(f->ffs_hb_features + len, &hb_features[CALT_FEATURE], sizeof(hb_feature_t));
|
||||
}
|
||||
for (size_t i = 0; i < f->num_hb_features; i++)
|
||||
hb_feat[len+i] = hb_features[i];
|
||||
f->ffs_hb_features = hb_feat;
|
||||
}
|
||||
}
|
||||
if (!f->num_ffs_hb_features) {
|
||||
f->ffs_hb_features = calloc(4, sizeof(hb_feature_t));
|
||||
if (!f->ffs_hb_features) return false;
|
||||
if (strstr(psname, "NimbusMonoPS-") == psname) {
|
||||
memcpy(f->ffs_hb_features + f->num_ffs_hb_features++, &hb_features[LIGA_FEATURE], sizeof(hb_feature_t));
|
||||
memcpy(f->ffs_hb_features + f->num_ffs_hb_features++, &hb_features[DLIG_FEATURE], sizeof(hb_feature_t));
|
||||
}
|
||||
memcpy(f->ffs_hb_features + f->num_ffs_hb_features++, &hb_features[CALT_FEATURE], sizeof(hb_feature_t));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void
|
||||
del_font(Font *f) {
|
||||
Py_CLEAR(f->face);
|
||||
if (f->num_ffs_hb_features > 0)
|
||||
free(f->ffs_hb_features);
|
||||
free(f->ffs_hb_features); f->ffs_hb_features = NULL;
|
||||
free_maps(f);
|
||||
f->bold = false; f->italic = false;
|
||||
}
|
||||
@ -795,10 +795,9 @@ shape(CPUCell *first_cpu_cell, GPUCell *first_gpu_cell, index_type num_cells, hb
|
||||
group_state.last_gpu_cell = first_gpu_cell + (num_cells ? num_cells - 1 : 0);
|
||||
load_hb_buffer(first_cpu_cell, first_gpu_cell, num_cells);
|
||||
|
||||
if (fobj->num_ffs_hb_features > 0)
|
||||
hb_shape(font, harfbuzz_buffer, fobj->ffs_hb_features, fobj->num_ffs_hb_features - (disable_ligature ? 0 : fobj->num_hb_features));
|
||||
else
|
||||
hb_shape(font, harfbuzz_buffer, fobj->hb_features, fobj->num_hb_features - (disable_ligature ? 0 : fobj->num_hb_features));
|
||||
size_t num_features = fobj->num_ffs_hb_features;
|
||||
if (num_features && !disable_ligature) num_features--; // the last feature is always -calt
|
||||
hb_shape(font, harfbuzz_buffer, fobj->ffs_hb_features, num_features);
|
||||
|
||||
unsigned int info_length, positions_length;
|
||||
group_state.info = hb_buffer_get_glyph_infos(harfbuzz_buffer, &info_length);
|
||||
@ -1049,8 +1048,6 @@ test_shape(PyObject UNUSED *self, PyObject *args) {
|
||||
if (face == NULL) return NULL;
|
||||
font = calloc(1, sizeof(Font));
|
||||
font->face = face;
|
||||
font->hb_features[0] = hb_features[CALT_FEATURE];
|
||||
font->num_hb_features = 1;
|
||||
} else {
|
||||
FontGroup *fg = font_groups;
|
||||
font = fg->fonts + fg->medium_font_idx;
|
||||
|
@ -103,7 +103,7 @@ def set_font_family(opts=None, override_font_size=None, debug_font_matching=Fals
|
||||
set_font_data(
|
||||
render_box_drawing, prerender_function, descriptor_for_idx,
|
||||
indices['bold'], indices['italic'], indices['bi'], num_symbol_fonts,
|
||||
sm, sz, opts['font_feature_settings']
|
||||
sm, sz, opts.font_features
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user