fonttools 4.59.2__cp39-cp39-musllinux_1_2_aarch64.whl → 4.60.1__cp39-cp39-musllinux_1_2_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fonttools might be problematic. Click here for more details.

Files changed (44) hide show
  1. fontTools/__init__.py +1 -1
  2. fontTools/annotations.py +30 -0
  3. fontTools/cu2qu/cu2qu.c +1057 -937
  4. fontTools/cu2qu/cu2qu.cpython-39-aarch64-linux-gnu.so +0 -0
  5. fontTools/cu2qu/cu2qu.py +19 -2
  6. fontTools/feaLib/lexer.c +8 -3
  7. fontTools/feaLib/lexer.cpython-39-aarch64-linux-gnu.so +0 -0
  8. fontTools/misc/bezierTools.c +8 -3
  9. fontTools/misc/bezierTools.cpython-39-aarch64-linux-gnu.so +0 -0
  10. fontTools/misc/enumTools.py +23 -0
  11. fontTools/misc/visitor.py +24 -16
  12. fontTools/pens/filterPen.py +218 -26
  13. fontTools/pens/momentsPen.c +8 -3
  14. fontTools/pens/momentsPen.cpython-39-aarch64-linux-gnu.so +0 -0
  15. fontTools/pens/pointPen.py +40 -6
  16. fontTools/qu2cu/qu2cu.c +20 -7
  17. fontTools/qu2cu/qu2cu.cpython-39-aarch64-linux-gnu.so +0 -0
  18. fontTools/subset/__init__.py +178 -12
  19. fontTools/ttLib/tables/_p_o_s_t.py +5 -5
  20. fontTools/ufoLib/__init__.py +278 -175
  21. fontTools/ufoLib/converters.py +14 -5
  22. fontTools/ufoLib/filenames.py +16 -6
  23. fontTools/ufoLib/glifLib.py +286 -190
  24. fontTools/ufoLib/kerning.py +32 -12
  25. fontTools/ufoLib/utils.py +41 -13
  26. fontTools/ufoLib/validators.py +121 -97
  27. fontTools/varLib/avar/__init__.py +0 -0
  28. fontTools/varLib/avar/__main__.py +72 -0
  29. fontTools/varLib/avar/build.py +79 -0
  30. fontTools/varLib/avar/map.py +108 -0
  31. fontTools/varLib/avar/plan.py +1004 -0
  32. fontTools/varLib/{avar.py → avar/unbuild.py} +70 -59
  33. fontTools/varLib/avarPlanner.py +3 -999
  34. fontTools/varLib/interpolatableHelpers.py +3 -0
  35. fontTools/varLib/iup.c +14 -5
  36. fontTools/varLib/iup.cpython-39-aarch64-linux-gnu.so +0 -0
  37. {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/METADATA +41 -2
  38. {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/RECORD +44 -37
  39. {fonttools-4.59.2.data → fonttools-4.60.1.data}/data/share/man/man1/ttx.1 +0 -0
  40. {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/WHEEL +0 -0
  41. {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/entry_points.txt +0 -0
  42. {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/licenses/LICENSE +0 -0
  43. {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/licenses/LICENSE.external +0 -0
  44. {fonttools-4.59.2.dist-info → fonttools-4.60.1.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,20 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Optional
4
+
5
+ from fontTools.annotations import KerningPair, KerningDict, KerningGroups, IntFloat
6
+
7
+ StrDict = dict[str, str]
8
+
9
+
1
10
  def lookupKerningValue(
2
- pair, kerning, groups, fallback=0, glyphToFirstGroup=None, glyphToSecondGroup=None
3
- ):
11
+ pair: KerningPair,
12
+ kerning: KerningDict,
13
+ groups: KerningGroups,
14
+ fallback: IntFloat = 0,
15
+ glyphToFirstGroup: Optional[StrDict] = None,
16
+ glyphToSecondGroup: Optional[StrDict] = None,
17
+ ) -> IntFloat:
4
18
  """Retrieve the kerning value (if any) between a pair of elements.
5
19
 
6
20
  The elments can be either individual glyphs (by name) or kerning
@@ -72,11 +86,12 @@ def lookupKerningValue(
72
86
  # quickly check to see if the pair is in the kerning dictionary
73
87
  if pair in kerning:
74
88
  return kerning[pair]
89
+ # ensure both or no glyph-to-group mappings are provided
90
+ if (glyphToFirstGroup is None) != (glyphToSecondGroup is None):
91
+ raise ValueError(
92
+ "Must provide both 'glyphToFirstGroup' and 'glyphToSecondGroup', or neither."
93
+ )
75
94
  # create glyph to group mapping
76
- if glyphToFirstGroup is not None:
77
- assert glyphToSecondGroup is not None
78
- if glyphToSecondGroup is not None:
79
- assert glyphToFirstGroup is not None
80
95
  if glyphToFirstGroup is None:
81
96
  glyphToFirstGroup = {}
82
97
  glyphToSecondGroup = {}
@@ -87,25 +102,30 @@ def lookupKerningValue(
87
102
  elif group.startswith("public.kern2."):
88
103
  for glyph in groupMembers:
89
104
  glyphToSecondGroup[glyph] = group
105
+ # ensure type safety for mappings
106
+ assert glyphToFirstGroup is not None
107
+ assert glyphToSecondGroup is not None
90
108
  # get group names and make sure first and second are glyph names
91
109
  first, second = pair
92
110
  firstGroup = secondGroup = None
93
111
  if first.startswith("public.kern1."):
94
112
  firstGroup = first
95
- first = None
113
+ firstGlyph = None
96
114
  else:
97
115
  firstGroup = glyphToFirstGroup.get(first)
116
+ firstGlyph = first
98
117
  if second.startswith("public.kern2."):
99
118
  secondGroup = second
100
- second = None
119
+ secondGlyph = None
101
120
  else:
102
121
  secondGroup = glyphToSecondGroup.get(second)
122
+ secondGlyph = second
103
123
  # make an ordered list of pairs to look up
104
124
  pairs = [
105
- (first, second),
106
- (first, secondGroup),
107
- (firstGroup, second),
108
- (firstGroup, secondGroup),
125
+ (a, b)
126
+ for a in (firstGlyph, firstGroup)
127
+ for b in (secondGlyph, secondGroup)
128
+ if a is not None and b is not None
109
129
  ]
110
130
  # look up the pairs and return any matches
111
131
  for pair in pairs:
fontTools/ufoLib/utils.py CHANGED
@@ -5,14 +5,22 @@ define the :py:obj:`.deprecated` decorator that is used elsewhere in
5
5
  the module.
6
6
  """
7
7
 
8
- import warnings
8
+ from __future__ import annotations
9
+
10
+ from typing import Optional, Type, TypeVar, Union, cast
11
+ from collections.abc import Callable
12
+ import enum
9
13
  import functools
14
+ import warnings
10
15
 
16
+ F = TypeVar("F", bound=Callable[..., object])
17
+ FormatVersion = TypeVar("FormatVersion", bound="BaseFormatVersion")
18
+ FormatVersionInput = Optional[Union[int, tuple[int, int], FormatVersion]]
11
19
 
12
20
  numberTypes = (int, float)
13
21
 
14
22
 
15
- def deprecated(msg=""):
23
+ def deprecated(msg: str = "") -> Callable[[F], F]:
16
24
  """Decorator factory to mark functions as deprecated with given message.
17
25
 
18
26
  >>> @deprecated("Enough!")
@@ -25,7 +33,7 @@ def deprecated(msg=""):
25
33
  True
26
34
  """
27
35
 
28
- def deprecated_decorator(func):
36
+ def deprecated_decorator(func: F) -> F:
29
37
  @functools.wraps(func)
30
38
  def wrapper(*args, **kwargs):
31
39
  warnings.warn(
@@ -35,41 +43,61 @@ def deprecated(msg=""):
35
43
  )
36
44
  return func(*args, **kwargs)
37
45
 
38
- return wrapper
46
+ return cast(F, wrapper)
39
47
 
40
48
  return deprecated_decorator
41
49
 
42
50
 
43
- # To be mixed with enum.Enum in UFOFormatVersion and GLIFFormatVersion
44
- class _VersionTupleEnumMixin:
51
+ def normalizeFormatVersion(
52
+ value: FormatVersionInput, cls: Type[FormatVersion]
53
+ ) -> FormatVersion:
54
+ # Needed for type safety of UFOFormatVersion and GLIFFormatVersion input
55
+ if value is None:
56
+ return cls.default()
57
+ if isinstance(value, cls):
58
+ return value
59
+ if isinstance(value, int):
60
+ return cls((value, 0))
61
+ if isinstance(value, tuple) and len(value) == 2:
62
+ return cls(value)
63
+ raise ValueError(f"Unsupported format version: {value!r}")
64
+
65
+
66
+ # Base class for UFOFormatVersion and GLIFFormatVersion
67
+ class BaseFormatVersion(tuple[int, int], enum.Enum):
68
+ value: tuple[int, int]
69
+
70
+ def __new__(cls: Type[FormatVersion], value: tuple[int, int]) -> BaseFormatVersion:
71
+ return super().__new__(cls, value)
72
+
45
73
  @property
46
- def major(self):
74
+ def major(self) -> int:
47
75
  return self.value[0]
48
76
 
49
77
  @property
50
- def minor(self):
78
+ def minor(self) -> int:
51
79
  return self.value[1]
52
80
 
53
81
  @classmethod
54
- def _missing_(cls, value):
82
+ def _missing_(cls, value: object) -> BaseFormatVersion:
55
83
  # allow to initialize a version enum from a single (major) integer
56
84
  if isinstance(value, int):
57
85
  return cls((value, 0))
58
86
  # or from None to obtain the current default version
59
87
  if value is None:
60
88
  return cls.default()
61
- return super()._missing_(value)
89
+ raise ValueError(f"{value!r} is not a valid {cls.__name__}")
62
90
 
63
- def __str__(self):
91
+ def __str__(self) -> str:
64
92
  return f"{self.major}.{self.minor}"
65
93
 
66
94
  @classmethod
67
- def default(cls):
95
+ def default(cls: Type[FormatVersion]) -> FormatVersion:
68
96
  # get the latest defined version (i.e. the max of all versions)
69
97
  return max(cls.__members__.values())
70
98
 
71
99
  @classmethod
72
- def supported_versions(cls):
100
+ def supported_versions(cls: Type[FormatVersion]) -> frozenset[FormatVersion]:
73
101
  return frozenset(cls.__members__.values())
74
102
 
75
103