fonttools 4.59.0__cp312-cp312-win_amd64.whl → 4.59.2__cp312-cp312-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 (38) 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 +760 -653
  5. fontTools/cu2qu/cu2qu.cp312-win_amd64.pyd +0 -0
  6. fontTools/cu2qu/cu2qu.py +17 -2
  7. fontTools/feaLib/builder.py +15 -4
  8. fontTools/feaLib/lexer.c +30 -16
  9. fontTools/feaLib/lexer.cp312-win_amd64.pyd +0 -0
  10. fontTools/feaLib/parser.py +11 -1
  11. fontTools/feaLib/variableScalar.py +6 -1
  12. fontTools/misc/bezierTools.c +33 -19
  13. fontTools/misc/bezierTools.cp312-win_amd64.pyd +0 -0
  14. fontTools/misc/psCharStrings.py +17 -2
  15. fontTools/misc/textTools.py +4 -2
  16. fontTools/pens/momentsPen.c +20 -14
  17. fontTools/pens/momentsPen.cp312-win_amd64.pyd +0 -0
  18. fontTools/qu2cu/qu2cu.c +32 -18
  19. fontTools/qu2cu/qu2cu.cp312-win_amd64.pyd +0 -0
  20. fontTools/subset/__init__.py +1 -0
  21. fontTools/ttLib/tables/_a_v_a_r.py +4 -2
  22. fontTools/ttLib/tables/_g_v_a_r.py +6 -3
  23. fontTools/ttLib/tables/_h_m_t_x.py +7 -3
  24. fontTools/ttLib/tables/_n_a_m_e.py +11 -6
  25. fontTools/varLib/__init__.py +80 -1
  26. fontTools/varLib/featureVars.py +8 -0
  27. fontTools/varLib/instancer/__init__.py +120 -22
  28. fontTools/varLib/iup.c +32 -18
  29. fontTools/varLib/iup.cp312-win_amd64.pyd +0 -0
  30. fontTools/varLib/mutator.py +11 -0
  31. {fonttools-4.59.0.dist-info → fonttools-4.59.2.dist-info}/METADATA +38 -10
  32. {fonttools-4.59.0.dist-info → fonttools-4.59.2.dist-info}/RECORD +38 -38
  33. {fonttools-4.59.0.data → fonttools-4.59.2.data}/data/share/man/man1/ttx.1 +0 -0
  34. {fonttools-4.59.0.dist-info → fonttools-4.59.2.dist-info}/WHEEL +0 -0
  35. {fonttools-4.59.0.dist-info → fonttools-4.59.2.dist-info}/entry_points.txt +0 -0
  36. {fonttools-4.59.0.dist-info → fonttools-4.59.2.dist-info}/licenses/LICENSE +0 -0
  37. {fonttools-4.59.0.dist-info → fonttools-4.59.2.dist-info}/licenses/LICENSE.external +0 -0
  38. {fonttools-4.59.0.dist-info → fonttools-4.59.2.dist-info}/top_level.txt +0 -0
Binary file
fontTools/cu2qu/cu2qu.py CHANGED
@@ -37,7 +37,7 @@ NAN = float("NaN")
37
37
  @cython.cfunc
38
38
  @cython.inline
39
39
  @cython.returns(cython.double)
40
- @cython.locals(v1=cython.complex, v2=cython.complex)
40
+ @cython.locals(v1=cython.complex, v2=cython.complex, result=cython.double)
41
41
  def dot(v1, v2):
42
42
  """Return the dot product of two vectors.
43
43
 
@@ -48,7 +48,16 @@ def dot(v1, v2):
48
48
  Returns:
49
49
  double: Dot product.
50
50
  """
51
- return (v1 * v2.conjugate()).real
51
+ result = (v1 * v2.conjugate()).real
52
+ # When vectors are perpendicular (i.e. dot product is 0), the above expression may
53
+ # yield slightly different results when running in pure Python vs C/Cython,
54
+ # both of which are correct within IEEE-754 floating-point precision.
55
+ # It's probably due to the different order of operations and roundings in each
56
+ # implementation. Because we are using the result in a denominator and catching
57
+ # ZeroDivisionError (see `calc_intersect`), it's best to normalize the result here.
58
+ if abs(result) < 1e-15:
59
+ result = 0.0
60
+ return result
52
61
 
53
62
 
54
63
  @cython.cfunc
@@ -273,6 +282,12 @@ def calc_intersect(a, b, c, d):
273
282
  try:
274
283
  h = dot(p, a - c) / dot(p, cd)
275
284
  except ZeroDivisionError:
285
+ # if 3 or 4 points are equal, we do have an intersection despite the zero-div:
286
+ # return one of the off-curves so that the algorithm can attempt a one-curve
287
+ # solution if it's within tolerance:
288
+ # https://github.com/linebender/kurbo/pull/484
289
+ if b == c and (a == b or c == d):
290
+ return b
276
291
  return complex(NAN, NAN)
277
292
  return c + cd * h
278
293
 
@@ -32,6 +32,7 @@ from fontTools.otlLib.builder import (
32
32
  AnySubstBuilder,
33
33
  )
34
34
  from fontTools.otlLib.error import OpenTypeLibError
35
+ from fontTools.varLib.errors import VarLibError
35
36
  from fontTools.varLib.varStore import OnlineVarStoreBuilder
36
37
  from fontTools.varLib.builder import buildVarDevTable
37
38
  from fontTools.varLib.featureVars import addFeatureVariationsRaw
@@ -926,6 +927,11 @@ class Builder(object):
926
927
  l.lookup_index for l in lookups if l.lookup_index is not None
927
928
  )
928
929
  )
930
+ # order doesn't matter, but lookup_indices preserves it.
931
+ # We want to combine identical sets of lookups (order doesn't matter)
932
+ # but also respect the order provided by the user (although there's
933
+ # a reasonable argument to just sort and dedupe, which fontc does)
934
+ lookup_key = frozenset(lookup_indices)
929
935
 
930
936
  size_feature = tag == "GPOS" and feature_tag == "size"
931
937
  force_feature = self.any_feature_variations(feature_tag, tag)
@@ -943,7 +949,7 @@ class Builder(object):
943
949
  "stash debug information. See fonttools#2065."
944
950
  )
945
951
 
946
- feature_key = (feature_tag, lookup_indices)
952
+ feature_key = (feature_tag, lookup_key)
947
953
  feature_index = feature_indices.get(feature_key)
948
954
  if feature_index is None:
949
955
  feature_index = len(table.FeatureList.FeatureRecord)
@@ -1723,9 +1729,14 @@ class Builder(object):
1723
1729
  if not varscalar.does_vary:
1724
1730
  return varscalar.default, None
1725
1731
 
1726
- default, index = varscalar.add_to_variation_store(
1727
- self.varstorebuilder, self.model_cache, self.font.get("avar")
1728
- )
1732
+ try:
1733
+ default, index = varscalar.add_to_variation_store(
1734
+ self.varstorebuilder, self.model_cache, self.font.get("avar")
1735
+ )
1736
+ except VarLibError as e:
1737
+ raise FeatureLibError(
1738
+ "Failed to compute deltas for variable scalar", location
1739
+ ) from e
1729
1740
 
1730
1741
  device = None
1731
1742
  if index is not None and index != 0xFFFFFFFF:
fontTools/feaLib/lexer.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
  {
@@ -26,8 +26,8 @@ END: Cython Metadata */
26
26
  #elif PY_VERSION_HEX < 0x03080000
27
27
  #error Cython requires Python 3.8+.
28
28
  #else
29
- #define __PYX_ABI_VERSION "3_1_2"
30
- #define CYTHON_HEX_VERSION 0x030102F0
29
+ #define __PYX_ABI_VERSION "3_1_3"
30
+ #define CYTHON_HEX_VERSION 0x030103F0
31
31
  #define CYTHON_FUTURE_DIVISION 1
32
32
  /* CModulePreamble */
33
33
  #include <stddef.h>
@@ -390,6 +390,9 @@ END: Cython Metadata */
390
390
  enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) };
391
391
  #endif
392
392
  #endif
393
+ #ifndef CYTHON_LOCK_AND_GIL_DEADLOCK_AVOIDANCE_TIME
394
+ #define CYTHON_LOCK_AND_GIL_DEADLOCK_AVOIDANCE_TIME 100
395
+ #endif
393
396
  #ifndef __has_attribute
394
397
  #define __has_attribute(x) 0
395
398
  #endif
@@ -10822,16 +10825,15 @@ static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) {
10822
10825
  return -1;
10823
10826
  }
10824
10827
  /* #### Code section: init_codeobjects ### */
10825
- \
10826
- typedef struct {
10827
- unsigned int argcount : 2;
10828
- unsigned int num_posonly_args : 1;
10829
- unsigned int num_kwonly_args : 1;
10830
- unsigned int nlocals : 4;
10831
- unsigned int flags : 10;
10832
- unsigned int first_line : 9;
10833
- unsigned int line_table_length : 15;
10834
- } __Pyx_PyCode_New_function_description;
10828
+ typedef struct {
10829
+ unsigned int argcount : 2;
10830
+ unsigned int num_posonly_args : 1;
10831
+ unsigned int num_kwonly_args : 1;
10832
+ unsigned int nlocals : 4;
10833
+ unsigned int flags : 10;
10834
+ unsigned int first_line : 9;
10835
+ unsigned int line_table_length : 15;
10836
+ } __Pyx_PyCode_New_function_description;
10835
10837
  /* NewCodeObj.proto */
10836
10838
  static PyObject* __Pyx_PyCode_New(
10837
10839
  const __Pyx_PyCode_New_function_description descr,
@@ -13414,6 +13416,13 @@ try_unpack:
13414
13416
 
13415
13417
  /* PyObjectCallMethod0 */
13416
13418
  static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) {
13419
+ #if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
13420
+ PyObject *args[1] = {obj};
13421
+ (void) __Pyx_PyObject_GetMethod;
13422
+ (void) __Pyx_PyObject_CallOneArg;
13423
+ (void) __Pyx_PyObject_CallNoArg;
13424
+ return PyObject_VectorcallMethod(method_name, args, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
13425
+ #else
13417
13426
  PyObject *method = NULL, *result = NULL;
13418
13427
  int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method);
13419
13428
  if (likely(is_method)) {
@@ -13426,6 +13435,7 @@ static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name
13426
13435
  Py_DECREF(method);
13427
13436
  bad:
13428
13437
  return result;
13438
+ #endif
13429
13439
  }
13430
13440
 
13431
13441
  /* CallUnboundCMethod0 */
@@ -13493,7 +13503,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyOb
13493
13503
  }
13494
13504
 
13495
13505
  /* PyObjectCallMethod1 */
13496
- #if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000)
13506
+ #if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)))
13497
13507
  static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
13498
13508
  PyObject *result = __Pyx_PyObject_CallOneArg(method, arg);
13499
13509
  Py_DECREF(method);
@@ -13501,7 +13511,7 @@ static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
13501
13511
  }
13502
13512
  #endif
13503
13513
  static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
13504
- #if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000
13514
+ #if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
13505
13515
  PyObject *args[2] = {obj, arg};
13506
13516
  (void) __Pyx_PyObject_GetMethod;
13507
13517
  (void) __Pyx_PyObject_CallOneArg;
@@ -14087,6 +14097,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
14087
14097
  changed = 1;
14088
14098
  }
14089
14099
  #endif // CYTHON_METH_FASTCALL
14100
+ #if !CYTHON_COMPILING_IN_PYPY
14090
14101
  else if (strcmp(memb->name, "__module__") == 0) {
14091
14102
  PyObject *descr;
14092
14103
  assert(memb->type == T_OBJECT);
@@ -14101,11 +14112,13 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
14101
14112
  }
14102
14113
  changed = 1;
14103
14114
  }
14115
+ #endif // !CYTHON_COMPILING_IN_PYPY
14104
14116
  }
14105
14117
  memb++;
14106
14118
  }
14107
14119
  }
14108
14120
  #endif // !CYTHON_COMPILING_IN_LIMITED_API
14121
+ #if !CYTHON_COMPILING_IN_PYPY
14109
14122
  slot = spec->slots;
14110
14123
  while (slot && slot->slot && slot->slot != Py_tp_getset)
14111
14124
  slot++;
@@ -14137,6 +14150,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
14137
14150
  ++getset;
14138
14151
  }
14139
14152
  }
14153
+ #endif // !CYTHON_COMPILING_IN_PYPY
14140
14154
  if (changed)
14141
14155
  PyType_Modified(type);
14142
14156
  #endif // PY_VERSION_HEX > 0x030900B1
@@ -14269,7 +14283,7 @@ bad:
14269
14283
  }
14270
14284
 
14271
14285
  /* CommonTypesMetaclass */
14272
- PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
14286
+ static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
14273
14287
  return PyUnicode_FromString(__PYX_ABI_MODULE_NAME);
14274
14288
  }
14275
14289
  static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = {
Binary file
@@ -2198,7 +2198,7 @@ class Parser(object):
2198
2198
  raise FeatureLibError(
2199
2199
  "Expected an equals sign", self.cur_token_location_
2200
2200
  )
2201
- value = self.expect_number_()
2201
+ value = self.expect_integer_or_float_()
2202
2202
  location[axis] = value
2203
2203
  if self.next_token_type_ is Lexer.NAME and self.next_token_[0] == ":":
2204
2204
  # Lexer has just read the value as a glyph name. We'll correct it later
@@ -2230,6 +2230,16 @@ class Parser(object):
2230
2230
  "Expected a floating-point number", self.cur_token_location_
2231
2231
  )
2232
2232
 
2233
+ def expect_integer_or_float_(self):
2234
+ if self.next_token_type_ == Lexer.FLOAT:
2235
+ return self.expect_float_()
2236
+ elif self.next_token_type_ is Lexer.NUMBER:
2237
+ return self.expect_number_()
2238
+ else:
2239
+ raise FeatureLibError(
2240
+ "Expected an integer or floating-point number", self.cur_token_location_
2241
+ )
2242
+
2233
2243
  def expect_decipoint_(self):
2234
2244
  if self.next_token_type_ == Lexer.FLOAT:
2235
2245
  return self.expect_float_()
@@ -17,7 +17,12 @@ class VariableScalar:
17
17
  def __repr__(self):
18
18
  items = []
19
19
  for location, value in self.values.items():
20
- loc = ",".join(["%s=%i" % (ax, loc) for ax, loc in location])
20
+ loc = ",".join(
21
+ [
22
+ f"{ax}={int(coord) if float(coord).is_integer() else coord}"
23
+ for ax, coord in location
24
+ ]
25
+ )
21
26
  items.append("%s:%i" % (loc, value))
22
27
  return "(" + (" ".join(items)) + ")"
23
28
 
@@ -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
  {
@@ -26,8 +26,8 @@ END: Cython Metadata */
26
26
  #elif PY_VERSION_HEX < 0x03080000
27
27
  #error Cython requires Python 3.8+.
28
28
  #else
29
- #define __PYX_ABI_VERSION "3_1_2"
30
- #define CYTHON_HEX_VERSION 0x030102F0
29
+ #define __PYX_ABI_VERSION "3_1_3"
30
+ #define CYTHON_HEX_VERSION 0x030103F0
31
31
  #define CYTHON_FUTURE_DIVISION 1
32
32
  /* CModulePreamble */
33
33
  #include <stddef.h>
@@ -390,6 +390,9 @@ END: Cython Metadata */
390
390
  enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) };
391
391
  #endif
392
392
  #endif
393
+ #ifndef CYTHON_LOCK_AND_GIL_DEADLOCK_AVOIDANCE_TIME
394
+ #define CYTHON_LOCK_AND_GIL_DEADLOCK_AVOIDANCE_TIME 100
395
+ #endif
393
396
  #ifndef __has_attribute
394
397
  #define __has_attribute(x) 0
395
398
  #endif
@@ -2390,7 +2393,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyLong_AddObjC(PyObject *op1, PyObject *op2
2390
2393
  static PyObject *__Pyx_PyLong_AbsNeg(PyObject *num);
2391
2394
  #define __Pyx_PyNumber_Absolute(x)\
2392
2395
  ((likely(PyLong_CheckExact(x))) ?\
2393
- (likely(__Pyx_PyLong_IsNonNeg(x)) ? (Py_INCREF(x), (x)) : __Pyx_PyLong_AbsNeg(x)) :\
2396
+ (likely(__Pyx_PyLong_IsNonNeg(x)) ? __Pyx_NewRef(x) : __Pyx_PyLong_AbsNeg(x)) :\
2394
2397
  PyNumber_Absolute(x))
2395
2398
  #else
2396
2399
  #define __Pyx_PyNumber_Absolute(x) PyNumber_Absolute(x)
@@ -3261,7 +3264,7 @@ static const char __pyx_k_segmentPointAtT[] = "segmentPointAtT";
3261
3264
  static const char __pyx_k_splitCubicAtT_2[] = "splitCubicAtT";
3262
3265
  static const char __pyx_k_transformPoints[] = "transformPoints";
3263
3266
  static const char __pyx_k_1_a_r_wb_gRvWBfA[] = "\320\000+\2501\360\034\000\005\014\320\013\036\230a\330\010\017\210r\220\026\220w\230b\240\006\240g\250R\250v\260W\270B\270f\300A";
3264
- static const char __pyx_k_s_3c_A_AS_1_b_AQ[] = "\200\001\330\004\007\200s\210!\2103\210c\220\021\330\010\017\320\017\"\240\"\240A\330\t\014\210A\210S\220\003\2201\330\010\017\210\230b\240\001\330\004\n\210*\220A\220Q";
3267
+ static const char __pyx_k_s_3c_A_AS_1_b_AQ[] = "\200\001\330\004\007\200s\210!\2103\210c\220\021\330\010\017\320\017\"\240\"\240A\330\t\014\210A\210S\220\003\2201\330\010\017\210\177\230b\240\001\330\004\n\210*\220A\220Q";
3265
3268
  static const char __pyx_k_splitCubicAtTC_2[] = "_splitCubicAtTC";
3266
3269
  static const char __pyx_k_quadraticPointAtT[] = "quadraticPointAtT";
3267
3270
  static const char __pyx_k_splitQuadraticAtT[] = "_splitQuadraticAtT";
@@ -31612,16 +31615,15 @@ static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) {
31612
31615
  return -1;
31613
31616
  }
31614
31617
  /* #### Code section: init_codeobjects ### */
31615
- \
31616
- typedef struct {
31617
- unsigned int argcount : 3;
31618
- unsigned int num_posonly_args : 1;
31619
- unsigned int num_kwonly_args : 1;
31620
- unsigned int nlocals : 6;
31621
- unsigned int flags : 10;
31622
- unsigned int first_line : 11;
31623
- unsigned int line_table_length : 14;
31624
- } __Pyx_PyCode_New_function_description;
31618
+ typedef struct {
31619
+ unsigned int argcount : 3;
31620
+ unsigned int num_posonly_args : 1;
31621
+ unsigned int num_kwonly_args : 1;
31622
+ unsigned int nlocals : 6;
31623
+ unsigned int flags : 10;
31624
+ unsigned int first_line : 11;
31625
+ unsigned int line_table_length : 14;
31626
+ } __Pyx_PyCode_New_function_description;
31625
31627
  /* NewCodeObj.proto */
31626
31628
  static PyObject* __Pyx_PyCode_New(
31627
31629
  const __Pyx_PyCode_New_function_description descr,
@@ -34135,6 +34137,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
34135
34137
  changed = 1;
34136
34138
  }
34137
34139
  #endif // CYTHON_METH_FASTCALL
34140
+ #if !CYTHON_COMPILING_IN_PYPY
34138
34141
  else if (strcmp(memb->name, "__module__") == 0) {
34139
34142
  PyObject *descr;
34140
34143
  assert(memb->type == T_OBJECT);
@@ -34149,11 +34152,13 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
34149
34152
  }
34150
34153
  changed = 1;
34151
34154
  }
34155
+ #endif // !CYTHON_COMPILING_IN_PYPY
34152
34156
  }
34153
34157
  memb++;
34154
34158
  }
34155
34159
  }
34156
34160
  #endif // !CYTHON_COMPILING_IN_LIMITED_API
34161
+ #if !CYTHON_COMPILING_IN_PYPY
34157
34162
  slot = spec->slots;
34158
34163
  while (slot && slot->slot && slot->slot != Py_tp_getset)
34159
34164
  slot++;
@@ -34185,6 +34190,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
34185
34190
  ++getset;
34186
34191
  }
34187
34192
  }
34193
+ #endif // !CYTHON_COMPILING_IN_PYPY
34188
34194
  if (changed)
34189
34195
  PyType_Modified(type);
34190
34196
  #endif // PY_VERSION_HEX > 0x030900B1
@@ -34317,7 +34323,7 @@ bad:
34317
34323
  }
34318
34324
 
34319
34325
  /* CommonTypesMetaclass */
34320
- PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
34326
+ static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
34321
34327
  return PyUnicode_FromString(__PYX_ABI_MODULE_NAME);
34322
34328
  }
34323
34329
  static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = {
@@ -34735,7 +34741,7 @@ try_unpack:
34735
34741
  }
34736
34742
 
34737
34743
  /* PyObjectCallMethod1 */
34738
- #if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000)
34744
+ #if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)))
34739
34745
  static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
34740
34746
  PyObject *result = __Pyx_PyObject_CallOneArg(method, arg);
34741
34747
  Py_DECREF(method);
@@ -34743,7 +34749,7 @@ static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
34743
34749
  }
34744
34750
  #endif
34745
34751
  static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
34746
- #if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000
34752
+ #if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
34747
34753
  PyObject *args[2] = {obj, arg};
34748
34754
  (void) __Pyx_PyObject_GetMethod;
34749
34755
  (void) __Pyx_PyObject_CallOneArg;
@@ -36076,7 +36082,7 @@ static PyObject *__Pyx_PyLong_AbsNeg(PyObject *n) {
36076
36082
  PyObject *copy = _PyLong_Copy((PyLongObject*)n);
36077
36083
  if (likely(copy)) {
36078
36084
  #if PY_VERSION_HEX >= 0x030C00A7
36079
- ((PyLongObject*)copy)->long_value.lv_tag = ((PyLongObject*)copy)->long_value.lv_tag & ~_PyLong_SIGN_MASK;
36085
+ ((PyLongObject*)copy)->long_value.lv_tag ^= ((PyLongObject*)copy)->long_value.lv_tag & _PyLong_SIGN_MASK;
36080
36086
  #else
36081
36087
  __Pyx_SET_SIZE(copy, -Py_SIZE(copy));
36082
36088
  #endif
@@ -37773,6 +37779,13 @@ static CYTHON_INLINE int __Pyx_PySet_ContainsTF(PyObject* key, PyObject* set, in
37773
37779
 
37774
37780
  /* PyObjectCallMethod0 */
37775
37781
  static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) {
37782
+ #if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
37783
+ PyObject *args[1] = {obj};
37784
+ (void) __Pyx_PyObject_GetMethod;
37785
+ (void) __Pyx_PyObject_CallOneArg;
37786
+ (void) __Pyx_PyObject_CallNoArg;
37787
+ return PyObject_VectorcallMethod(method_name, args, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
37788
+ #else
37776
37789
  PyObject *method = NULL, *result = NULL;
37777
37790
  int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method);
37778
37791
  if (likely(is_method)) {
@@ -37785,6 +37798,7 @@ static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name
37785
37798
  Py_DECREF(method);
37786
37799
  bad:
37787
37800
  return result;
37801
+ #endif
37788
37802
  }
37789
37803
 
37790
37804
  /* ValidateBasesTuple */
@@ -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,
@@ -1,5 +1,7 @@
1
1
  """fontTools.misc.textTools.py -- miscellaneous routines."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import ast
4
6
  import string
5
7
 
@@ -118,14 +120,14 @@ def pad(data, size):
118
120
  return data
119
121
 
120
122
 
121
- def tostr(s, encoding="ascii", errors="strict"):
123
+ def tostr(s: str | bytes, encoding: str = "ascii", errors: str = "strict") -> str:
122
124
  if not isinstance(s, str):
123
125
  return s.decode(encoding, errors)
124
126
  else:
125
127
  return s
126
128
 
127
129
 
128
- def tobytes(s, encoding="ascii", errors="strict"):
130
+ def tobytes(s: str | bytes, encoding: str = "ascii", errors: str = "strict") -> bytes:
129
131
  if isinstance(s, str):
130
132
  return s.encode(encoding, errors)
131
133
  else:
@@ -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
  {
@@ -26,8 +26,8 @@ END: Cython Metadata */
26
26
  #elif PY_VERSION_HEX < 0x03080000
27
27
  #error Cython requires Python 3.8+.
28
28
  #else
29
- #define __PYX_ABI_VERSION "3_1_2"
30
- #define CYTHON_HEX_VERSION 0x030102F0
29
+ #define __PYX_ABI_VERSION "3_1_3"
30
+ #define CYTHON_HEX_VERSION 0x030103F0
31
31
  #define CYTHON_FUTURE_DIVISION 1
32
32
  /* CModulePreamble */
33
33
  #include <stddef.h>
@@ -390,6 +390,9 @@ END: Cython Metadata */
390
390
  enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) };
391
391
  #endif
392
392
  #endif
393
+ #ifndef CYTHON_LOCK_AND_GIL_DEADLOCK_AVOIDANCE_TIME
394
+ #define CYTHON_LOCK_AND_GIL_DEADLOCK_AVOIDANCE_TIME 100
395
+ #endif
393
396
  #ifndef __has_attribute
394
397
  #define __has_attribute(x) 0
395
398
  #endif
@@ -8294,16 +8297,15 @@ static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) {
8294
8297
  return -1;
8295
8298
  }
8296
8299
  /* #### Code section: init_codeobjects ### */
8297
- \
8298
- typedef struct {
8299
- unsigned int argcount : 3;
8300
- unsigned int num_posonly_args : 1;
8301
- unsigned int num_kwonly_args : 1;
8302
- unsigned int nlocals : 8;
8303
- unsigned int flags : 10;
8304
- unsigned int first_line : 9;
8305
- unsigned int line_table_length : 17;
8306
- } __Pyx_PyCode_New_function_description;
8300
+ typedef struct {
8301
+ unsigned int argcount : 3;
8302
+ unsigned int num_posonly_args : 1;
8303
+ unsigned int num_kwonly_args : 1;
8304
+ unsigned int nlocals : 8;
8305
+ unsigned int flags : 10;
8306
+ unsigned int first_line : 9;
8307
+ unsigned int line_table_length : 17;
8308
+ } __Pyx_PyCode_New_function_description;
8307
8309
  /* NewCodeObj.proto */
8308
8310
  static PyObject* __Pyx_PyCode_New(
8309
8311
  const __Pyx_PyCode_New_function_description descr,
@@ -10172,6 +10174,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
10172
10174
  changed = 1;
10173
10175
  }
10174
10176
  #endif // CYTHON_METH_FASTCALL
10177
+ #if !CYTHON_COMPILING_IN_PYPY
10175
10178
  else if (strcmp(memb->name, "__module__") == 0) {
10176
10179
  PyObject *descr;
10177
10180
  assert(memb->type == T_OBJECT);
@@ -10186,11 +10189,13 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
10186
10189
  }
10187
10190
  changed = 1;
10188
10191
  }
10192
+ #endif // !CYTHON_COMPILING_IN_PYPY
10189
10193
  }
10190
10194
  memb++;
10191
10195
  }
10192
10196
  }
10193
10197
  #endif // !CYTHON_COMPILING_IN_LIMITED_API
10198
+ #if !CYTHON_COMPILING_IN_PYPY
10194
10199
  slot = spec->slots;
10195
10200
  while (slot && slot->slot && slot->slot != Py_tp_getset)
10196
10201
  slot++;
@@ -10222,6 +10227,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
10222
10227
  ++getset;
10223
10228
  }
10224
10229
  }
10230
+ #endif // !CYTHON_COMPILING_IN_PYPY
10225
10231
  if (changed)
10226
10232
  PyType_Modified(type);
10227
10233
  #endif // PY_VERSION_HEX > 0x030900B1
@@ -10354,7 +10360,7 @@ bad:
10354
10360
  }
10355
10361
 
10356
10362
  /* CommonTypesMetaclass */
10357
- PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
10363
+ static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
10358
10364
  return PyUnicode_FromString(__PYX_ABI_MODULE_NAME);
10359
10365
  }
10360
10366
  static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = {