mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-10-26 15:13:22 +03:00
Add tests to validate feature-from-spec
This commit is contained in:
parent
060732b428
commit
57edb412e6
@ -953,6 +953,20 @@ static CTFontRef nerd_font(CGFloat sz) {
|
||||
return variation_to_python(src);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
applied_features(CTFace *self, PyObject *a UNUSED) {
|
||||
RAII_PyObject(ans, PyTuple_New(self->font_features.count));
|
||||
if (!ans) return NULL;
|
||||
char buf[256];
|
||||
for (size_t i = 0; i < self->font_features.count; i++) {
|
||||
hb_feature_to_string(&self->font_features.features[i], buf, arraysz(buf));
|
||||
PyObject *t = PyUnicode_FromString(buf);
|
||||
if (!t) return NULL;
|
||||
PyTuple_SET_ITEM(ans, i, t);
|
||||
}
|
||||
Py_INCREF(ans); return ans;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
get_features(CTFace *self, PyObject *a UNUSED) {
|
||||
if (!ensure_name_table(self)) return NULL;
|
||||
@ -1012,6 +1026,7 @@ static CTFontRef nerd_font(CGFloat sz) {
|
||||
METHODB(display_name, METH_NOARGS),
|
||||
METHODB(postscript_name, METH_NOARGS),
|
||||
METHODB(get_variable_data, METH_NOARGS),
|
||||
METHODB(applied_features, METH_NOARGS),
|
||||
METHODB(get_features, METH_NOARGS),
|
||||
METHODB(get_variation, METH_NOARGS),
|
||||
METHODB(identify_for_debug, METH_NOARGS),
|
||||
|
@ -442,6 +442,7 @@ class Face:
|
||||
def render_sample_text(self, text: str, width: int, height: int, fg_color: int = 0xffffff) -> bytes: ...
|
||||
def get_variation(self) -> Optional[Dict[str, float]]: ...
|
||||
def get_features(self) -> Dict[str, Optional[FeatureData]]: ...
|
||||
def applied_features(self) -> Tuple[str, ...]: ...
|
||||
|
||||
|
||||
class CoreTextFont(TypedDict):
|
||||
@ -478,6 +479,7 @@ class CTFace:
|
||||
def render_sample_text(self, text: str, width: int, height: int, fg_color: int = 0xffffff) -> bytes: ...
|
||||
def get_variation(self) -> Optional[Dict[str, float]]: ...
|
||||
def get_features(self) -> Dict[str, Optional[FeatureData]]: ...
|
||||
def applied_features(self) -> Tuple[str, ...]: ...
|
||||
|
||||
|
||||
def coretext_all_fonts(monospaced_only: bool) -> Tuple[CoreTextFont, ...]:
|
||||
|
@ -290,6 +290,17 @@ desc_to_face(PyObject *desc, FONTS_DATA_HANDLE fg) {
|
||||
return ans;
|
||||
}
|
||||
|
||||
static void
|
||||
add_feature(FontFeatures *output, const hb_feature_t *feature) {
|
||||
for (size_t i = 0; i < output->count; i++) {
|
||||
if (output->features[i].tag == feature->tag) {
|
||||
output->features[i] = *feature;
|
||||
return;
|
||||
}
|
||||
}
|
||||
output->features[output->count++] = *feature;
|
||||
}
|
||||
|
||||
bool
|
||||
create_features_for_face(const char *psname, PyObject *features, FontFeatures *output) {
|
||||
size_t count_from_descriptor = features ? PyTuple_GET_SIZE(features): 0;
|
||||
@ -304,16 +315,16 @@ create_features_for_face(const char *psname, PyObject *features, FontFeatures *o
|
||||
output->features = calloc(MAX(2u, count_from_opts + count_from_descriptor), sizeof(output->features[0]));
|
||||
if (!output->features) { PyErr_NoMemory(); return false; }
|
||||
for (size_t i = 0; i < count_from_opts; i++) {
|
||||
output->features[output->count++] = from_opts->features[i];
|
||||
add_feature(output, &from_opts->features[i]);
|
||||
}
|
||||
for (size_t i = 0; i < count_from_descriptor; i++) {
|
||||
ParsedFontFeature *f = (ParsedFontFeature*)PyTuple_GET_ITEM(features, i);
|
||||
output->features[output->count++] = f->feature;
|
||||
add_feature(output, &f->feature);
|
||||
}
|
||||
if (!output->count) {
|
||||
if (strstr(psname, "NimbusMonoPS-") == psname) {
|
||||
output->features[output->count++] = hb_features[LIGA_FEATURE];
|
||||
output->features[output->count++] = hb_features[DLIG_FEATURE];
|
||||
add_feature(output, &hb_features[LIGA_FEATURE]);
|
||||
add_feature(output, &hb_features[DLIG_FEATURE]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -315,8 +315,11 @@ def get_font_from_spec(
|
||||
resolved_medium_font: Optional[Descriptor] = None, match_is_more_specific_than_family: Event = Event()
|
||||
) -> Descriptor:
|
||||
if not spec.is_system:
|
||||
return get_fine_grained_font(spec, bold, italic, resolved_medium_font=resolved_medium_font, family_axis_values=family_axis_values,
|
||||
ans = get_fine_grained_font(spec, bold, italic, resolved_medium_font=resolved_medium_font, family_axis_values=family_axis_values,
|
||||
match_is_more_specific_than_family=match_is_more_specific_than_family)
|
||||
if spec.features:
|
||||
ans['features'] = spec.features
|
||||
return ans
|
||||
family = spec.system or ''
|
||||
if family == 'auto':
|
||||
if bold or italic:
|
||||
|
@ -847,6 +847,20 @@ get_variation(Face *self, PyObject *a UNUSED) {
|
||||
Py_INCREF(ans); return ans;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
applied_features(Face *self, PyObject *a UNUSED) {
|
||||
RAII_PyObject(ans, PyTuple_New(self->font_features.count));
|
||||
if (!ans) return NULL;
|
||||
char buf[256];
|
||||
for (size_t i = 0; i < self->font_features.count; i++) {
|
||||
hb_feature_to_string(&self->font_features.features[i], buf, arraysz(buf));
|
||||
PyObject *t = PyUnicode_FromString(buf);
|
||||
if (!t) return NULL;
|
||||
PyTuple_SET_ITEM(ans, i, t);
|
||||
}
|
||||
Py_INCREF(ans); return ans;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
get_features(Face *self, PyObject *a UNUSED) {
|
||||
FT_Error err;
|
||||
@ -1023,6 +1037,7 @@ static PyMethodDef methods[] = {
|
||||
METHODB(identify_for_debug, METH_NOARGS),
|
||||
METHODB(extra_data, METH_NOARGS),
|
||||
METHODB(get_variable_data, METH_NOARGS),
|
||||
METHODB(applied_features, METH_NOARGS),
|
||||
METHODB(get_features, METH_NOARGS),
|
||||
METHODB(get_variation, METH_NOARGS),
|
||||
METHODB(get_best_name, METH_O),
|
||||
|
@ -10,6 +10,7 @@
|
||||
from kitty.constants import is_macos, read_kitty_resource
|
||||
from kitty.fast_data_types import (
|
||||
DECAWM,
|
||||
ParsedFontFeature,
|
||||
get_fallback_font,
|
||||
sprite_map_set_layout,
|
||||
sprite_map_set_limits,
|
||||
@ -33,6 +34,7 @@ def parse_font_spec(spec):
|
||||
class Selection(BaseTest):
|
||||
|
||||
def test_font_selection(self):
|
||||
self.set_options({'font_features': {'LiberationMono': (ParsedFontFeature('-dlig'),)}})
|
||||
opts = Options()
|
||||
fonts_map = all_fonts_map(True)
|
||||
names = set(fonts_map['family_map']) | set(fonts_map['variable_map'])
|
||||
@ -140,6 +142,17 @@ def t(x, **kw):
|
||||
t('bold', spec='variable_name=CascadiaCodeRoman wght=603')
|
||||
t('bi', spec='variable_name= wght=603')
|
||||
|
||||
# Test font features
|
||||
if has('liberation mono'):
|
||||
opts = Options()
|
||||
opts.font_family = parse_font_spec('family="liberation mono"')
|
||||
ff = get_font_files(opts)
|
||||
self.ae(face_from_descriptor(ff['medium']).applied_features(), ('-dlig',))
|
||||
self.ae(face_from_descriptor(ff['bold']).applied_features(), ())
|
||||
opts.font_family = parse_font_spec('family="liberation mono" features="dlig test"')
|
||||
ff = get_font_files(opts)
|
||||
self.ae(face_from_descriptor(ff['medium']).applied_features(), ('dlig', 'test'))
|
||||
|
||||
|
||||
class Rendering(BaseTest):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user