fonttools 4.59.0__cp312-cp312-macosx_10_13_universal2.whl → 4.59.2__cp312-cp312-macosx_10_13_universal2.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 +751 -643
  5. fontTools/cu2qu/cu2qu.cpython-312-darwin.so +0 -0
  6. fontTools/cu2qu/cu2qu.py +17 -2
  7. fontTools/feaLib/builder.py +15 -4
  8. fontTools/feaLib/lexer.c +21 -6
  9. fontTools/feaLib/lexer.cpython-312-darwin.so +0 -0
  10. fontTools/feaLib/parser.py +11 -1
  11. fontTools/feaLib/variableScalar.py +6 -1
  12. fontTools/misc/bezierTools.c +24 -9
  13. fontTools/misc/bezierTools.cpython-312-darwin.so +0 -0
  14. fontTools/misc/psCharStrings.py +17 -2
  15. fontTools/misc/textTools.py +4 -2
  16. fontTools/pens/momentsPen.c +11 -4
  17. fontTools/pens/momentsPen.cpython-312-darwin.so +0 -0
  18. fontTools/qu2cu/qu2cu.c +23 -8
  19. fontTools/qu2cu/qu2cu.cpython-312-darwin.so +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 +23 -8
  29. fontTools/varLib/iup.cpython-312-darwin.so +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
@@ -13414,6 +13417,13 @@ try_unpack:
13414
13417
 
13415
13418
  /* PyObjectCallMethod0 */
13416
13419
  static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) {
13420
+ #if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
13421
+ PyObject *args[1] = {obj};
13422
+ (void) __Pyx_PyObject_GetMethod;
13423
+ (void) __Pyx_PyObject_CallOneArg;
13424
+ (void) __Pyx_PyObject_CallNoArg;
13425
+ return PyObject_VectorcallMethod(method_name, args, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
13426
+ #else
13417
13427
  PyObject *method = NULL, *result = NULL;
13418
13428
  int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method);
13419
13429
  if (likely(is_method)) {
@@ -13426,6 +13436,7 @@ static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name
13426
13436
  Py_DECREF(method);
13427
13437
  bad:
13428
13438
  return result;
13439
+ #endif
13429
13440
  }
13430
13441
 
13431
13442
  /* CallUnboundCMethod0 */
@@ -13493,7 +13504,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyOb
13493
13504
  }
13494
13505
 
13495
13506
  /* PyObjectCallMethod1 */
13496
- #if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000)
13507
+ #if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)))
13497
13508
  static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
13498
13509
  PyObject *result = __Pyx_PyObject_CallOneArg(method, arg);
13499
13510
  Py_DECREF(method);
@@ -13501,7 +13512,7 @@ static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
13501
13512
  }
13502
13513
  #endif
13503
13514
  static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
13504
- #if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000
13515
+ #if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
13505
13516
  PyObject *args[2] = {obj, arg};
13506
13517
  (void) __Pyx_PyObject_GetMethod;
13507
13518
  (void) __Pyx_PyObject_CallOneArg;
@@ -14087,6 +14098,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
14087
14098
  changed = 1;
14088
14099
  }
14089
14100
  #endif // CYTHON_METH_FASTCALL
14101
+ #if !CYTHON_COMPILING_IN_PYPY
14090
14102
  else if (strcmp(memb->name, "__module__") == 0) {
14091
14103
  PyObject *descr;
14092
14104
  assert(memb->type == T_OBJECT);
@@ -14101,11 +14113,13 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
14101
14113
  }
14102
14114
  changed = 1;
14103
14115
  }
14116
+ #endif // !CYTHON_COMPILING_IN_PYPY
14104
14117
  }
14105
14118
  memb++;
14106
14119
  }
14107
14120
  }
14108
14121
  #endif // !CYTHON_COMPILING_IN_LIMITED_API
14122
+ #if !CYTHON_COMPILING_IN_PYPY
14109
14123
  slot = spec->slots;
14110
14124
  while (slot && slot->slot && slot->slot != Py_tp_getset)
14111
14125
  slot++;
@@ -14137,6 +14151,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
14137
14151
  ++getset;
14138
14152
  }
14139
14153
  }
14154
+ #endif // !CYTHON_COMPILING_IN_PYPY
14140
14155
  if (changed)
14141
14156
  PyType_Modified(type);
14142
14157
  #endif // PY_VERSION_HEX > 0x030900B1
@@ -14269,7 +14284,7 @@ bad:
14269
14284
  }
14270
14285
 
14271
14286
  /* CommonTypesMetaclass */
14272
- PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
14287
+ static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
14273
14288
  return PyUnicode_FromString(__PYX_ABI_MODULE_NAME);
14274
14289
  }
14275
14290
  static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = {
@@ -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";
@@ -34135,6 +34138,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
34135
34138
  changed = 1;
34136
34139
  }
34137
34140
  #endif // CYTHON_METH_FASTCALL
34141
+ #if !CYTHON_COMPILING_IN_PYPY
34138
34142
  else if (strcmp(memb->name, "__module__") == 0) {
34139
34143
  PyObject *descr;
34140
34144
  assert(memb->type == T_OBJECT);
@@ -34149,11 +34153,13 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
34149
34153
  }
34150
34154
  changed = 1;
34151
34155
  }
34156
+ #endif // !CYTHON_COMPILING_IN_PYPY
34152
34157
  }
34153
34158
  memb++;
34154
34159
  }
34155
34160
  }
34156
34161
  #endif // !CYTHON_COMPILING_IN_LIMITED_API
34162
+ #if !CYTHON_COMPILING_IN_PYPY
34157
34163
  slot = spec->slots;
34158
34164
  while (slot && slot->slot && slot->slot != Py_tp_getset)
34159
34165
  slot++;
@@ -34185,6 +34191,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
34185
34191
  ++getset;
34186
34192
  }
34187
34193
  }
34194
+ #endif // !CYTHON_COMPILING_IN_PYPY
34188
34195
  if (changed)
34189
34196
  PyType_Modified(type);
34190
34197
  #endif // PY_VERSION_HEX > 0x030900B1
@@ -34317,7 +34324,7 @@ bad:
34317
34324
  }
34318
34325
 
34319
34326
  /* CommonTypesMetaclass */
34320
- PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
34327
+ static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
34321
34328
  return PyUnicode_FromString(__PYX_ABI_MODULE_NAME);
34322
34329
  }
34323
34330
  static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = {
@@ -34735,7 +34742,7 @@ try_unpack:
34735
34742
  }
34736
34743
 
34737
34744
  /* PyObjectCallMethod1 */
34738
- #if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000)
34745
+ #if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)))
34739
34746
  static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
34740
34747
  PyObject *result = __Pyx_PyObject_CallOneArg(method, arg);
34741
34748
  Py_DECREF(method);
@@ -34743,7 +34750,7 @@ static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
34743
34750
  }
34744
34751
  #endif
34745
34752
  static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
34746
- #if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000
34753
+ #if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
34747
34754
  PyObject *args[2] = {obj, arg};
34748
34755
  (void) __Pyx_PyObject_GetMethod;
34749
34756
  (void) __Pyx_PyObject_CallOneArg;
@@ -36076,7 +36083,7 @@ static PyObject *__Pyx_PyLong_AbsNeg(PyObject *n) {
36076
36083
  PyObject *copy = _PyLong_Copy((PyLongObject*)n);
36077
36084
  if (likely(copy)) {
36078
36085
  #if PY_VERSION_HEX >= 0x030C00A7
36079
- ((PyLongObject*)copy)->long_value.lv_tag = ((PyLongObject*)copy)->long_value.lv_tag & ~_PyLong_SIGN_MASK;
36086
+ ((PyLongObject*)copy)->long_value.lv_tag ^= ((PyLongObject*)copy)->long_value.lv_tag & _PyLong_SIGN_MASK;
36080
36087
  #else
36081
36088
  __Pyx_SET_SIZE(copy, -Py_SIZE(copy));
36082
36089
  #endif
@@ -37773,6 +37780,13 @@ static CYTHON_INLINE int __Pyx_PySet_ContainsTF(PyObject* key, PyObject* set, in
37773
37780
 
37774
37781
  /* PyObjectCallMethod0 */
37775
37782
  static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) {
37783
+ #if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
37784
+ PyObject *args[1] = {obj};
37785
+ (void) __Pyx_PyObject_GetMethod;
37786
+ (void) __Pyx_PyObject_CallOneArg;
37787
+ (void) __Pyx_PyObject_CallNoArg;
37788
+ return PyObject_VectorcallMethod(method_name, args, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
37789
+ #else
37776
37790
  PyObject *method = NULL, *result = NULL;
37777
37791
  int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method);
37778
37792
  if (likely(is_method)) {
@@ -37785,6 +37799,7 @@ static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name
37785
37799
  Py_DECREF(method);
37786
37800
  bad:
37787
37801
  return result;
37802
+ #endif
37788
37803
  }
37789
37804
 
37790
37805
  /* 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
@@ -10172,6 +10175,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
10172
10175
  changed = 1;
10173
10176
  }
10174
10177
  #endif // CYTHON_METH_FASTCALL
10178
+ #if !CYTHON_COMPILING_IN_PYPY
10175
10179
  else if (strcmp(memb->name, "__module__") == 0) {
10176
10180
  PyObject *descr;
10177
10181
  assert(memb->type == T_OBJECT);
@@ -10186,11 +10190,13 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
10186
10190
  }
10187
10191
  changed = 1;
10188
10192
  }
10193
+ #endif // !CYTHON_COMPILING_IN_PYPY
10189
10194
  }
10190
10195
  memb++;
10191
10196
  }
10192
10197
  }
10193
10198
  #endif // !CYTHON_COMPILING_IN_LIMITED_API
10199
+ #if !CYTHON_COMPILING_IN_PYPY
10194
10200
  slot = spec->slots;
10195
10201
  while (slot && slot->slot && slot->slot != Py_tp_getset)
10196
10202
  slot++;
@@ -10222,6 +10228,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
10222
10228
  ++getset;
10223
10229
  }
10224
10230
  }
10231
+ #endif // !CYTHON_COMPILING_IN_PYPY
10225
10232
  if (changed)
10226
10233
  PyType_Modified(type);
10227
10234
  #endif // PY_VERSION_HEX > 0x030900B1
@@ -10354,7 +10361,7 @@ bad:
10354
10361
  }
10355
10362
 
10356
10363
  /* CommonTypesMetaclass */
10357
- PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
10364
+ static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
10358
10365
  return PyUnicode_FromString(__PYX_ABI_MODULE_NAME);
10359
10366
  }
10360
10367
  static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = {
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)
@@ -10557,7 +10560,7 @@ static PyObject *__Pyx_PyLong_AbsNeg(PyObject *n) {
10557
10560
  PyObject *copy = _PyLong_Copy((PyLongObject*)n);
10558
10561
  if (likely(copy)) {
10559
10562
  #if PY_VERSION_HEX >= 0x030C00A7
10560
- ((PyLongObject*)copy)->long_value.lv_tag = ((PyLongObject*)copy)->long_value.lv_tag & ~_PyLong_SIGN_MASK;
10563
+ ((PyLongObject*)copy)->long_value.lv_tag ^= ((PyLongObject*)copy)->long_value.lv_tag & _PyLong_SIGN_MASK;
10561
10564
  #else
10562
10565
  __Pyx_SET_SIZE(copy, -Py_SIZE(copy));
10563
10566
  #endif
@@ -11193,6 +11196,13 @@ try_unpack:
11193
11196
 
11194
11197
  /* PyObjectCallMethod0 */
11195
11198
  static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) {
11199
+ #if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
11200
+ PyObject *args[1] = {obj};
11201
+ (void) __Pyx_PyObject_GetMethod;
11202
+ (void) __Pyx_PyObject_CallOneArg;
11203
+ (void) __Pyx_PyObject_CallNoArg;
11204
+ return PyObject_VectorcallMethod(method_name, args, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
11205
+ #else
11196
11206
  PyObject *method = NULL, *result = NULL;
11197
11207
  int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method);
11198
11208
  if (likely(is_method)) {
@@ -11205,6 +11215,7 @@ static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name
11205
11215
  Py_DECREF(method);
11206
11216
  bad:
11207
11217
  return result;
11218
+ #endif
11208
11219
  }
11209
11220
 
11210
11221
  /* CallUnboundCMethod0 */
@@ -11742,6 +11753,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
11742
11753
  changed = 1;
11743
11754
  }
11744
11755
  #endif // CYTHON_METH_FASTCALL
11756
+ #if !CYTHON_COMPILING_IN_PYPY
11745
11757
  else if (strcmp(memb->name, "__module__") == 0) {
11746
11758
  PyObject *descr;
11747
11759
  assert(memb->type == T_OBJECT);
@@ -11756,11 +11768,13 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
11756
11768
  }
11757
11769
  changed = 1;
11758
11770
  }
11771
+ #endif // !CYTHON_COMPILING_IN_PYPY
11759
11772
  }
11760
11773
  memb++;
11761
11774
  }
11762
11775
  }
11763
11776
  #endif // !CYTHON_COMPILING_IN_LIMITED_API
11777
+ #if !CYTHON_COMPILING_IN_PYPY
11764
11778
  slot = spec->slots;
11765
11779
  while (slot && slot->slot && slot->slot != Py_tp_getset)
11766
11780
  slot++;
@@ -11792,6 +11806,7 @@ static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject
11792
11806
  ++getset;
11793
11807
  }
11794
11808
  }
11809
+ #endif // !CYTHON_COMPILING_IN_PYPY
11795
11810
  if (changed)
11796
11811
  PyType_Modified(type);
11797
11812
  #endif // PY_VERSION_HEX > 0x030900B1
@@ -12227,7 +12242,7 @@ bad:
12227
12242
  }
12228
12243
 
12229
12244
  /* CommonTypesMetaclass */
12230
- PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
12245
+ static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) {
12231
12246
  return PyUnicode_FromString(__PYX_ABI_MODULE_NAME);
12232
12247
  }
12233
12248
  static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = {
@@ -14847,7 +14862,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyOb
14847
14862
  }
14848
14863
 
14849
14864
  /* PyObjectCallMethod1 */
14850
- #if !(CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000)
14865
+ #if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)))
14851
14866
  static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
14852
14867
  PyObject *result = __Pyx_PyObject_CallOneArg(method, arg);
14853
14868
  Py_DECREF(method);
@@ -14855,7 +14870,7 @@ static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) {
14855
14870
  }
14856
14871
  #endif
14857
14872
  static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
14858
- #if CYTHON_VECTORCALL && __PYX_LIMITED_VERSION_HEX >= 0x030C0000
14873
+ #if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))
14859
14874
  PyObject *args[2] = {obj, arg};
14860
14875
  (void) __Pyx_PyObject_GetMethod;
14861
14876
  (void) __Pyx_PyObject_CallOneArg;
Binary file
@@ -1530,6 +1530,7 @@ def subset_glyphs(self, s):
1530
1530
  if self.MarkFilteringSet not in s.used_mark_sets:
1531
1531
  self.MarkFilteringSet = None
1532
1532
  self.LookupFlag &= ~0x10
1533
+ self.LookupFlag |= 0x8
1533
1534
  else:
1534
1535
  self.MarkFilteringSet = s.used_mark_sets.index(self.MarkFilteringSet)
1535
1536
  return bool(self.SubTableCount)
@@ -143,7 +143,7 @@ class table__a_v_a_r(BaseTTXConverter):
143
143
  else:
144
144
  super().fromXML(name, attrs, content, ttFont)
145
145
 
146
- def renormalizeLocation(self, location, font):
146
+ def renormalizeLocation(self, location, font, dropZeroes=True):
147
147
 
148
148
  majorVersion = getattr(self, "majorVersion", 1)
149
149
 
@@ -185,7 +185,9 @@ class table__a_v_a_r(BaseTTXConverter):
185
185
  out.append(v)
186
186
 
187
187
  mappedLocation = {
188
- axis.axisTag: fi2fl(v, 14) for v, axis in zip(out, axes) if v != 0
188
+ axis.axisTag: fi2fl(v, 14)
189
+ for v, axis in zip(out, axes)
190
+ if v != 0 or not dropZeroes
189
191
  }
190
192
 
191
193
  return mappedLocation