fonttools 4.58.5__cp310-cp310-win_amd64.whl → 4.59.1__cp310-cp310-win_amd64.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 (67) hide show
  1. fontTools/__init__.py +1 -1
  2. fontTools/cffLib/CFF2ToCFF.py +40 -10
  3. fontTools/cffLib/transforms.py +11 -6
  4. fontTools/cu2qu/cu2qu.c +30 -16
  5. fontTools/cu2qu/cu2qu.cp310-win_amd64.pyd +0 -0
  6. fontTools/feaLib/builder.py +6 -1
  7. fontTools/feaLib/lexer.c +30 -16
  8. fontTools/feaLib/lexer.cp310-win_amd64.pyd +0 -0
  9. fontTools/merge/__init__.py +1 -1
  10. fontTools/misc/bezierTools.c +33 -19
  11. fontTools/misc/bezierTools.cp310-win_amd64.pyd +0 -0
  12. fontTools/misc/filesystem/__init__.py +68 -0
  13. fontTools/misc/filesystem/_base.py +134 -0
  14. fontTools/misc/filesystem/_copy.py +45 -0
  15. fontTools/misc/filesystem/_errors.py +54 -0
  16. fontTools/misc/filesystem/_info.py +75 -0
  17. fontTools/misc/filesystem/_osfs.py +164 -0
  18. fontTools/misc/filesystem/_path.py +67 -0
  19. fontTools/misc/filesystem/_subfs.py +92 -0
  20. fontTools/misc/filesystem/_tempfs.py +34 -0
  21. fontTools/misc/filesystem/_tools.py +34 -0
  22. fontTools/misc/filesystem/_walk.py +55 -0
  23. fontTools/misc/filesystem/_zipfs.py +204 -0
  24. fontTools/misc/psCharStrings.py +17 -2
  25. fontTools/misc/sstruct.py +2 -6
  26. fontTools/misc/xmlWriter.py +28 -1
  27. fontTools/pens/momentsPen.c +20 -14
  28. fontTools/pens/momentsPen.cp310-win_amd64.pyd +0 -0
  29. fontTools/pens/roundingPen.py +2 -2
  30. fontTools/qu2cu/qu2cu.c +32 -18
  31. fontTools/qu2cu/qu2cu.cp310-win_amd64.pyd +0 -0
  32. fontTools/subset/__init__.py +11 -11
  33. fontTools/ttLib/sfnt.py +2 -3
  34. fontTools/ttLib/tables/S__i_l_f.py +2 -2
  35. fontTools/ttLib/tables/T_S_I__1.py +2 -5
  36. fontTools/ttLib/tables/T_S_I__5.py +2 -2
  37. fontTools/ttLib/tables/_c_m_a_p.py +1 -1
  38. fontTools/ttLib/tables/_c_v_t.py +1 -2
  39. fontTools/ttLib/tables/_g_l_y_f.py +9 -10
  40. fontTools/ttLib/tables/_g_v_a_r.py +6 -3
  41. fontTools/ttLib/tables/_h_d_m_x.py +4 -4
  42. fontTools/ttLib/tables/_h_m_t_x.py +7 -3
  43. fontTools/ttLib/tables/_l_o_c_a.py +2 -2
  44. fontTools/ttLib/tables/_p_o_s_t.py +3 -4
  45. fontTools/ttLib/tables/otBase.py +2 -4
  46. fontTools/ttLib/tables/otTables.py +7 -12
  47. fontTools/ttLib/tables/sbixStrike.py +3 -3
  48. fontTools/ttLib/ttFont.py +7 -16
  49. fontTools/ttLib/woff2.py +10 -13
  50. fontTools/ufoLib/__init__.py +20 -25
  51. fontTools/ufoLib/glifLib.py +12 -17
  52. fontTools/ufoLib/validators.py +2 -4
  53. fontTools/unicodedata/__init__.py +2 -0
  54. fontTools/varLib/featureVars.py +8 -0
  55. fontTools/varLib/hvar.py +1 -1
  56. fontTools/varLib/instancer/__init__.py +65 -5
  57. fontTools/varLib/iup.c +32 -18
  58. fontTools/varLib/iup.cp310-win_amd64.pyd +0 -0
  59. fontTools/varLib/mutator.py +11 -0
  60. {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/METADATA +42 -12
  61. {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/RECORD +67 -55
  62. {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/licenses/LICENSE.external +29 -0
  63. {fonttools-4.58.5.data → fonttools-4.59.1.data}/data/share/man/man1/ttx.1 +0 -0
  64. {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/WHEEL +0 -0
  65. {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/entry_points.txt +0 -0
  66. {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/licenses/LICENSE +0 -0
  67. {fonttools-4.58.5.dist-info → fonttools-4.59.1.dist-info}/top_level.txt +0 -0
fontTools/qu2cu/qu2cu.c CHANGED
@@ -1,4 +1,4 @@
1
- /* Generated by Cython 3.1.2 */
1
+ /* Generated by Cython 3.1.3 */
2
2
 
3
3
  /* BEGIN: Cython Metadata
4
4
  {
@@ -32,8 +32,8 @@ END: Cython Metadata */
32
32
  #elif PY_VERSION_HEX < 0x03080000
33
33
  #error Cython requires Python 3.8+.
34
34
  #else
35
- #define __PYX_ABI_VERSION "3_1_2"
36
- #define CYTHON_HEX_VERSION 0x030102F0
35
+ #define __PYX_ABI_VERSION "3_1_3"
36
+ #define CYTHON_HEX_VERSION 0x030103F0
37
37
  #define CYTHON_FUTURE_DIVISION 1
38
38
  /* CModulePreamble */
39
39
  #include <stddef.h>
@@ -396,6 +396,9 @@ END: Cython Metadata */
396
396
  enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) };
397
397
  #endif
398
398
  #endif
399
+ #ifndef CYTHON_LOCK_AND_GIL_DEADLOCK_AVOIDANCE_TIME
400
+ #define CYTHON_LOCK_AND_GIL_DEADLOCK_AVOIDANCE_TIME 100
401
+ #endif
399
402
  #ifndef __has_attribute
400
403
  #define __has_attribute(x) 0
401
404
  #endif
@@ -1963,7 +1966,7 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject
1963
1966
  static PyObject *__Pyx_PyLong_AbsNeg(PyObject *num);
1964
1967
  #define __Pyx_PyNumber_Absolute(x)\
1965
1968
  ((likely(PyLong_CheckExact(x))) ?\
1966
- (likely(__Pyx_PyLong_IsNonNeg(x)) ? (Py_INCREF(x), (x)) : __Pyx_PyLong_AbsNeg(x)) :\
1969
+ (likely(__Pyx_PyLong_IsNonNeg(x)) ? __Pyx_NewRef(x) : __Pyx_PyLong_AbsNeg(x)) :\
1967
1970
  PyNumber_Absolute(x))
1968
1971
  #else
1969
1972
  #define __Pyx_PyNumber_Absolute(x) PyNumber_Absolute(x)
@@ -9028,16 +9031,15 @@ static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) {
9028
9031
  return -1;
9029
9032
  }
9030
9033
  /* #### Code section: init_codeobjects ### */
9031
- \
9032
- typedef struct {
9033
- unsigned int argcount : 3;
9034
- unsigned int num_posonly_args : 1;
9035
- unsigned int num_kwonly_args : 1;
9036
- unsigned int nlocals : 6;
9037
- unsigned int flags : 10;
9038
- unsigned int first_line : 9;
9039
- unsigned int line_table_length : 15;
9040
- } __Pyx_PyCode_New_function_description;
9034
+ typedef struct {
9035
+ unsigned int argcount : 3;
9036
+ unsigned int num_posonly_args : 1;
9037
+ unsigned int num_kwonly_args : 1;
9038
+ unsigned int nlocals : 6;
9039
+ unsigned int flags : 10;
9040
+ unsigned int first_line : 9;
9041
+ unsigned int line_table_length : 15;
9042
+ } __Pyx_PyCode_New_function_description;
9041
9043
  /* NewCodeObj.proto */
9042
9044
  static PyObject* __Pyx_PyCode_New(
9043
9045
  const __Pyx_PyCode_New_function_description descr,
@@ -10557,7 +10559,7 @@ static PyObject *__Pyx_PyLong_AbsNeg(PyObject *n) {
10557
10559
  PyObject *copy = _PyLong_Copy((PyLongObject*)n);
10558
10560
  if (likely(copy)) {
10559
10561
  #if PY_VERSION_HEX >= 0x030C00A7
10560
- ((PyLongObject*)copy)->long_value.lv_tag = ((PyLongObject*)copy)->long_value.lv_tag & ~_PyLong_SIGN_MASK;
10562
+ ((PyLongObject*)copy)->long_value.lv_tag ^= ((PyLongObject*)copy)->long_value.lv_tag & _PyLong_SIGN_MASK;
10561
10563
  #else
10562
10564
  __Pyx_SET_SIZE(copy, -Py_SIZE(copy));
10563
10565
  #endif
@@ -11193,6 +11195,13 @@ try_unpack:
11193
11195
 
11194
11196
  /* PyObjectCallMethod0 */
11195
11197
  static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) {
11198
+ #if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
11199
+ PyObject *args[1] = {obj};
11200
+ (void) __Pyx_PyObject_GetMethod;
11201
+ (void) __Pyx_PyObject_CallOneArg;
11202
+ (void) __Pyx_PyObject_CallNoArg;
11203
+ return PyObject_VectorcallMethod(method_name, args, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
11204
+ #else
11196
11205
  PyObject *method = NULL, *result = NULL;
11197
11206
  int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method);
11198
11207
  if (likely(is_method)) {
@@ -11205,6 +11214,7 @@ static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name
11205
11214
  Py_DECREF(method);
11206
11215
  bad:
11207
11216
  return result;
11217
+ #endif
11208
11218
  }
11209
11219
 
11210
11220
  /* CallUnboundCMethod0 */
@@ -11742,6 +11752,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
11742
11752
  changed = 1;
11743
11753
  }
11744
11754
  #endif // CYTHON_METH_FASTCALL
11755
+ #if !CYTHON_COMPILING_IN_PYPY
11745
11756
  else if (strcmp(memb->name, "__module__") == 0) {
11746
11757
  PyObject *descr;
11747
11758
  assert(memb->type == T_OBJECT);
@@ -11756,11 +11767,13 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
11756
11767
  }
11757
11768
  changed = 1;
11758
11769
  }
11770
+ #endif // !CYTHON_COMPILING_IN_PYPY
11759
11771
  }
11760
11772
  memb++;
11761
11773
  }
11762
11774
  }
11763
11775
  #endif // !CYTHON_COMPILING_IN_LIMITED_API
11776
+ #if !CYTHON_COMPILING_IN_PYPY
11764
11777
  slot = spec->slots;
11765
11778
  while (slot && slot->slot && slot->slot != Py_tp_getset)
11766
11779
  slot++;
@@ -11792,6 +11805,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
11792
11805
  ++getset;
11793
11806
  }
11794
11807
  }
11808
+ #endif // !CYTHON_COMPILING_IN_PYPY
11795
11809
  if (changed)
11796
11810
  PyType_Modified(type);
11797
11811
  #endif // PY_VERSION_HEX > 0x030900B1
@@ -12227,7 +12241,7 @@ bad:
12227
12241
  }
12228
12242
 
12229
12243
  /* CommonTypesMetaclass */
12230
- PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
12244
+ static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
12231
12245
  return PyUnicode_FromString(__PYX_ABI_MODULE_NAME);
12232
12246
  }
12233
12247
  static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = {
@@ -14847,7 +14861,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyOb
14847
14861
  }
14848
14862
 
14849
14863
  /* PyObjectCallMethod1 */
14850
- #if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000)
14864
+ #if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)))
14851
14865
  static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
14852
14866
  PyObject *result = __Pyx_PyObject_CallOneArg(method, arg);
14853
14867
  Py_DECREF(method);
@@ -14855,7 +14869,7 @@ static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
14855
14869
  }
14856
14870
  #endif
14857
14871
  static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
14858
- #if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000
14872
+ #if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
14859
14873
  PyObject *args[2] = {obj, arg};
14860
14874
  (void) __Pyx_PyObject_GetMethod;
14861
14875
  (void) __Pyx_PyObject_CallOneArg;
Binary file
@@ -27,16 +27,16 @@ from collections import Counter, defaultdict
27
27
  from functools import reduce
28
28
  from types import MethodType
29
29
 
30
- __usage__ = "pyftsubset font-file [glyph...] [--option=value]..."
30
+ __usage__ = "fonttools subset font-file [glyph...] [--option=value]..."
31
31
 
32
32
  __doc__ = (
33
33
  """\
34
- pyftsubset -- OpenType font subsetter and optimizer
34
+ fonttools subset -- OpenType font subsetter and optimizer
35
35
 
36
- pyftsubset is an OpenType font subsetter and optimizer, based on fontTools.
37
- It accepts any TT- or CFF-flavored OpenType (.otf or .ttf) or WOFF (.woff)
38
- font file. The subsetted glyph set is based on the specified glyphs
39
- or characters, and specified OpenType layout features.
36
+ fonttools subset is an OpenType font subsetter and optimizer, based on
37
+ fontTools. It accepts any TT- or CFF-flavored OpenType (.otf or .ttf)
38
+ or WOFF (.woff) font file. The subsetted glyph set is based on the
39
+ specified glyphs or characters, and specified OpenType layout features.
40
40
 
41
41
  The tool also performs some size-reducing optimizations, aimed for using
42
42
  subset fonts as webfonts. Individual optimizations can be enabled or
@@ -130,11 +130,11 @@ you might need to escape the question mark, like this: '--glyph-names\\?'.
130
130
 
131
131
  Examples::
132
132
 
133
- $ pyftsubset --glyph-names?
133
+ $ fonttools subset --glyph-names?
134
134
  Current setting for 'glyph-names' is: False
135
- $ pyftsubset --name-IDs=?
135
+ $ fonttools subset --name-IDs=?
136
136
  Current setting for 'name-IDs' is: [0, 1, 2, 3, 4, 5, 6]
137
- $ pyftsubset --hinting? --no-hinting --hinting?
137
+ $ fonttools subset --hinting? --no-hinting --hinting?
138
138
  Current setting for 'hinting' is: True
139
139
  Current setting for 'hinting' is: False
140
140
 
@@ -445,7 +445,7 @@ Example
445
445
  Produce a subset containing the characters ' !"#$%' without performing
446
446
  size-reducing optimizations::
447
447
 
448
- $ pyftsubset font.ttf --unicodes="U+0020-0025" \\
448
+ $ fonttools subset font.ttf --unicodes="U+0020-0025" \\
449
449
  --layout-features=* --glyph-names --symbol-cmap --legacy-cmap \\
450
450
  --notdef-glyph --notdef-outline --recommended-glyphs \\
451
451
  --name-IDs=* --name-legacy --name-languages=*
@@ -3768,7 +3768,7 @@ def parse_glyphs(s):
3768
3768
 
3769
3769
  def usage():
3770
3770
  print("usage:", __usage__, file=sys.stderr)
3771
- print("Try pyftsubset --help for more information.\n", file=sys.stderr)
3771
+ print("Try fonttools subset --help for more information.\n", file=sys.stderr)
3772
3772
 
3773
3773
 
3774
3774
  @timer("make one with everything (TOTAL TIME)")
fontTools/ttLib/sfnt.py CHANGED
@@ -375,10 +375,9 @@ class SFNTWriter(object):
375
375
 
376
376
  def _calcMasterChecksum(self, directory):
377
377
  # calculate checkSumAdjustment
378
- tags = list(self.tables.keys())
379
378
  checksums = []
380
- for i in range(len(tags)):
381
- checksums.append(self.tables[tags[i]].checkSum)
379
+ for tag in self.tables.keys():
380
+ checksums.append(self.tables[tag].checkSum)
382
381
 
383
382
  if self.DirectoryEntry != SFNTDirectoryEntry:
384
383
  # Create a SFNT directory for checksum calculation purposes
@@ -948,7 +948,7 @@ class Pass(object):
948
948
  writer.newline()
949
949
  writer.begintag("rules")
950
950
  writer.newline()
951
- for i in range(len(self.actions)):
951
+ for i, action in enumerate(self.actions):
952
952
  writer.begintag(
953
953
  "rule",
954
954
  index=i,
@@ -958,7 +958,7 @@ class Pass(object):
958
958
  writer.newline()
959
959
  if len(self.ruleConstraints[i]):
960
960
  writecode("constraint", writer, self.ruleConstraints[i])
961
- writecode("action", writer, self.actions[i])
961
+ writecode("action", writer, action)
962
962
  writer.endtag("rule")
963
963
  writer.newline()
964
964
  writer.endtag("rules")
@@ -91,12 +91,11 @@ class table_T_S_I__1(LogMixin, DefaultTable.DefaultTable):
91
91
  glyphNames = ttFont.getGlyphOrder()
92
92
 
93
93
  indices = []
94
- for i in range(len(glyphNames)):
94
+ for i, name in enumerate(glyphNames):
95
95
  if len(data) % 2:
96
96
  data = (
97
97
  data + b"\015"
98
98
  ) # align on 2-byte boundaries, fill with return chars. Yum.
99
- name = glyphNames[i]
100
99
  if name in self.glyphPrograms:
101
100
  text = tobytes(self.glyphPrograms[name], encoding="utf-8")
102
101
  else:
@@ -108,13 +107,11 @@ class table_T_S_I__1(LogMixin, DefaultTable.DefaultTable):
108
107
  data = data + text
109
108
 
110
109
  extra_indices = []
111
- codes = sorted(self.extras.items())
112
- for i in range(len(codes)):
110
+ for code, name in sorted(self.extras.items()):
113
111
  if len(data) % 2:
114
112
  data = (
115
113
  data + b"\015"
116
114
  ) # align on 2-byte boundaries, fill with return chars.
117
- code, name = codes[i]
118
115
  if name in self.extraPrograms:
119
116
  text = tobytes(self.extraPrograms[name], encoding="utf-8")
120
117
  else:
@@ -38,8 +38,8 @@ class table_T_S_I__5(DefaultTable.DefaultTable):
38
38
  def compile(self, ttFont):
39
39
  glyphNames = ttFont.getGlyphOrder()
40
40
  a = array.array("H")
41
- for i in range(len(glyphNames)):
42
- a.append(self.glyphGrouping.get(glyphNames[i], 0))
41
+ for glyphName in glyphNames:
42
+ a.append(self.glyphGrouping.get(glyphName, 0))
43
43
  if sys.byteorder != "big":
44
44
  a.byteswap()
45
45
  return a.tobytes()
@@ -398,7 +398,7 @@ class cmap_format_0(CmapSubtable):
398
398
  assert 262 == self.length, "Format 0 cmap subtable not 262 bytes"
399
399
  gids = array.array("B")
400
400
  gids.frombytes(self.data)
401
- charCodes = list(range(len(gids)))
401
+ charCodes = range(len(gids))
402
402
  self.cmap = _make_map(self.ttFont, charCodes, gids)
403
403
 
404
404
  def compile(self, ttFont):
@@ -29,8 +29,7 @@ class table__c_v_t(DefaultTable.DefaultTable):
29
29
  return values.tobytes()
30
30
 
31
31
  def toXML(self, writer, ttFont):
32
- for i in range(len(self.values)):
33
- value = self.values[i]
32
+ for i, value in enumerate(self.values):
34
33
  writer.simpletag("cv", value=value, index=i)
35
34
  writer.newline()
36
35
 
@@ -974,11 +974,10 @@ class Glyph(object):
974
974
  lastcomponent = len(self.components) - 1
975
975
  more = 1
976
976
  haveInstructions = 0
977
- for i in range(len(self.components)):
977
+ for i, compo in enumerate(self.components):
978
978
  if i == lastcomponent:
979
979
  haveInstructions = hasattr(self, "program")
980
980
  more = 0
981
- compo = self.components[i]
982
981
  data = data + compo.compile(more, haveInstructions, glyfTable)
983
982
  if haveInstructions:
984
983
  instructions = self.program.getBytecode()
@@ -2037,8 +2036,8 @@ class GlyphCoordinates(object):
2037
2036
  if round is noRound:
2038
2037
  return
2039
2038
  a = self._a
2040
- for i in range(len(a)):
2041
- a[i] = round(a[i])
2039
+ for i, value in enumerate(a):
2040
+ a[i] = round(value)
2042
2041
 
2043
2042
  def calcBounds(self):
2044
2043
  a = self._a
@@ -2168,8 +2167,8 @@ class GlyphCoordinates(object):
2168
2167
  """
2169
2168
  r = self.copy()
2170
2169
  a = r._a
2171
- for i in range(len(a)):
2172
- a[i] = -a[i]
2170
+ for i, value in enumerate(a):
2171
+ a[i] = -value
2173
2172
  return r
2174
2173
 
2175
2174
  def __round__(self, *, round=otRound):
@@ -2214,8 +2213,8 @@ class GlyphCoordinates(object):
2214
2213
  other = other._a
2215
2214
  a = self._a
2216
2215
  assert len(a) == len(other)
2217
- for i in range(len(a)):
2218
- a[i] += other[i]
2216
+ for i, value in enumerate(other):
2217
+ a[i] += value
2219
2218
  return self
2220
2219
  return NotImplemented
2221
2220
 
@@ -2238,8 +2237,8 @@ class GlyphCoordinates(object):
2238
2237
  other = other._a
2239
2238
  a = self._a
2240
2239
  assert len(a) == len(other)
2241
- for i in range(len(a)):
2242
- a[i] -= other[i]
2240
+ for i, value in enumerate(other):
2241
+ a[i] -= value
2243
2242
  return self
2244
2243
  return NotImplemented
2245
2244
 
@@ -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
  )
@@ -65,8 +65,8 @@ class table__h_d_m_x(DefaultTable.DefaultTable):
65
65
  items = sorted(self.hdmx.items())
66
66
  for ppem, widths in items:
67
67
  data = data + bytechr(ppem) + bytechr(max(widths.values()))
68
- for glyphID in range(len(glyphOrder)):
69
- width = widths[glyphOrder[glyphID]]
68
+ for glyphName in glyphOrder:
69
+ width = widths[glyphName]
70
70
  data = data + bytechr(width)
71
71
  data = data + pad
72
72
  return data
@@ -123,5 +123,5 @@ class table__h_d_m_x(DefaultTable.DefaultTable):
123
123
  glyphName = safeEval('"""' + glyphName + '"""')
124
124
  line = list(map(int, line[1:]))
125
125
  assert len(line) == len(ppems), "illegal hdmx format"
126
- for i in range(len(ppems)):
127
- hdmx[ppems[i]][glyphName] = line[i]
126
+ for i, ppem in enumerate(ppems):
127
+ hdmx[ppem][glyphName] = line[i]
@@ -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
 
@@ -46,8 +46,8 @@ class table__l_o_c_a(DefaultTable.DefaultTable):
46
46
  max_location = 0
47
47
  if max_location < 0x20000 and all(l % 2 == 0 for l in self.locations):
48
48
  locations = array.array("H")
49
- for i in range(len(self.locations)):
50
- locations.append(self.locations[i] // 2)
49
+ for location in self.locations:
50
+ locations.append(location // 2)
51
51
  ttFont["head"].indexToLocFormat = 0
52
52
  else:
53
53
  locations = array.array("I", self.locations)
@@ -174,10 +174,9 @@ class table__p_o_s_t(DefaultTable.DefaultTable):
174
174
  extraNames = self.extraNames = [
175
175
  n for n in self.extraNames if n not in standardGlyphOrder
176
176
  ]
177
- for i in range(len(extraNames)):
178
- extraDict[extraNames[i]] = i
179
- for glyphID in range(numGlyphs):
180
- glyphName = glyphOrder[glyphID]
177
+ for i, name in enumerate(extraNames):
178
+ extraDict[name] = i
179
+ for glyphName in glyphOrder:
181
180
  if glyphName in self.mapping:
182
181
  psName = self.mapping[glyphName]
183
182
  else:
@@ -500,8 +500,7 @@ class OTTableWriter(object):
500
500
  internedTables = {}
501
501
 
502
502
  items = self.items
503
- for i in range(len(items)):
504
- item = items[i]
503
+ for i, item in enumerate(items):
505
504
  if hasattr(item, "getCountData"):
506
505
  items[i] = item.getCountData()
507
506
  elif hasattr(item, "subWriter"):
@@ -1130,8 +1129,7 @@ class BaseTable(object):
1130
1129
  for conv in self.getConverters():
1131
1130
  if conv.repeat:
1132
1131
  value = getattr(self, conv.name, [])
1133
- for i in range(len(value)):
1134
- item = value[i]
1132
+ for i, item in enumerate(value):
1135
1133
  conv.xmlWrite(xmlWriter, font, item, conv.name, [("index", i)])
1136
1134
  else:
1137
1135
  if conv.aux and not eval(conv.aux, None, vars(self)):
@@ -990,8 +990,7 @@ class Coverage(FormatSwitchingBaseTable):
990
990
  if brokenOrder or len(ranges) * 3 < len(glyphs): # 3 words vs. 1 word
991
991
  # Format 2 is more compact
992
992
  index = 0
993
- for i in range(len(ranges)):
994
- start, end = ranges[i]
993
+ for i, (start, end) in enumerate(ranges):
995
994
  r = RangeRecord()
996
995
  r.StartID = start
997
996
  r.Start = font.getGlyphName(start)
@@ -1404,8 +1403,7 @@ class ClassDef(FormatSwitchingBaseTable):
1404
1403
  glyphCount = endGlyph - startGlyph + 1
1405
1404
  if len(ranges) * 3 < glyphCount + 1:
1406
1405
  # Format 2 is more compact
1407
- for i in range(len(ranges)):
1408
- cls, start, startName, end, endName = ranges[i]
1406
+ for i, (cls, start, startName, end, endName) in enumerate(ranges):
1409
1407
  rec = ClassRangeRecord()
1410
1408
  rec.Start = startName
1411
1409
  rec.End = endName
@@ -1463,8 +1461,7 @@ class AlternateSubst(FormatSwitchingBaseTable):
1463
1461
  if alternates is None:
1464
1462
  alternates = self.alternates = {}
1465
1463
  items = list(alternates.items())
1466
- for i in range(len(items)):
1467
- glyphName, set = items[i]
1464
+ for i, (glyphName, set) in enumerate(items):
1468
1465
  items[i] = font.getGlyphID(glyphName), glyphName, set
1469
1466
  items.sort()
1470
1467
  cov = Coverage()
@@ -1520,8 +1517,8 @@ class LigatureSubst(FormatSwitchingBaseTable):
1520
1517
  input = _getGlyphsFromCoverageTable(rawTable["Coverage"])
1521
1518
  ligSets = rawTable["LigatureSet"]
1522
1519
  assert len(input) == len(ligSets)
1523
- for i in range(len(input)):
1524
- ligatures[input[i]] = ligSets[i].Ligature
1520
+ for i, inp in enumerate(input):
1521
+ ligatures[inp] = ligSets[i].Ligature
1525
1522
  else:
1526
1523
  assert 0, "unknown format: %s" % self.Format
1527
1524
  self.ligatures = ligatures
@@ -1577,8 +1574,7 @@ class LigatureSubst(FormatSwitchingBaseTable):
1577
1574
  ligatures = newLigatures
1578
1575
 
1579
1576
  items = list(ligatures.items())
1580
- for i in range(len(items)):
1581
- glyphName, set = items[i]
1577
+ for i, (glyphName, set) in enumerate(items):
1582
1578
  items[i] = font.getGlyphID(glyphName), glyphName, set
1583
1579
  items.sort()
1584
1580
  cov = Coverage()
@@ -2279,8 +2275,7 @@ def fixLookupOverFlows(ttf, overflowRecord):
2279
2275
  lookup = lookups[lookupIndex]
2280
2276
  if lookup.LookupType != extType:
2281
2277
  lookup.LookupType = extType
2282
- for si in range(len(lookup.SubTable)):
2283
- subTable = lookup.SubTable[si]
2278
+ for si, subTable in enumerate(lookup.SubTable):
2284
2279
  extSubTableClass = lookupTypes[overflowRecord.tableType][extType]
2285
2280
  extSubTable = extSubTableClass()
2286
2281
  extSubTable.Format = 1
@@ -128,9 +128,9 @@ class Strike(object):
128
128
  xmlWriter.simpletag("resolution", value=self.resolution)
129
129
  xmlWriter.newline()
130
130
  glyphOrder = ttFont.getGlyphOrder()
131
- for i in range(len(glyphOrder)):
132
- if glyphOrder[i] in self.glyphs:
133
- self.glyphs[glyphOrder[i]].toXML(xmlWriter, ttFont)
131
+ for glyphName in glyphOrder:
132
+ if glyphName in self.glyphs:
133
+ self.glyphs[glyphName].toXML(xmlWriter, ttFont)
134
134
  # TODO: what if there are more glyph data records than (glyf table) glyphs?
135
135
  xmlWriter.endtag("strike")
136
136
  xmlWriter.newline()
fontTools/ttLib/ttFont.py CHANGED
@@ -259,9 +259,8 @@ class TTFont(object):
259
259
  "head"
260
260
  ] # make sure 'head' is loaded so the recalculation is actually done
261
261
 
262
- tags = list(self.keys())
263
- if "GlyphOrder" in tags:
264
- tags.remove("GlyphOrder")
262
+ tags = self.keys()
263
+ tags.pop(0) # skip GlyphOrder tag
265
264
  numTables = len(tags)
266
265
  # write to a temporary stream to allow saving to unseekable streams
267
266
  writer = SFNTWriter(
@@ -307,14 +306,9 @@ class TTFont(object):
307
306
  self.disassembleInstructions = disassembleInstructions
308
307
  self.bitmapGlyphDataFormat = bitmapGlyphDataFormat
309
308
  if not tables:
310
- tables = list(self.keys())
311
- if "GlyphOrder" not in tables:
312
- tables = ["GlyphOrder"] + tables
309
+ tables = self.keys()
313
310
  if skipTables:
314
- for tag in skipTables:
315
- if tag in tables:
316
- tables.remove(tag)
317
- numTables = len(tables)
311
+ tables = [tag for tag in tables if tag not in skipTables]
318
312
 
319
313
  if writeVersion:
320
314
  from fontTools import version
@@ -337,8 +331,7 @@ class TTFont(object):
337
331
  else:
338
332
  path, ext = os.path.splitext(writer.filename)
339
333
 
340
- for i in range(numTables):
341
- tag = tables[i]
334
+ for tag in tables:
342
335
  if splitTables:
343
336
  tablePath = path + "." + tagToIdentifier(tag) + ext
344
337
  tableWriter = xmlWriter.XMLWriter(
@@ -608,8 +601,7 @@ class TTFont(object):
608
601
  else:
609
602
  reversecmap = {}
610
603
  useCount = {}
611
- for i in range(numGlyphs):
612
- tempName = glyphOrder[i]
604
+ for i, tempName in enumerate(glyphOrder):
613
605
  if tempName in reversecmap:
614
606
  # If a font maps both U+0041 LATIN CAPITAL LETTER A and
615
607
  # U+0391 GREEK CAPITAL LETTER ALPHA to the same glyph,
@@ -866,8 +858,7 @@ class GlyphOrder(object):
866
858
  "The 'id' attribute is only for humans; " "it is ignored when parsed."
867
859
  )
868
860
  writer.newline()
869
- for i in range(len(glyphOrder)):
870
- glyphName = glyphOrder[i]
861
+ for i, glyphName in enumerate(glyphOrder):
871
862
  writer.simpletag("GlyphID", id=i, name=glyphName)
872
863
  writer.newline()
873
864