mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-02 12:44:01 +02:00
Prune listings of variable fonts
Show only one entry per style per variable font as identified by path
This commit is contained in:
@@ -845,10 +845,13 @@ get_variable_data(CTFace *self) {
|
||||
RAII_CoreFoundation(CFArrayRef, descriptors, CTFontCollectionCreateMatchingFontDescriptors(collection));
|
||||
RAII_PyObject(named_styles, PyTuple_New(CFArrayGetCount(descriptors)));
|
||||
Py_ssize_t actual_num = 0;
|
||||
RAII_CoreFoundation(CFURLRef, url, CTFontCopyAttribute(self->ct_font, kCTFontURLAttribute));
|
||||
for (CFIndex i = 0; i < CFArrayGetCount(descriptors); i++) {
|
||||
CTFontDescriptorRef descriptor = (CTFontDescriptorRef)CFArrayGetValueAtIndex(descriptors, i);
|
||||
RAII_CoreFoundation(CFDictionaryRef, variation, CTFontDescriptorCopyAttribute(descriptor, kCTFontVariationAttribute));
|
||||
if (!variation) continue;
|
||||
RAII_CoreFoundation(CFURLRef, candidate_url, CTFontDescriptorCopyAttribute(descriptor, kCTFontURLAttribute));
|
||||
if (!CFEqual(url, candidate_url)) continue;
|
||||
RAII_CoreFoundation(CFStringRef, style, CTFontDescriptorCopyAttribute(descriptor, kCTFontStyleNameAttribute));
|
||||
RAII_CoreFoundation(CFStringRef, psname, CTFontDescriptorCopyAttribute(descriptor, kCTFontNameAttribute));
|
||||
RAII_PyObject(axis_values, PyDict_New());
|
||||
|
||||
@@ -118,6 +118,26 @@ def font_for_family(family: str) -> Tuple[CoreTextFont, bool, bool]:
|
||||
|
||||
|
||||
def get_variable_data_for_descriptor(f: ListedFont) -> VariableData:
|
||||
return CTFace(descriptor=descriptor(f)).get_variable_data()
|
||||
|
||||
|
||||
def descriptor(f: ListedFont) -> CoreTextFont:
|
||||
d = f['descriptor']
|
||||
assert d['descriptor_type'] == 'core_text'
|
||||
return CTFace(descriptor=d).get_variable_data()
|
||||
return d
|
||||
|
||||
|
||||
def prune_family_group(g: List[ListedFont]) -> List[ListedFont]:
|
||||
# CoreText returns a separate font for every style in the variable font, so
|
||||
# merge them.
|
||||
variable_paths = {descriptor(f)['path']: False for f in g if f['is_variable']}
|
||||
if not variable_paths:
|
||||
return g
|
||||
def is_ok(d: CoreTextFont) -> bool:
|
||||
if d['path'] not in variable_paths:
|
||||
return True
|
||||
if not variable_paths[d['path']]:
|
||||
variable_paths[d['path']] = True
|
||||
return True
|
||||
return False
|
||||
return [x for x in g if is_ok(descriptor(x))]
|
||||
|
||||
@@ -177,7 +177,22 @@ def font_for_family(family: str) -> Tuple[FontConfigPattern, bool, bool]:
|
||||
return ans, ans.get('weight', 0) >= FC_WEIGHT_BOLD, ans.get('slant', FC_SLANT_ROMAN) != FC_SLANT_ROMAN
|
||||
|
||||
|
||||
def get_variable_data_for_descriptor(f: ListedFont) -> VariableData:
|
||||
def descriptor(f: ListedFont) -> FontConfigPattern:
|
||||
d = f['descriptor']
|
||||
assert d['descriptor_type'] == 'fontconfig'
|
||||
return Face(descriptor=d).get_variable_data()
|
||||
return d
|
||||
|
||||
|
||||
def get_variable_data_for_descriptor(f: ListedFont) -> VariableData:
|
||||
return Face(descriptor=descriptor(f)).get_variable_data()
|
||||
|
||||
|
||||
def prune_family_group(g: List[ListedFont]) -> List[ListedFont]:
|
||||
# fontconfig creates dummy entries for named styles in variable fonts, prune them
|
||||
variable_paths = {descriptor(f)['path'] for f in g if f['is_variable']}
|
||||
if not variable_paths:
|
||||
return g
|
||||
def is_ok(d: FontConfigPattern) -> bool:
|
||||
return d['variable'] or d['path'] not in variable_paths
|
||||
|
||||
return [x for x in g if is_ok(descriptor(x))]
|
||||
|
||||
@@ -11,9 +11,9 @@ from kitty.types import run_once
|
||||
from . import ListedFont
|
||||
|
||||
if is_macos:
|
||||
from .core_text import get_variable_data_for_descriptor, list_fonts
|
||||
from .core_text import get_variable_data_for_descriptor, list_fonts, prune_family_group
|
||||
else:
|
||||
from .fontconfig import get_variable_data_for_descriptor, list_fonts
|
||||
from .fontconfig import get_variable_data_for_descriptor, list_fonts, prune_family_group
|
||||
|
||||
|
||||
@run_once
|
||||
@@ -54,14 +54,12 @@ def create_family_groups(monospaced: bool = True) -> Dict[str, List[ListedFont]]
|
||||
for f in list_fonts():
|
||||
if not monospaced or f['is_monospace']:
|
||||
g.setdefault(f['family'], []).append(f)
|
||||
return g
|
||||
return {k: prune_family_group(v) for k, v in g.items()}
|
||||
|
||||
|
||||
def show_variable(f: ListedFont, psnames: bool) -> None:
|
||||
vd = get_variable_data_for_descriptor(f)
|
||||
p = italic(f['full_name'])
|
||||
if psnames and f['postscript_name']:
|
||||
p += f' ({f["postscript_name"]})'
|
||||
p = italic(f['family'])
|
||||
p = f"{p} {variable_font_label('Variable font')}"
|
||||
print(indented(p))
|
||||
print(indented(variable_font_label('Axes of variation'), level=2))
|
||||
|
||||
Reference in New Issue
Block a user