diff --git a/kitty/fonts/common.py b/kitty/fonts/common.py new file mode 100644 index 000000000..94ef9074b --- /dev/null +++ b/kitty/fonts/common.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# License: GPLv3 Copyright: 2024, Kovid Goyal + +from typing import TYPE_CHECKING, Dict, Union + +from kitty.constants import is_macos + +from . import VariableData + +if TYPE_CHECKING: + from kitty.fast_data_types import CoreTextFont, CTFace, FontConfigPattern + from kitty.fast_data_types import Face as FT_Face + + Descriptor = Union[FontConfigPattern, CoreTextFont] + def Face(descriptor: Descriptor) -> Union[FT_Face, CTFace]: + pass +else: + Descriptor = object + if is_macos: + from kitty.fast_data_types import CTFace as Face + else: + from kitty.fast_data_types import Face + + +cache_for_variable_data_by_path: Dict[str, VariableData] = {} + + +def get_variable_data_for_descriptor(d: Descriptor) -> VariableData: + if not d['path']: + return Face(descriptor=d).get_variable_data() + ans = cache_for_variable_data_by_path.get(d['path']) + if ans is None: + ans = cache_for_variable_data_by_path[d['path']] = Face(descriptor=d).get_variable_data() + return ans diff --git a/kitty/fonts/core_text.py b/kitty/fonts/core_text.py index ca0bf759a..7cf920a0c 100644 --- a/kitty/fonts/core_text.py +++ b/kitty/fonts/core_text.py @@ -4,8 +4,8 @@ import re from typing import Dict, Generator, Iterable, List, Optional, Tuple -from kitty.fast_data_types import CTFace, coretext_all_fonts -from kitty.fonts import FontSpec, VariableData +from kitty.fast_data_types import coretext_all_fonts +from kitty.fonts import FontSpec from kitty.options.types import Options from kitty.typing import CoreTextFont from kitty.utils import log_error @@ -119,19 +119,6 @@ def font_for_family(family: str) -> Tuple[CoreTextFont, bool, bool]: return ans, ans['bold'], ans['italic'] -cache_for_variable_data_by_path: Dict[str, VariableData] = {} - - -def get_variable_data_for_descriptor(f: ListedFont) -> VariableData: - d = descriptor(f) - if not d['path']: - return CTFace(descriptor=d).get_variable_data() - ans = cache_for_variable_data_by_path.get(d['path']) - if ans is None: - ans = cache_for_variable_data_by_path[d['path']] = CTFace(descriptor=d).get_variable_data() - return ans - - def descriptor(f: ListedFont) -> CoreTextFont: d = f['descriptor'] assert d['descriptor_type'] == 'core_text' diff --git a/kitty/fonts/fontconfig.py b/kitty/fonts/fontconfig.py index 66cf4680a..a340e4734 100644 --- a/kitty/fonts/fontconfig.py +++ b/kitty/fonts/fontconfig.py @@ -20,7 +20,7 @@ from kitty.fast_data_types import fc_match as fc_match_impl from kitty.options.types import Options from kitty.typing import FontConfigPattern -from . import FontSpec, ListedFont, VariableData +from . import FontSpec, ListedFont attr_map = {(False, False): 'font_family', (True, False): 'bold_font', @@ -166,8 +166,11 @@ def get_fine_grained_font( resolved_medium_font: Optional[FontConfigPattern] = None, monospaced: bool = True ) -> FontConfigPattern: font_map = all_fonts_map(monospaced) - scorer = create_scorer(bold, italic, monospaced, prefer_variable=bool(spec.axes) or bool(spec.style)) - is_medium_face = not bold and not italic + is_medium_face = resolved_medium_font is None + prefer_variable = bool(spec.axes) or bool(spec.style) + if resolved_medium_font and resolved_medium_font['variable']: + prefer_variable = True + scorer = create_scorer(bold, italic, monospaced, prefer_variable=prefer_variable) if spec.postscript_name: q = find_best_match_in_candidates(font_map['ps_map'].get(family_name_to_key(spec.postscript_name), []), scorer, is_medium_face) if q: @@ -263,19 +266,6 @@ def descriptor(f: ListedFont) -> FontConfigPattern: return d -cache_for_variable_data_by_path: Dict[str, VariableData] = {} - - -def get_variable_data_for_descriptor(f: ListedFont) -> VariableData: - d = descriptor(f) - if not d['path']: - return Face(descriptor=d).get_variable_data() - ans = cache_for_variable_data_by_path.get(d['path']) - if ans is None: - ans = cache_for_variable_data_by_path[d['path']] = Face(descriptor=d).get_variable_data() - return ans - - 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']} diff --git a/kitty/fonts/list.py b/kitty/fonts/list.py index a7fb606c1..16f04d4d4 100644 --- a/kitty/fonts/list.py +++ b/kitty/fonts/list.py @@ -9,11 +9,12 @@ from kitty.constants import is_macos from kitty.types import run_once from . import ListedFont +from .common import get_variable_data_for_descriptor if is_macos: - from .core_text import get_variable_data_for_descriptor, list_fonts, prune_family_group + from .core_text import list_fonts, prune_family_group else: - from .fontconfig import get_variable_data_for_descriptor, list_fonts, prune_family_group + from .fontconfig import list_fonts, prune_family_group @run_once @@ -58,7 +59,7 @@ def create_family_groups(monospaced: bool = True) -> Dict[str, List[ListedFont]] def show_variable(f: ListedFont, psnames: bool) -> None: - vd = get_variable_data_for_descriptor(f) + vd = get_variable_data_for_descriptor(f['descriptor']) p = italic(vd['variations_postscript_name_prefix'] or f['family']) p = f"{p} {variable_font_label('Variable font')}" print(indented(p))