fonttools 4.59.0__cp39-cp39-win32.whl → 4.59.1__cp39-cp39-win32.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.

fontTools/__init__.py CHANGED
@@ -3,6 +3,6 @@ from fontTools.misc.loggingTools import configLogger
3
3
 
4
4
  log = logging.getLogger(__name__)
5
5
 
6
- version = __version__ = "4.59.0"
6
+ version = __version__ = "4.59.1"
7
7
 
8
8
  __all__ = ["version", "log", "configLogger"]
@@ -2,13 +2,17 @@
2
2
 
3
3
  from fontTools.ttLib import TTFont, newTable
4
4
  from fontTools.misc.cliTools import makeOutputFileName
5
+ from fontTools.misc.psCharStrings import T2StackUseExtractor
5
6
  from fontTools.cffLib import (
6
7
  TopDictIndex,
7
8
  buildOrder,
8
9
  buildDefaults,
9
10
  topDictOperators,
10
11
  privateDictOperators,
12
+ FDSelect,
11
13
  )
14
+ from .transforms import desubroutinizeCharString
15
+ from .specializer import specializeProgram
12
16
  from .width import optimizeWidths
13
17
  from collections import defaultdict
14
18
  import logging
@@ -27,7 +31,7 @@ def _convertCFF2ToCFF(cff, otFont):
27
31
  The CFF2 font cannot be variable. (TODO Accept those and convert to the
28
32
  default instance?)
29
33
 
30
- This assumes a decompiled CFF table. (i.e. that the object has been
34
+ This assumes a decompiled CFF2 table. (i.e. that the object has been
31
35
  filled via :meth:`decompile` and e.g. not loaded from XML.)"""
32
36
 
33
37
  cff.major = 1
@@ -51,9 +55,14 @@ def _convertCFF2ToCFF(cff, otFont):
51
55
  if hasattr(topDict, key):
52
56
  delattr(topDict, key)
53
57
 
54
- fdArray = topDict.FDArray
55
58
  charStrings = topDict.CharStrings
56
59
 
60
+ fdArray = topDict.FDArray
61
+ if not hasattr(topDict, "FDSelect"):
62
+ # FDSelect is optional in CFF2, but required in CFF.
63
+ fdSelect = topDict.FDSelect = FDSelect()
64
+ fdSelect.gidArray = [0] * len(charStrings.charStrings)
65
+
57
66
  defaults = buildDefaults(privateDictOperators)
58
67
  order = buildOrder(privateDictOperators)
59
68
  for fd in fdArray:
@@ -69,6 +78,7 @@ def _convertCFF2ToCFF(cff, otFont):
69
78
  if hasattr(privateDict, key):
70
79
  delattr(privateDict, key)
71
80
 
81
+ # Add ending operators
72
82
  for cs in charStrings.values():
73
83
  cs.decompile()
74
84
  cs.program.append("endchar")
@@ -100,23 +110,43 @@ def _convertCFF2ToCFF(cff, otFont):
100
110
  if width != private.defaultWidthX:
101
111
  cs.program.insert(0, width - private.nominalWidthX)
102
112
 
113
+ # Handle stack use since stack-depth is lower in CFF than in CFF2.
114
+ for glyphName in charStrings.keys():
115
+ cs, fdIndex = charStrings.getItemAndSelector(glyphName)
116
+ if fdIndex is None:
117
+ fdIndex = 0
118
+ private = fdArray[fdIndex].Private
119
+ extractor = T2StackUseExtractor(
120
+ getattr(private, "Subrs", []), cff.GlobalSubrs, private=private
121
+ )
122
+ stackUse = extractor.execute(cs)
123
+ if stackUse > 48: # CFF stack depth is 48
124
+ desubroutinizeCharString(cs)
125
+ cs.program = specializeProgram(cs.program)
126
+
127
+ # Unused subroutines are still in CFF2 (ie. lacking 'return' operator)
128
+ # because they were not decompiled when we added the 'return'.
129
+ # Moreover, some used subroutines may have become unused after the
130
+ # stack-use fixup. So we remove all unused subroutines now.
131
+ cff.remove_unused_subroutines()
132
+
103
133
  mapping = {
104
- name: ("cid" + str(n) if n else ".notdef")
134
+ name: ("cid" + str(n).zfill(5) if n else ".notdef")
105
135
  for n, name in enumerate(topDict.charset)
106
136
  }
107
137
  topDict.charset = [
108
- "cid" + str(n) if n else ".notdef" for n in range(len(topDict.charset))
138
+ "cid" + str(n).zfill(5) if n else ".notdef" for n in range(len(topDict.charset))
109
139
  ]
110
140
  charStrings.charStrings = {
111
141
  mapping[name]: v for name, v in charStrings.charStrings.items()
112
142
  }
113
143
 
114
- # I'm not sure why the following is *not* necessary. And it breaks
115
- # the output if I add it.
116
- # topDict.ROS = ("Adobe", "Identity", 0)
144
+ topDict.ROS = ("Adobe", "Identity", 0)
117
145
 
118
146
 
119
147
  def convertCFF2ToCFF(font, *, updatePostTable=True):
148
+ if "CFF2" not in font:
149
+ raise ValueError("Input font does not contain a CFF2 table.")
120
150
  cff = font["CFF2"].cff
121
151
  _convertCFF2ToCFF(cff, font)
122
152
  del font["CFF2"]
@@ -131,7 +161,7 @@ def convertCFF2ToCFF(font, *, updatePostTable=True):
131
161
 
132
162
 
133
163
  def main(args=None):
134
- """Convert CFF OTF font to CFF2 OTF font"""
164
+ """Convert CFF2 OTF font to CFF OTF font"""
135
165
  if args is None:
136
166
  import sys
137
167
 
@@ -140,8 +170,8 @@ def main(args=None):
140
170
  import argparse
141
171
 
142
172
  parser = argparse.ArgumentParser(
143
- "fonttools cffLib.CFFToCFF2",
144
- description="Upgrade a CFF font to CFF2.",
173
+ "fonttools cffLib.CFF2ToCFF",
174
+ description="Convert a non-variable CFF2 font to CFF.",
145
175
  )
146
176
  parser.add_argument(
147
177
  "input", metavar="INPUT.ttf", help="Input OTF file with CFF table."
@@ -94,17 +94,22 @@ class _DesubroutinizingT2Decompiler(SimpleT2Decompiler):
94
94
  cs._patches.append((index, subr._desubroutinized))
95
95
 
96
96
 
97
+ def desubroutinizeCharString(cs):
98
+ """Desubroutinize a charstring in-place."""
99
+ cs.decompile()
100
+ subrs = getattr(cs.private, "Subrs", [])
101
+ decompiler = _DesubroutinizingT2Decompiler(subrs, cs.globalSubrs, cs.private)
102
+ decompiler.execute(cs)
103
+ cs.program = cs._desubroutinized
104
+ del cs._desubroutinized
105
+
106
+
97
107
  def desubroutinize(cff):
98
108
  for fontName in cff.fontNames:
99
109
  font = cff[fontName]
100
110
  cs = font.CharStrings
101
111
  for c in cs.values():
102
- c.decompile()
103
- subrs = getattr(c.private, "Subrs", [])
104
- decompiler = _DesubroutinizingT2Decompiler(subrs, c.globalSubrs, c.private)
105
- decompiler.execute(c)
106
- c.program = c._desubroutinized
107
- del c._desubroutinized
112
+ desubroutinizeCharString(c)
108
113
  # Delete all the local subrs
109
114
  if hasattr(font, "FDArray"):
110
115
  for fd in font.FDArray:
Binary file
@@ -926,6 +926,11 @@ class Builder(object):
926
926
  l.lookup_index for l in lookups if l.lookup_index is not None
927
927
  )
928
928
  )
929
+ # order doesn't matter, but lookup_indices preserves it.
930
+ # We want to combine identical sets of lookups (order doesn't matter)
931
+ # but also respect the order provided by the user (although there's
932
+ # a reasonable argument to just sort and dedupe, which fontc does)
933
+ lookup_key = frozenset(lookup_indices)
929
934
 
930
935
  size_feature = tag == "GPOS" and feature_tag == "size"
931
936
  force_feature = self.any_feature_variations(feature_tag, tag)
@@ -943,7 +948,7 @@ class Builder(object):
943
948
  "stash debug information. See fonttools#2065."
944
949
  )
945
950
 
946
- feature_key = (feature_tag, lookup_indices)
951
+ feature_key = (feature_tag, lookup_key)
947
952
  feature_index = feature_indices.get(feature_key)
948
953
  if feature_index is None:
949
954
  feature_index = len(table.FeatureList.FeatureRecord)
Binary file
Binary file
@@ -338,7 +338,7 @@ class SimpleT2Decompiler(object):
338
338
  self.numRegions = 0
339
339
  self.vsIndex = 0
340
340
 
341
- def execute(self, charString):
341
+ def execute(self, charString, *, pushToStack=None):
342
342
  self.callingStack.append(charString)
343
343
  needsDecompilation = charString.needsDecompilation()
344
344
  if needsDecompilation:
@@ -346,7 +346,8 @@ class SimpleT2Decompiler(object):
346
346
  pushToProgram = program.append
347
347
  else:
348
348
  pushToProgram = lambda x: None
349
- pushToStack = self.operandStack.append
349
+ if pushToStack is None:
350
+ pushToStack = self.operandStack.append
350
351
  index = 0
351
352
  while True:
352
353
  token, isOperator, index = charString.getToken(index)
@@ -551,6 +552,20 @@ t1Operators = [
551
552
  ]
552
553
 
553
554
 
555
+ class T2StackUseExtractor(SimpleT2Decompiler):
556
+
557
+ def execute(self, charString):
558
+ maxStackUse = 0
559
+
560
+ def pushToStack(value):
561
+ nonlocal maxStackUse
562
+ self.operandStack.append(value)
563
+ maxStackUse = max(maxStackUse, len(self.operandStack))
564
+
565
+ super().execute(charString, pushToStack=pushToStack)
566
+ return maxStackUse
567
+
568
+
554
569
  class T2WidthExtractor(SimpleT2Decompiler):
555
570
  def __init__(
556
571
  self,
Binary file
Binary file
@@ -64,7 +64,6 @@ class table__g_v_a_r(DefaultTable.DefaultTable):
64
64
  self.variations = {}
65
65
 
66
66
  def compile(self, ttFont):
67
-
68
67
  axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
69
68
  sharedTuples = tv.compileSharedTuples(
70
69
  axisTags, itertools.chain(*self.variations.values())
@@ -141,8 +140,12 @@ class table__g_v_a_r(DefaultTable.DefaultTable):
141
140
  self,
142
141
  )
143
142
 
144
- assert len(glyphs) == self.glyphCount
145
- assert len(axisTags) == self.axisCount
143
+ assert len(glyphs) == self.glyphCount, (len(glyphs), self.glyphCount)
144
+ assert len(axisTags) == self.axisCount, (
145
+ len(axisTags),
146
+ self.axisCount,
147
+ axisTags,
148
+ )
146
149
  sharedCoords = tv.decompileSharedTuples(
147
150
  axisTags, self.sharedTupleCount, data, self.offsetToSharedTuples
148
151
  )
@@ -40,15 +40,19 @@ class table__h_m_t_x(DefaultTable.DefaultTable):
40
40
  % (self.headerTag, self.numberOfMetricsName)
41
41
  )
42
42
  numberOfMetrics = numGlyphs
43
- if len(data) < 4 * numberOfMetrics:
44
- raise ttLib.TTLibError("not enough '%s' table data" % self.tableTag)
43
+ numberOfSideBearings = numGlyphs - numberOfMetrics
44
+ tableSize = 4 * numberOfMetrics + 2 * numberOfSideBearings
45
+ if len(data) < tableSize:
46
+ raise ttLib.TTLibError(
47
+ f"not enough '{self.tableTag}' table data: "
48
+ f"expected {tableSize} bytes, got {len(data)}"
49
+ )
45
50
  # Note: advanceWidth is unsigned, but some font editors might
46
51
  # read/write as signed. We can't be sure whether it was a mistake
47
52
  # or not, so we read as unsigned but also issue a warning...
48
53
  metricsFmt = ">" + self.longMetricFormat * numberOfMetrics
49
54
  metrics = struct.unpack(metricsFmt, data[: 4 * numberOfMetrics])
50
55
  data = data[4 * numberOfMetrics :]
51
- numberOfSideBearings = numGlyphs - numberOfMetrics
52
56
  sideBearings = array.array("h", data[: 2 * numberOfSideBearings])
53
57
  data = data[2 * numberOfSideBearings :]
54
58
 
@@ -95,6 +95,14 @@ def addFeatureVariations(font, conditionalSubstitutions, featureTag="rvrn"):
95
95
 
96
96
  addFeatureVariationsRaw(font, font["GSUB"].table, conditionsAndLookups, featureTags)
97
97
 
98
+ # Update OS/2.usMaxContext in case the font didn't have features before, but
99
+ # does now, if the OS/2 table exists. The table may be required, but
100
+ # fontTools needs to be able to deal with non-standard fonts. Since feature
101
+ # variations are always 1:1 mappings, we can set the value to at least 1
102
+ # instead of recomputing it with `otlLib.maxContextCalc.maxCtxFont()`.
103
+ if (os2 := font.get("OS/2")) is not None:
104
+ os2.usMaxContext = max(1, os2.usMaxContext)
105
+
98
106
 
99
107
  def _existingVariableFeatures(table):
100
108
  existingFeatureVarsTags = set()
@@ -120,6 +120,7 @@ from fontTools.cffLib.specializer import (
120
120
  specializeCommands,
121
121
  generalizeCommands,
122
122
  )
123
+ from fontTools.cffLib.CFF2ToCFF import convertCFF2ToCFF
123
124
  from fontTools.varLib import builder
124
125
  from fontTools.varLib.mvar import MVAR_ENTRIES
125
126
  from fontTools.varLib.merger import MutatorMerger
@@ -136,6 +137,7 @@ from enum import IntEnum
136
137
  import logging
137
138
  import os
138
139
  import re
140
+ import io
139
141
  from typing import Dict, Iterable, Mapping, Optional, Sequence, Tuple, Union
140
142
  import warnings
141
143
 
@@ -643,7 +645,11 @@ def instantiateCFF2(
643
645
  # the Private dicts.
644
646
  #
645
647
  # Then prune unused things and possibly drop the VarStore if it's empty.
646
- # In which case, downgrade to CFF table if requested.
648
+ #
649
+ # If the downgrade parameter is True, no actual downgrading is done, but
650
+ # the function returns True if the VarStore was empty after instantiation,
651
+ # and hence a downgrade to CFF is possible. In all other cases it returns
652
+ # False.
647
653
 
648
654
  log.info("Instantiating CFF2 table")
649
655
 
@@ -882,9 +888,9 @@ def instantiateCFF2(
882
888
  del private.vstore
883
889
 
884
890
  if downgrade:
885
- from fontTools.cffLib.CFF2ToCFF import convertCFF2ToCFF
891
+ return True
886
892
 
887
- convertCFF2ToCFF(varfont)
893
+ return False
888
894
 
889
895
 
890
896
  def _instantiateGvarGlyph(
@@ -1377,6 +1383,52 @@ def _isValidAvarSegmentMap(axisTag, segmentMap):
1377
1383
  return True
1378
1384
 
1379
1385
 
1386
+ def downgradeCFF2ToCFF(varfont):
1387
+
1388
+ # Save these properties
1389
+ recalcTimestamp = varfont.recalcTimestamp
1390
+ recalcBBoxes = varfont.recalcBBoxes
1391
+
1392
+ # Disable them
1393
+ varfont.recalcTimestamp = False
1394
+ varfont.recalcBBoxes = False
1395
+
1396
+ # Save to memory, reload, downgrade and save again, reload.
1397
+ # We do this dance because the convertCFF2ToCFF changes glyph
1398
+ # names, so following save would fail if any other table was
1399
+ # loaded and referencing glyph names.
1400
+ #
1401
+ # The second save+load is unfortunate but also necessary.
1402
+
1403
+ stream = io.BytesIO()
1404
+ log.info("Saving CFF2 font to memory for downgrade")
1405
+ varfont.save(stream)
1406
+ stream.seek(0)
1407
+ varfont = TTFont(stream, recalcTimestamp=False, recalcBBoxes=False)
1408
+
1409
+ convertCFF2ToCFF(varfont)
1410
+
1411
+ stream = io.BytesIO()
1412
+ log.info("Saving downgraded CFF font to memory")
1413
+ varfont.save(stream)
1414
+ stream.seek(0)
1415
+ varfont = TTFont(stream, recalcTimestamp=False, recalcBBoxes=False)
1416
+
1417
+ # Uncomment, to see test all tables can be loaded. This fails without
1418
+ # the extra save+load above.
1419
+ """
1420
+ for tag in varfont.keys():
1421
+ print("Loading", tag)
1422
+ varfont[tag]
1423
+ """
1424
+
1425
+ # Restore them
1426
+ varfont.recalcTimestamp = recalcTimestamp
1427
+ varfont.recalcBBoxes = recalcBBoxes
1428
+
1429
+ return varfont
1430
+
1431
+
1380
1432
  def instantiateAvar(varfont, axisLimits):
1381
1433
  # 'axisLimits' dict must contain user-space (non-normalized) coordinates.
1382
1434
 
@@ -1665,7 +1717,9 @@ def instantiateVariableFont(
1665
1717
  instantiateVARC(varfont, normalizedLimits)
1666
1718
 
1667
1719
  if "CFF2" in varfont:
1668
- instantiateCFF2(varfont, normalizedLimits, downgrade=downgradeCFF2)
1720
+ downgradeCFF2 = instantiateCFF2(
1721
+ varfont, normalizedLimits, downgrade=downgradeCFF2
1722
+ )
1669
1723
 
1670
1724
  if "gvar" in varfont:
1671
1725
  instantiateGvar(varfont, normalizedLimits, optimize=optimize)
@@ -1720,6 +1774,12 @@ def instantiateVariableFont(
1720
1774
  # name table has been updated.
1721
1775
  setRibbiBits(varfont)
1722
1776
 
1777
+ if downgradeCFF2:
1778
+ origVarfont = varfont
1779
+ varfont = downgradeCFF2ToCFF(varfont)
1780
+ if inplace:
1781
+ origVarfont.__dict__ = varfont.__dict__.copy()
1782
+
1723
1783
  return varfont
1724
1784
 
1725
1785
 
@@ -1929,7 +1989,7 @@ def main(args=None):
1929
1989
  if limit is None or limit[0] == limit[2]
1930
1990
  }.issuperset(axis.axisTag for axis in varfont["fvar"].axes)
1931
1991
 
1932
- instantiateVariableFont(
1992
+ varfont = instantiateVariableFont(
1933
1993
  varfont,
1934
1994
  axisLimits,
1935
1995
  inplace=True,
Binary file
@@ -4,9 +4,16 @@ Instantiate a variation font. Run, eg:
4
4
  .. code-block:: sh
5
5
 
6
6
  $ fonttools varLib.mutator ./NotoSansArabic-VF.ttf wght=140 wdth=85
7
+
8
+ .. warning::
9
+ ``fontTools.varLib.mutator`` is deprecated in favor of :mod:`fontTools.varLib.instancer`
10
+ which provides equivalent full instancing and also supports partial instancing.
11
+ Please migrate CLI usage to ``fonttools varLib.instancer`` and API usage to
12
+ :func:`fontTools.varLib.instancer.instantiateVariableFont`.
7
13
  """
8
14
 
9
15
  from fontTools.misc.fixedTools import floatToFixedToFloat, floatToFixed
16
+ from fontTools.misc.loggingTools import deprecateFunction
10
17
  from fontTools.misc.roundTools import otRound
11
18
  from fontTools.pens.boundsPen import BoundsPen
12
19
  from fontTools.ttLib import TTFont, newTable
@@ -159,6 +166,10 @@ def interpolate_cff2_metrics(varfont, topDict, glyphOrder, loc):
159
166
  hmtx[gname] = tuple(entry)
160
167
 
161
168
 
169
+ @deprecateFunction(
170
+ "use fontTools.varLib.instancer.instantiateVariableFont instead "
171
+ "for either full or partial instancing",
172
+ )
162
173
  def instantiateVariableFont(varfont, location, inplace=False, overlap=True):
163
174
  """Generate a static instance from a variable TTFont and a dictionary
164
175
  defining the desired location along the variable font's axes.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fonttools
3
- Version: 4.59.0
3
+ Version: 4.59.1
4
4
  Summary: Tools to manipulate font files
5
5
  Home-page: http://github.com/fonttools/fonttools
6
6
  Author: Just van Rossum
@@ -168,15 +168,6 @@ are required to unlock the extra features named "ufo", etc.
168
168
 
169
169
  *Extra:* ``lxml``
170
170
 
171
- - ``Lib/fontTools/ufoLib``
172
-
173
- Package for reading and writing UFO source files; it requires:
174
-
175
- * `fs <https://pypi.org/pypi/fs>`__: (aka ``pyfilesystem2``) filesystem
176
- abstraction layer.
177
-
178
- *Extra:* ``ufo``
179
-
180
171
  - ``Lib/fontTools/ttLib/woff2.py``
181
172
 
182
173
  Module to compress/decompress WOFF 2.0 web fonts; it requires:
@@ -269,6 +260,17 @@ are required to unlock the extra features named "ufo", etc.
269
260
 
270
261
  *Extra:* ``pathops``
271
262
 
263
+ - ``Lib/fontTools/ufoLib``
264
+
265
+ Package for reading and writing UFO source files; if available, it will use:
266
+
267
+ * `fs <https://pypi.org/pypi/fs>`__: (aka ``pyfilesystem2``) filesystem abstraction layer
268
+
269
+ for reading and writing UFOs to the local filesystem or zip files (.ufoz), instead of
270
+ the built-in ``fontTools.misc.filesystem`` package.
271
+ The reader and writer classes can in theory also accept any object compatible the
272
+ ``fs.base.FS`` interface, although not all have been tested.
273
+
272
274
  - ``Lib/fontTools/pens/cocoaPen.py`` and ``Lib/fontTools/pens/quartzPen.py``
273
275
 
274
276
  Pens for drawing glyphs with Cocoa ``NSBezierPath`` or ``CGPath`` require:
@@ -386,6 +388,18 @@ Have fun!
386
388
  Changelog
387
389
  ~~~~~~~~~
388
390
 
391
+ 4.59.1 (released 2025-08-14)
392
+ ----------------------------
393
+
394
+ - [featureVars] Update OS/2.usMaxContext if possible after addFeatureVariationsRaw (#3894).
395
+ - [vhmtx] raise TTLibError('not enough data...') when hmtx/vmtx are truncated (#3843, #3901).
396
+ - [feaLib] Combine duplicate features that have the same set of lookups regardless of the order in which those lookups are added to the feature (#3895).
397
+ - [varLib] Deprecate ``varLib.mutator`` in favor of ``varLib.instancer``. The latter
398
+ provides equivalent full (static font) instancing in addition to partial VF instancing.
399
+ CLI users should replace ``fonttools varLib.mutator`` with ``fonttools varLib.instancer``.
400
+ API users should migrate to ``fontTools.varLib.instancer.instantiateVariableFont`` (#2680).
401
+
402
+
389
403
  4.59.0 (released 2025-07-16)
390
404
  ----------------------------
391
405
 
@@ -1,4 +1,4 @@
1
- fontTools/__init__.py,sha256=5U6x_uZd11VYk1ucwvyYEj3wYSfJMdnXPt0twVOXaPQ,191
1
+ fontTools/__init__.py,sha256=57GFbw-0oMhpoPuHsKfQPQWBV6jVdkCDEyCW48RYF64,191
2
2
  fontTools/__main__.py,sha256=T8Tg8xPKHOCVoYVG82p_zpQXfW7_ERRAphBkZVvhWN8,960
3
3
  fontTools/afmLib.py,sha256=YbmmjT8Du6qFUhFHwnAhOdvsyfXszODVjSJtd18CCjY,13603
4
4
  fontTools/agl.py,sha256=4aKwnbvSVUa39eV5Ka8e5ULwV-IEp4pcfwlMwEH_z3k,118208
@@ -7,11 +7,11 @@ fontTools/help.py,sha256=8yn5iAonGPsijFSHmU6aLuuZtaLMhR5CIkSp9hVYL2c,1161
7
7
  fontTools/tfmLib.py,sha256=-bv4iv2VhUSse5pA0oXdudf7o7ZuFWdWNsiHElO06dk,14730
8
8
  fontTools/ttx.py,sha256=CpfOtEVTXAv79XM2jiWKrOFXHFtWSyAniIgC7b9tWf8,17756
9
9
  fontTools/unicode.py,sha256=a7460sU25TnVYGzrVl0uv0lI_pDbANZp8Jfmqx9tAag,1287
10
- fontTools/cffLib/CFF2ToCFF.py,sha256=5uPKDFwoJvH0KVDrCjpf3MdOpqbyvdZMe0jZ3emjdsQ,6291
10
+ fontTools/cffLib/CFF2ToCFF.py,sha256=y-RJL8bbg6F1DPklI5xLUqfrjvjmByyx_l1XG_L1WRA,7657
11
11
  fontTools/cffLib/CFFToCFF2.py,sha256=0dCYSSozptUC9BVUre49e6LgjSxJRtVyMl8vDB6i3r4,10424
12
12
  fontTools/cffLib/__init__.py,sha256=E4wzLsJ1LxWO7CIR7fjZMHaYQJSVdqCO08fOVFowwpM,111580
13
13
  fontTools/cffLib/specializer.py,sha256=dznFa-7VrKZkx6D8klaixTaqEAnrnT6YLX9jzA6S0Cc,33536
14
- fontTools/cffLib/transforms.py,sha256=8hffhsWRhBhVukNSL-7ieuygTVV5Ta3Cz9s4s8Awvgg,17861
14
+ fontTools/cffLib/transforms.py,sha256=YvLBqogfYx_UsPKsU_WsOcS_ASeN3rwFzlow-lL2C6I,17950
15
15
  fontTools/cffLib/width.py,sha256=3L9NWI0uQrJHvHF_IvC_tbW1cq94zgDEPSjubdug8qM,6284
16
16
  fontTools/colorLib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  fontTools/colorLib/builder.py,sha256=S8z4Qzw2FAE-d1Zm1eHyqDBYh6FW4W_hQJWjVeVicOk,23672
@@ -24,7 +24,7 @@ fontTools/cu2qu/__init__.py,sha256=OoM_nBJAleZal6kxeNJn1ESy1pNm5c3DG417yVIE0-Q,6
24
24
  fontTools/cu2qu/__main__.py,sha256=6Vb8Ler3yqJ5w84UwlMJV6cS01uhV4PN10OlXQ6jlqo,98
25
25
  fontTools/cu2qu/benchmark.py,sha256=FwdvNjKfWHo18_CX0CO8AY5c68XSBE4M4TJo_EkB4q8,1350
26
26
  fontTools/cu2qu/cli.py,sha256=CvWzC5a6XF_v5o0yrS4vGI1JXiVVLzSJahTIqpJmiPk,6274
27
- fontTools/cu2qu/cu2qu.cp39-win32.pyd,sha256=WwSbRTJA11ZZUPw_WM7QpTsazL3DIXicZu6Et4sQaEg,88576
27
+ fontTools/cu2qu/cu2qu.cp39-win32.pyd,sha256=C-lqCegNkjZiYGbVnIFJwuekMyW9FWkrSnmG_Y4OnvA,87552
28
28
  fontTools/cu2qu/cu2qu.py,sha256=XH2bnQ5aG9ic921ZWzQzU1-q3MQU6INCjLk4XjRj5_Y,16970
29
29
  fontTools/cu2qu/errors.py,sha256=uYyPSs_x-EMJKO2S3cLGWyk_KlHoOoh_XEtdB_oKBp0,2518
30
30
  fontTools/cu2qu/ufo.py,sha256=Mpd_7Be9jxNcOKFqkyRp8Oem3CS3R-ZYMMSD03LJL6o,12143
@@ -40,9 +40,9 @@ fontTools/encodings/codecs.py,sha256=bSpO6kuPbEIDsXSVHhzftqsm_FFUiXpLVfPSk410SqE
40
40
  fontTools/feaLib/__init__.py,sha256=RprjP6BKswq4pt0J-9L1XGuZfjIFAGD6HDly_haMAN4,217
41
41
  fontTools/feaLib/__main__.py,sha256=niUAPkiYxeRAJMlJuvVJZism2VFufZrNaQtieA7sNLk,2318
42
42
  fontTools/feaLib/ast.py,sha256=q-UvEPZ97AAHpggVOzVHdgfTcE072kuOK08rdAYpCXU,76301
43
- fontTools/feaLib/builder.py,sha256=9f7v9Vfo0HkC6Pqj-hP4B6xj5GDIoV_XLCeDajmbI2g,74962
43
+ fontTools/feaLib/builder.py,sha256=JlxYFm1g99yi3XWZ2cTl_BmrnaB_YBZ-qWYN3VkhxbE,75324
44
44
  fontTools/feaLib/error.py,sha256=pqi8F2tnH2h7pXVffxwzuBuWaSHMzZsXs5VckdQKQAI,670
45
- fontTools/feaLib/lexer.cp39-win32.pyd,sha256=j3BGaqqEP1t2qbvNRWtyzhy5msMU4zdIiM7Nj7j0Qvw,110592
45
+ fontTools/feaLib/lexer.cp39-win32.pyd,sha256=D-DmQ-Ra6rZsWpPCXBzQx-POjfpIM7mg8ddBIagq6DA,109568
46
46
  fontTools/feaLib/lexer.py,sha256=7VZ3NPFH7V1mvRbym111BNKvbB4hLfGLTMS0VV_3Ipw,11408
47
47
  fontTools/feaLib/location.py,sha256=teHrhjT8zzImcGBEJS1J43oaX9onCPu_pynxS8d-tUg,246
48
48
  fontTools/feaLib/lookupDebugInfo.py,sha256=h4Ig8kmEk5WlGf1C9JJAbbOKQK5OwkFLdj8CT7fOkmU,316
@@ -59,7 +59,7 @@ fontTools/merge/unicode.py,sha256=mgqRFhRugda62Xt0r28SduaN7YBzRfHxrpNprjLqoX8,43
59
59
  fontTools/merge/util.py,sha256=3alo4b7mhFNC6h8PjeqNU99dS7EuO8sdZkZpvRsEE6E,3521
60
60
  fontTools/misc/__init__.py,sha256=QoK6HlOoqtVqX5gOyv0bJiTXsVBbBRreUifdccWNp2k,76
61
61
  fontTools/misc/arrayTools.py,sha256=baENNALPvYRUhS4rdx_F3ltOmVIf1PV9G2EaMt7gAHM,11907
62
- fontTools/misc/bezierTools.cp39-win32.pyd,sha256=jjzVd60uj419B_45NJ2PxMpUTu4W2M2_VjMh_TEm78g,317952
62
+ fontTools/misc/bezierTools.cp39-win32.pyd,sha256=WpNNzGAXTf17MGfj6CqB9ObE4ftmpmg5dn_eb51iCsY,317440
63
63
  fontTools/misc/bezierTools.py,sha256=m4j14ckKYtrKy8NhFFFY_Uv3kuL8g-SWNdEKUzqGjRQ,46535
64
64
  fontTools/misc/classifyTools.py,sha256=wLTjOhLiZaLiwwUTj2Ad5eZ5T_38W0Eo_uzRGWHWYvE,5783
65
65
  fontTools/misc/cliTools.py,sha256=7zKOXczaCKRMW6Yv5jdCZYHco8y0-lfimhIWzQ2IL8A,1915
@@ -77,7 +77,7 @@ fontTools/misc/lazyTools.py,sha256=LJ7QvDG65xOBw2AI43qGCLxVmfdbsf-PUECfrenbkAU,1
77
77
  fontTools/misc/loggingTools.py,sha256=27VatVrX8Yu-w5rFYSUjOnPLJIJ9Hx2R6hJ5YpP_djA,20476
78
78
  fontTools/misc/macCreatorType.py,sha256=5JZKTsnkI_VBhC52lwMSrdmzqgUOhwC42jPvbGahsPo,1649
79
79
  fontTools/misc/macRes.py,sha256=ewiYDKioxxBKW6JQcRmxpNYw5JgtJZIJyqWBG_KplUo,8840
80
- fontTools/misc/psCharStrings.py,sha256=e5kR55Gm3orJsDLo3eu6CxpoZ1pMNZh5Wm-Zj4m7wJs,44532
80
+ fontTools/misc/psCharStrings.py,sha256=T91YzpraGjZ3ChrM56t-KCoEuE79OvPq1tJA3qYywDU,44979
81
81
  fontTools/misc/psLib.py,sha256=cqxG8yMZ7_5VTxgTUl2ARNhIhNu_iTzxLTEd1Egwugo,12497
82
82
  fontTools/misc/psOperators.py,sha256=9nZ4ymbiiCApY9V8OARpYqvO73OEcJgGyTtCuGzD-rw,16272
83
83
  fontTools/misc/py23.py,sha256=BhByQabxZis6fDvK3ZVeI-YRj_1rMQeBZCFzGWIac0U,2334
@@ -127,7 +127,7 @@ fontTools/pens/explicitClosingLinePen.py,sha256=knCXcjSl2iPy6mLCDnsdDYx6J5rV7FH4
127
127
  fontTools/pens/filterPen.py,sha256=tWhgklyaCTUt7oQRTBbFUcOlc702V0NfadCH3X93CYg,8031
128
128
  fontTools/pens/freetypePen.py,sha256=NqNzXrOTDckoH4N6WLnj-KuxGcg6z7DlqSCfmpq8qAE,20370
129
129
  fontTools/pens/hashPointPen.py,sha256=ZAU87uw5ge3Kb4i9kRV28a5VFeZ_TWSsJabyAzwAHrU,3662
130
- fontTools/pens/momentsPen.cp39-win32.pyd,sha256=xyjSxO19cswmbUH_UEAJYpPrY0AkFWpb0UcaJL3OtL0,81920
130
+ fontTools/pens/momentsPen.cp39-win32.pyd,sha256=P1se1305s7ELIX2xqww0fOMUMtWFOwlNT_BfseT7HPk,81920
131
131
  fontTools/pens/momentsPen.py,sha256=Z-V5CjQBSj3qPxg3C_DBFKExqno89nOe3jWwHT9_xsM,26537
132
132
  fontTools/pens/perimeterPen.py,sha256=Zy5F8QzaNJAkkQQSb2QJCp-wZTvDAjBn-B099t2ABds,2222
133
133
  fontTools/pens/pointInsidePen.py,sha256=Hy48iR5NWV3x_wWoos-UC7GMtwvvUhd_q_ykiwaWdzQ,6547
@@ -150,7 +150,7 @@ fontTools/qu2cu/__init__.py,sha256=MpdE0XsHSDo9M3hyHLkPPLxB3FKr3aiT0dPW5qHCuSo,6
150
150
  fontTools/qu2cu/__main__.py,sha256=leKpToUNNyHf0nobr1I19vus2ziA1pO7rRKkreat-Xw,100
151
151
  fontTools/qu2cu/benchmark.py,sha256=PFxx2Bfu7-KuNrzdOIBXHPZvyNphqqcTVy4CneaCo3M,1456
152
152
  fontTools/qu2cu/cli.py,sha256=1QLBTSZW7e_VATJN9vjszRxIk_-Xjxu1KP53yX4T7q8,3839
153
- fontTools/qu2cu/qu2cu.cp39-win32.pyd,sha256=Lupr9yrC9fuJuBaWEWF8mdejrgR3lc1Tv7KfOh4im7M,97280
153
+ fontTools/qu2cu/qu2cu.cp39-win32.pyd,sha256=NHp0awkbr-utWt2DBAvzXKgT0a3Gb-aW14uxUek44W0,96768
154
154
  fontTools/qu2cu/qu2cu.py,sha256=dtp5Zqhcs_NePwA2U5fgG2LtWleRwmBilTurau8sLL0,12693
155
155
  fontTools/subset/__init__.py,sha256=cMUbkLDSaj0f576WF5zhbZ9mYT4U9b_PPzFFBpg8VEI,141636
156
156
  fontTools/subset/__main__.py,sha256=cEIC52EtGOJvFDfHXzi0M2EAYmyHAcI-ZZ0lb2y4r7s,101
@@ -243,11 +243,11 @@ fontTools/ttLib/tables/_f_v_a_r.py,sha256=hpxU0-u7_pZYDmQdKpmd_7c6BjVpXHdoQ97jKk
243
243
  fontTools/ttLib/tables/_g_a_s_p.py,sha256=Pr4X2CEg3a_nYAZrKSWT0auQ5HU2WutP1Shxxg7ALPw,2266
244
244
  fontTools/ttLib/tables/_g_c_i_d.py,sha256=diZlew4U8nFK5vimh-GMOjwHw8ccZtIEl9cPq0PrNdA,375
245
245
  fontTools/ttLib/tables/_g_l_y_f.py,sha256=gnZ1femTeEaFeWn4inLiWL0h8U9_iJ0CzU_6PDtFryk,87895
246
- fontTools/ttLib/tables/_g_v_a_r.py,sha256=bXLh4wXqtbL_hEmds5PXWJ5FTx58_1VojaqVvgesYH4,12412
246
+ fontTools/ttLib/tables/_g_v_a_r.py,sha256=3_uN_OGGLpEjLJKfEOBIMyt92NOXpKBoLymRkiMwzCQ,12536
247
247
  fontTools/ttLib/tables/_h_d_m_x.py,sha256=1dRbNSzHQlznrXqG0GtFYbGp_SzzgDcYfJqhSoS1FL8,4379
248
248
  fontTools/ttLib/tables/_h_e_a_d.py,sha256=ft9ghTA1NZsGBvB0yElFFCqVHecuCKGjT2m2GfYB3Yc,5056
249
249
  fontTools/ttLib/tables/_h_h_e_a.py,sha256=pY92ZLt3o0jZ3KQVd_qtxYtk_tbP2DLzSWm_wVP8FNM,4914
250
- fontTools/ttLib/tables/_h_m_t_x.py,sha256=p-9K-E3LcdJByagZ-0F0OA11pCVfNS9HtKRjbpvMM6I,6202
250
+ fontTools/ttLib/tables/_h_m_t_x.py,sha256=39O10q6zJNPGgoDbd5Ivli4-BpESP81ajtDOZy-xCHg,6356
251
251
  fontTools/ttLib/tables/_k_e_r_n.py,sha256=AjG5Fd6XaPAdXi5puDtLuMrfCsHUi9X7uFh76QGCMrc,11083
252
252
  fontTools/ttLib/tables/_l_c_a_r.py,sha256=N-1I6OJHvnF_YfGktyfFTRAG5lrExV7q6HX-0ffSRyQ,403
253
253
  fontTools/ttLib/tables/_l_o_c_a.py,sha256=MHRhxCcHbyK71lD3L91qNfYXD_rflSXsRa-YHDptCik,2250
@@ -300,7 +300,7 @@ fontTools/varLib/avarPlanner.py,sha256=orjyFvg3YkC-slt7fgSEU1AGjLCkGgMEJ7hTRV6Cq
300
300
  fontTools/varLib/builder.py,sha256=1k-N-rTwnZqQpzhNLBx2tqu2oYGG44sJSXKTCjAvIVM,6824
301
301
  fontTools/varLib/cff.py,sha256=bl8rrPHHpwzUdZBY80_5JJLWYcXQOolhKKvTJiiU-Bs,23532
302
302
  fontTools/varLib/errors.py,sha256=mXl-quT2Z75_t7Uwb6ug3VMhmbQjO841YNLeghwuY_s,7153
303
- fontTools/varLib/featureVars.py,sha256=fBt7iJtohfsfqO7AULmYMD56hb3apCDXRgpR18pDoG8,26390
303
+ fontTools/varLib/featureVars.py,sha256=cPiijbzRMZ0AiudBNPhF8XE1LoBr5VGkjiwpw5N0oKQ,26883
304
304
  fontTools/varLib/hvar.py,sha256=Tm0ibxOtSVrBQeHiA5-idUQaJEjzOdUWxAQyKTGsOdQ,3808
305
305
  fontTools/varLib/interpolatable.py,sha256=8AXrhsnYY1z0hR6gskqYRYx8qcFsvUKmIIHZRpIOlAU,46430
306
306
  fontTools/varLib/interpolatableHelpers.py,sha256=JnabttZY7sY9-QzdiqkgzQ_S5nG8k_O1TzLEmfNUvNo,11892
@@ -308,17 +308,17 @@ fontTools/varLib/interpolatablePlot.py,sha256=tUKFd8H9B2eD_GE6jV13J-dZkkIeLmk3oj
308
308
  fontTools/varLib/interpolatableTestContourOrder.py,sha256=Pbt0jW0LoVggIwrtADZ7HWK6Ftdoo1bjuWz0ost0HD0,3103
309
309
  fontTools/varLib/interpolatableTestStartingPoint.py,sha256=f5MJ3mj8MctJCvDJwqmW1fIVOgovUMYAOela9HweaRU,4403
310
310
  fontTools/varLib/interpolate_layout.py,sha256=tTPUes_K7MwooUO_wac9AeFEVgL1uGSz4ITYiOizaME,3813
311
- fontTools/varLib/iup.cp39-win32.pyd,sha256=nkmd-zYi_s2CcXf4XAfykn62_BOfqTrsORin8K78cPo,117248
311
+ fontTools/varLib/iup.cp39-win32.pyd,sha256=bqcBlx0hNv1aFJRc3CIHaygdO1gOOKgztau6cpV2IJ0,116736
312
312
  fontTools/varLib/iup.py,sha256=O_xPJOBECrNDbQqCC3e5xf9KsWXUd1i3BAp9Fl6Hv2Y,15474
313
313
  fontTools/varLib/merger.py,sha256=V-B17poOYbbrRsfUYJbdqt46GtRfG833MKwtv9NOB3Q,62519
314
314
  fontTools/varLib/models.py,sha256=ZqQb1Lapj5dCO8dwa3UTx1LsIpF0-GiDte32t_TMJJQ,23040
315
315
  fontTools/varLib/multiVarStore.py,sha256=OvrrTaKrCZCXP40Rrv-2w416P-dNz3xE6gPOEyS3PrY,8558
316
- fontTools/varLib/mutator.py,sha256=bUkUP27sxhEVkdljzbHNylHkj6Ob3FfQ9AoDYTRIwdo,19796
316
+ fontTools/varLib/mutator.py,sha256=0Mxy2ZSfFPEQrZM1fIHxZ17f0U_axLXArQ7apkjm0UI,20333
317
317
  fontTools/varLib/mvar.py,sha256=Gf3q54ICH-E9oAwKYeIKUPLZabfjY0bUT4t220zLzYI,2489
318
318
  fontTools/varLib/plot.py,sha256=BtozrcnKoEyCs0rGy7PZmrUvUNTmZT-5_sylW5PuJ28,7732
319
319
  fontTools/varLib/stat.py,sha256=ScaVFIVpXTqA-F07umv_66GoxtcjaZ54MPLFvFK4s68,4960
320
320
  fontTools/varLib/varStore.py,sha256=GWz-B1YcR-JnIh2aDmeQg621GDEBj9M4pKYcbZraA3w,24808
321
- fontTools/varLib/instancer/__init__.py,sha256=Dp4bxw_aOCdpECbQ4QPj8PujUzzpZAxQso4huWUx2J4,74220
321
+ fontTools/varLib/instancer/__init__.py,sha256=DHzuj_HRfNA6ELtCqBdCIdq5vjM1KE62ukZsZ-suJZc,76006
322
322
  fontTools/varLib/instancer/__main__.py,sha256=YN_tyJDdmLlH3umiLDS2ue0Zc3fSFexa9wCuk3Wuod0,109
323
323
  fontTools/varLib/instancer/featureVars.py,sha256=b3qtGCYVZ9fqkqcgFQUikYQBX_3_x0YgdrvvxIALbuU,7300
324
324
  fontTools/varLib/instancer/names.py,sha256=vmHi7JZlh-N4amxKdaTJ-5DN9mDJ8Wnh_s9W1gJAQ4Y,15338
@@ -330,11 +330,11 @@ fontTools/voltLib/error.py,sha256=3TsaZBA82acFd2j5Beq3WUQTURTKM0zxOnUFGZovSNA,40
330
330
  fontTools/voltLib/lexer.py,sha256=v9V4zdBO2VqVJG__IWrL8fv_CRURmh2eD_1UpbIJn9g,3467
331
331
  fontTools/voltLib/parser.py,sha256=HS72gxtFzvcPSwEbUYj3E41CPK7ZqK9mSe0nLRxn-IY,26060
332
332
  fontTools/voltLib/voltToFea.py,sha256=nS-OSlx_a-TngGICFNKyFxMhjqkV3OQLcvyzw4sQFyk,37460
333
- fonttools-4.59.0.data/data/share/man/man1/ttx.1,sha256=E71F9mRNWlttVpzlnP7w_fqkQygPkph5s-AtVa0Js50,5601
334
- fonttools-4.59.0.dist-info/licenses/LICENSE,sha256=Ir74Bpfs-qF_l-YrmibfoSggvgVYPo3RKtFpskEnTJk,1093
335
- fonttools-4.59.0.dist-info/licenses/LICENSE.external,sha256=sIKl-Gd1smQfAbzLi5yCkISB3l9QK7JUseE7_CqfMD0,20410
336
- fonttools-4.59.0.dist-info/METADATA,sha256=d4GOxfoHGPMLqZHqeziF_YonUyYjeJuRcCWQgCZg81s,110052
337
- fonttools-4.59.0.dist-info/WHEEL,sha256=Q3uEVTFw-CqGed7ywmQZcdvBC5FiRV941NvAhTjjkOQ,95
338
- fonttools-4.59.0.dist-info/entry_points.txt,sha256=8kVHddxfFWA44FSD4mBpmC-4uCynQnkoz_9aNJb227Y,147
339
- fonttools-4.59.0.dist-info/top_level.txt,sha256=rRgRylrXzekqWOsrhygzib12pQ7WILf7UGjqEwkIFDM,10
340
- fonttools-4.59.0.dist-info/RECORD,,
333
+ fonttools-4.59.1.data/data/share/man/man1/ttx.1,sha256=E71F9mRNWlttVpzlnP7w_fqkQygPkph5s-AtVa0Js50,5601
334
+ fonttools-4.59.1.dist-info/licenses/LICENSE,sha256=Ir74Bpfs-qF_l-YrmibfoSggvgVYPo3RKtFpskEnTJk,1093
335
+ fonttools-4.59.1.dist-info/licenses/LICENSE.external,sha256=sIKl-Gd1smQfAbzLi5yCkISB3l9QK7JUseE7_CqfMD0,20410
336
+ fonttools-4.59.1.dist-info/METADATA,sha256=w4dkM7l3YORuqe-It8OyLkQbUvr3HFOLfIt-KPDAifA,111107
337
+ fonttools-4.59.1.dist-info/WHEEL,sha256=Q3uEVTFw-CqGed7ywmQZcdvBC5FiRV941NvAhTjjkOQ,95
338
+ fonttools-4.59.1.dist-info/entry_points.txt,sha256=8kVHddxfFWA44FSD4mBpmC-4uCynQnkoz_9aNJb227Y,147
339
+ fonttools-4.59.1.dist-info/top_level.txt,sha256=rRgRylrXzekqWOsrhygzib12pQ7WILf7UGjqEwkIFDM,10
340
+ fonttools-4.59.1.dist-info/RECORD,,