Add information about variable fonts to list-fonts output

This commit is contained in:
Kovid Goyal
2024-04-20 06:05:34 +05:30
parent 57770f2f55
commit f4311d4b61
5 changed files with 76 additions and 31 deletions

View File

@@ -3,7 +3,7 @@ from ctypes import Array, c_ubyte
from typing import Any, Callable, Dict, Iterator, List, NewType, Optional, Tuple, TypedDict, Union, overload
from kitty.boss import Boss
from kitty.fonts import FontFeature
from kitty.fonts import FontFeature, VariableData
from kitty.fonts.render import FontObject
from kitty.marks import MarkerFunc
from kitty.options.types import Options
@@ -416,26 +416,6 @@ def fc_match_postscript_name(
pass
class VariableAxis(TypedDict):
minimum: float
maximum: float
default: float
hidden: bool
tag: str
strid: Optional[str]
class NamedStyle(TypedDict):
axis_values: Tuple[float, ...]
name: Optional[str]
psname: Optional[str]
class VariableData(TypedDict):
axes: Tuple[VariableAxis, ...]
named_styles: Tuple[NamedStyle, ...]
class Face:
def __init__(self, descriptor: Optional[FontConfigPattern] = None, path: str = '', index: int = 0): ...
def get_variable_data(self) -> VariableData: ...

View File

@@ -1,5 +1,5 @@
from enum import Enum, IntEnum, auto
from typing import Any, NamedTuple, TypedDict
from typing import Any, NamedTuple, Optional, Tuple, TypedDict
class ListedFont(TypedDict):
@@ -11,6 +11,27 @@ class ListedFont(TypedDict):
descriptor: Any
class VariableAxis(TypedDict):
minimum: float
maximum: float
default: float
hidden: bool
tag: str
strid: Optional[str]
class NamedStyle(TypedDict):
axis_values: Tuple[float, ...]
name: Optional[str]
psname: Optional[str]
class VariableData(TypedDict):
axes: Tuple[VariableAxis, ...]
named_styles: Tuple[NamedStyle, ...]
class FontFeature:
__slots__ = 'name', 'parsed'

View File

@@ -13,16 +13,17 @@ from kitty.fast_data_types import (
FC_WEIGHT_BOLD,
FC_WEIGHT_REGULAR,
FC_WIDTH_NORMAL,
Face,
fc_list,
fc_match_postscript_name,
parse_font_feature,
)
from kitty.fast_data_types import fc_match as fc_match_impl, Face
from kitty.fast_data_types import fc_match as fc_match_impl
from kitty.options.types import Options
from kitty.typing import FontConfigPattern
from kitty.utils import log_error
from . import FontFeature, ListedFont
from . import FontFeature, ListedFont, VariableData
attr_map = {(False, False): 'font_family',
(True, False): 'bold_font',
@@ -176,6 +177,5 @@ 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(fd: FontConfigPattern) -> None:
f = Face(descriptor=fd)
print(f.get_variable_axes())
def get_variable_data_for_descriptor(fd: FontConfigPattern) -> VariableData:
return Face(descriptor=fd).get_variable_data()

View File

@@ -6,6 +6,7 @@ from typing import Dict, List, Sequence
from kittens.tui.operations import styled
from kitty.constants import is_macos
from kitty.types import run_once
from . import ListedFont
@@ -15,18 +16,39 @@ else:
from .fontconfig import get_variable_data_for_descriptor, list_fonts
@run_once
def isatty() -> bool:
return sys.stdout.isatty()
def title(x: str) -> str:
if sys.stdout.isatty():
if isatty():
return styled(x, fg='green', bold=True)
return x
def italic(x: str) -> str:
if sys.stdout.isatty():
if isatty():
return styled(x, italic=True)
return x
def variable_font_label(x: str) -> str:
if isatty():
return styled(x, fg='yellow')
return x
def variable_font_tag(x: str) -> str:
if isatty():
return styled(x, fg='cyan')
return x
def indented(x: str, level: int = 1) -> str:
return ' ' * level + x
def create_family_groups(monospaced: bool = True) -> Dict[str, List[ListedFont]]:
g: Dict[str, List[ListedFont]] = {}
for f in list_fonts():
@@ -36,7 +58,28 @@ def create_family_groups(monospaced: bool = True) -> Dict[str, List[ListedFont]]
def show_variable(f: ListedFont, psnames: bool) -> None:
get_variable_data_for_descriptor(f['descriptor'])
vd = get_variable_data_for_descriptor(f['descriptor'])
p = f"{italic(f['full_name'])} {variable_font_label('Variable font')}"
print(indented(p))
print(indented(variable_font_label('Axes of variation'), level=2))
for a in vd['axes']:
t = variable_font_tag(a['tag'])
n = a['strid'] or ''
if n:
t += f' ({n})'
print(indented(t, level=3) + ':', f'minimum={a["minimum"]:g}', f'maximum={a["maximum"]:g}', f'default={a["default"]:g}')
if vd['named_styles']:
print(indented(variable_font_label('Named styles'), level=2))
for ns in vd['named_styles']:
name = ns['name'] or ''
if psnames:
name += f' ({ns["psname"] or ""})'
axes = []
for axis, val in zip(vd['axes'], ns['axis_values']):
axes.append(f'{axis["tag"]}={val:g}')
p = name + ': ' + ' '.join(axes)
print(indented(p, level=3))
def main(argv: Sequence[str]) -> None:
@@ -51,5 +94,5 @@ def main(argv: Sequence[str]) -> None:
p = italic(f['full_name'])
if psnames:
p += ' ({})'.format(f['postscript_name'])
print(' ', p)
print(indented(p))
print()

View File

@@ -802,6 +802,7 @@ convert_named_style_to_python(Face *face, const FT_Var_Named_Style *src, unsigne
static PyObject*
tag_to_string(uint32_t tag) {
if (!tag) return PyUnicode_FromString("");
unsigned char bytes[5] = {0};
bytes[0] = (tag >> 24) & 0xff;
bytes[1] = (tag >> 16) & 0xff;