fonttools 4.58.3__cp39-cp39-musllinux_1_2_x86_64.whl → 4.58.5__cp39-cp39-musllinux_1_2_x86_64.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.58.3"
6
+ version = __version__ = "4.58.5"
7
7
 
8
8
  __all__ = ["version", "log", "configLogger"]
fontTools/feaLib/ast.py CHANGED
@@ -1,3 +1,4 @@
1
+ import weakref
1
2
  from fontTools.feaLib.error import FeatureLibError
2
3
  from fontTools.feaLib.location import FeatureLibLocation
3
4
  from fontTools.misc.encodingTools import getEncoding
@@ -529,7 +530,7 @@ class MarkClass(object):
529
530
  def addDefinition(self, definition):
530
531
  """Add a :class:`MarkClassDefinition` statement to this mark class."""
531
532
  assert isinstance(definition, MarkClassDefinition)
532
- self.definitions.append(definition)
533
+ self.definitions.append(weakref.proxy(definition))
533
534
  for glyph in definition.glyphSet():
534
535
  if glyph in self.glyphs:
535
536
  otherLoc = self.glyphs[glyph].location
@@ -259,12 +259,13 @@ class Builder(object):
259
259
  key = (script, lang, feature_name)
260
260
  self.features_.setdefault(key, []).append(lookup)
261
261
 
262
- def get_lookup_(self, location, builder_class):
262
+ def get_lookup_(self, location, builder_class, mapping=None):
263
263
  if (
264
264
  self.cur_lookup_
265
265
  and type(self.cur_lookup_) == builder_class
266
266
  and self.cur_lookup_.lookupflag == self.lookupflag_
267
267
  and self.cur_lookup_.markFilterSet == self.lookupflag_markFilterSet_
268
+ and self.cur_lookup_.can_add_mapping(mapping)
268
269
  ):
269
270
  return self.cur_lookup_
270
271
  if self.cur_lookup_name_ and self.cur_lookup_:
@@ -1206,10 +1207,10 @@ class Builder(object):
1206
1207
 
1207
1208
  def set_lookup_flag(self, location, value, markAttach, markFilter):
1208
1209
  value = value & 0xFF
1209
- if markAttach:
1210
+ if markAttach is not None:
1210
1211
  markAttachClass = self.getMarkAttachClass_(location, markAttach)
1211
1212
  value = value | (markAttachClass << 8)
1212
- if markFilter:
1213
+ if markFilter is not None:
1213
1214
  markFilterSet = self.getMarkFilterSet_(location, markFilter)
1214
1215
  value = value | 0x10
1215
1216
  self.lookupflag_markFilterSet_ = markFilterSet
@@ -1305,7 +1306,7 @@ class Builder(object):
1305
1306
  # GSUB rules
1306
1307
 
1307
1308
  def add_any_subst_(self, location, mapping):
1308
- lookup = self.get_lookup_(location, AnySubstBuilder)
1309
+ lookup = self.get_lookup_(location, AnySubstBuilder, mapping=mapping)
1309
1310
  for key, value in mapping.items():
1310
1311
  if key in lookup.mapping:
1311
1312
  if value == lookup.mapping[key]:
fontTools/misc/visitor.py CHANGED
@@ -1,11 +1,19 @@
1
1
  """Generic visitor pattern implementation for Python objects."""
2
2
 
3
3
  import enum
4
+ import weakref
4
5
 
5
6
 
6
7
  class Visitor(object):
7
8
  defaultStop = False
8
9
 
10
+ _visitors = {
11
+ # By default we skip visiting weak references to avoid recursion
12
+ # issues. Users can override this by registering a visit
13
+ # function for weakref.ProxyType.
14
+ weakref.ProxyType: {None: lambda self, obj, *args, **kwargs: False}
15
+ }
16
+
9
17
  @classmethod
10
18
  def _register(celf, clazzes_attrs):
11
19
  assert celf != Visitor, "Subclass Visitor instead."
@@ -256,6 +256,10 @@ class LookupBuilder(object):
256
256
  )
257
257
  )
258
258
 
259
+ def can_add_mapping(self, _mapping) -> bool:
260
+ # used by AnySubstBuilder, below
261
+ return True
262
+
259
263
 
260
264
  class AlternateSubstBuilder(LookupBuilder):
261
265
  """Builds an Alternate Substitution (GSUB3) lookup.
@@ -1376,6 +1380,32 @@ class AnySubstBuilder(LookupBuilder):
1376
1380
  def _add_to_ligature_subst(self, builder, key, value):
1377
1381
  builder.ligatures[key] = value[0]
1378
1382
 
1383
+ def can_add_mapping(self, mapping) -> bool:
1384
+ if mapping is None:
1385
+ return True
1386
+ # single sub rules can be treated as (degenerate) liga-or-multi sub
1387
+ # rules, but multi and liga sub rules themselves have incompatible
1388
+ # representations. It is uncommon that these are in the same set of
1389
+ # rules, but it happens.
1390
+ is_multi = any(len(v) > 1 for v in mapping.values())
1391
+ is_liga = any(len(k) > 1 for k in mapping.keys())
1392
+
1393
+ has_existing_multi = False
1394
+ has_existing_liga = False
1395
+
1396
+ for k, v in self.mapping.items():
1397
+ if k[0] == self.SUBTABLE_BREAK_:
1398
+ continue
1399
+ if len(k) > 1:
1400
+ has_existing_liga = True
1401
+ if len(v) > 1:
1402
+ has_existing_multi = True
1403
+
1404
+ can_reuse = not (has_existing_multi and is_liga) and not (
1405
+ has_existing_liga and is_multi
1406
+ )
1407
+ return can_reuse
1408
+
1379
1409
  def promote_lookup_type(self, is_named_lookup):
1380
1410
  # https://github.com/fonttools/fonttools/issues/612
1381
1411
  # A multiple substitution may have a single destination, in which case
@@ -723,9 +723,7 @@ def instantiateCFF2(
723
723
  minor = varDataCursor[major]
724
724
  varDataCursor[major] += 1
725
725
 
726
- varIdx = (major << 16) + minor
727
-
728
- defaultValue += round(defaultDeltas[varIdx])
726
+ defaultValue += round(defaultDeltas[major][minor])
729
727
  newDefaults.append(defaultValue)
730
728
 
731
729
  varData = varStore.VarData[major]
@@ -781,7 +779,9 @@ def instantiateCFF2(
781
779
  storeBlendsToVarStore(value + [count])
782
780
 
783
781
  # Instantiate VarStore
784
- defaultDeltas = instantiateItemVariationStore(varStore, fvarAxes, axisLimits)
782
+ defaultDeltas = instantiateItemVariationStore(
783
+ varStore, fvarAxes, axisLimits, hierarchical=True
784
+ )
785
785
 
786
786
  # Read back new charstring blends from the instantiated VarStore
787
787
  varDataCursor = [0] * len(varStore.VarData)
@@ -839,18 +839,13 @@ def instantiateCFF2(
839
839
  varData.Item = []
840
840
  varData.ItemCount = 0
841
841
 
842
- # Remove vsindex commands that are no longer needed, collect those that are.
843
- usedVsindex = set()
844
- for commands in allCommands:
845
- if any(isinstance(arg, list) for command in commands for arg in command[1]):
846
- vsindex = 0
847
- for command in commands:
848
- if command[0] == "vsindex":
849
- vsindex = command[1][0]
850
- continue
851
- if any(isinstance(arg, list) for arg in command[1]):
852
- usedVsindex.add(vsindex)
853
- else:
842
+ # Collect surviving vsindexes
843
+ usedVsindex = set(
844
+ i for i in range(len(varStore.VarData)) if varStore.VarData[i].VarRegionCount
845
+ )
846
+ # Remove vsindex commands that are no longer needed
847
+ for commands, private in zip(allCommands, allCommandPrivates):
848
+ if not any(isinstance(arg, list) for command in commands for arg in command[1]):
854
849
  commands[:] = [command for command in commands if command[0] != "vsindex"]
855
850
 
856
851
  # Remove unused VarData and update vsindex values
@@ -863,10 +858,14 @@ def instantiateCFF2(
863
858
  for command in commands:
864
859
  if command[0] == "vsindex":
865
860
  command[1][0] = vsindexMapping[command[1][0]]
861
+ for private in privateDicts:
862
+ if hasattr(private, "vsindex"):
863
+ private.vsindex = vsindexMapping[private.vsindex]
866
864
 
867
865
  # Remove initial vsindex commands that are implied
868
- for commands in allCommands:
869
- if commands and commands[0] == ("vsindex", [0]):
866
+ for commands, private in zip(allCommands, allCommandPrivates):
867
+ vsindex = getattr(private, "vsindex", 0)
868
+ if commands and commands[0] == ("vsindex", [vsindex]):
870
869
  commands.pop(0)
871
870
 
872
871
  # Ship the charstrings!
@@ -1247,7 +1246,9 @@ class _TupleVarStoreAdapter(object):
1247
1246
  return itemVarStore
1248
1247
 
1249
1248
 
1250
- def instantiateItemVariationStore(itemVarStore, fvarAxes, axisLimits):
1249
+ def instantiateItemVariationStore(
1250
+ itemVarStore, fvarAxes, axisLimits, hierarchical=False
1251
+ ):
1251
1252
  """Compute deltas at partial location, and update varStore in-place.
1252
1253
 
1253
1254
  Remove regions in which all axes were instanced, or fall outside the new axis
@@ -1279,12 +1280,19 @@ def instantiateItemVariationStore(itemVarStore, fvarAxes, axisLimits):
1279
1280
  assert itemVarStore.VarDataCount == newItemVarStore.VarDataCount
1280
1281
  itemVarStore.VarData = newItemVarStore.VarData
1281
1282
 
1282
- defaultDeltas = {
1283
- ((major << 16) + minor): delta
1284
- for major, deltas in enumerate(defaultDeltaArray)
1285
- for minor, delta in enumerate(deltas)
1286
- }
1287
- defaultDeltas[itemVarStore.NO_VARIATION_INDEX] = 0
1283
+ if not hierarchical:
1284
+ defaultDeltas = {
1285
+ ((major << 16) + minor): delta
1286
+ for major, deltas in enumerate(defaultDeltaArray)
1287
+ for minor, delta in enumerate(deltas)
1288
+ }
1289
+ defaultDeltas[itemVarStore.NO_VARIATION_INDEX] = 0
1290
+ else:
1291
+ defaultDeltas = {0xFFFF: {0xFFFF: 0}} # NO_VARIATION_INDEX
1292
+ for major, deltas in enumerate(defaultDeltaArray):
1293
+ defaultDeltasForMajor = defaultDeltas.setdefault(major, {})
1294
+ for minor, delta in enumerate(deltas):
1295
+ defaultDeltasForMajor[minor] = delta
1288
1296
  return defaultDeltas
1289
1297
 
1290
1298
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fonttools
3
- Version: 4.58.3
3
+ Version: 4.58.5
4
4
  Summary: Tools to manipulate font files
5
5
  Home-page: http://github.com/fonttools/fonttools
6
6
  Author: Just van Rossum
@@ -388,6 +388,18 @@ Have fun!
388
388
  Changelog
389
389
  ~~~~~~~~~
390
390
 
391
+ 4.58.5 (released 2025-07-03)
392
+ ----------------------------
393
+
394
+ - [feaLib] Don't try to combine ligature & multisub rules (#3874).
395
+ - [feaLib/ast] Use weakref proxies to avoid cycles in visitor (#3873).
396
+ - [varLib.instancer] Fixed instancing CFF2 fonts where VarData contains more than 64k items (#3858).
397
+
398
+ 4.58.4 (released 2025-06-13)
399
+ ----------------------------
400
+
401
+ - [feaLib] Allow for empty MarkFilter & MarkAttach sets (#3856).
402
+
391
403
  4.58.3 (released 2025-06-13)
392
404
  ----------------------------
393
405
 
@@ -1,4 +1,4 @@
1
- fontTools/__init__.py,sha256=OEv9EAYRZSFSgiQigb-JuHXQpeq2x5rkSEJng0Mfczg,183
1
+ fontTools/__init__.py,sha256=4HbUas2X9jd_VJXaT0sWmsVzqiFmh9BonBxhlk4Sho8,183
2
2
  fontTools/__main__.py,sha256=VjkGh1UD-i1zTDA1dXo1uecSs6PxHdGQ5vlCk_mCCYs,925
3
3
  fontTools/afmLib.py,sha256=1MagIItOzRV4vV5kKPxeDZbPJsfxLB3wdHLFkQvl0uk,13164
4
4
  fontTools/agl.py,sha256=05bm8Uq45uVWW8nPbP6xbNgmFyxQr8sWhYAiP0VSjnI,112975
@@ -40,8 +40,8 @@ fontTools/encodings/__init__.py,sha256=DJBWmoX_Haau7qlgmvWyfbhSzrX2qL636Rns7CG01
40
40
  fontTools/encodings/codecs.py,sha256=u50ruwz9fcRsrUrRGpR17Cr55Ovn1fvCHCKrElVumDE,4721
41
41
  fontTools/feaLib/__init__.py,sha256=jlIru2ghxvb1HhC5Je2BCXjFJmFQlYKpruorPoz3BvQ,213
42
42
  fontTools/feaLib/__main__.py,sha256=Df2PA6LXwna98lSXiL7R4as_ZEdWCIk3egSM5w7GpvM,2240
43
- fontTools/feaLib/ast.py,sha256=AuWdCUE_oysF2yDkvr1dj8K7AUF9bibDEIM0Dla9sbc,74128
44
- fontTools/feaLib/builder.py,sha256=cJGF2d4ueHO5vvzcxnKRufFsIbaJsYvTlBsrDyxDMKI,73052
43
+ fontTools/feaLib/ast.py,sha256=48Y6vpSD_wYfucWyh_bQtzf2AQFX-pOwBvsxdcpVDz0,74158
44
+ fontTools/feaLib/builder.py,sha256=f8bet-VuwM6aIBIUPgKUQ01chyTSaWOzn152zq4Y1rY,73165
45
45
  fontTools/feaLib/error.py,sha256=Bz_5tNcNVcY7_nrAmFlQNhQldtqZWd8WUGQ2E3PWhZo,648
46
46
  fontTools/feaLib/lexer.c,sha256=yVnAVeP6s8MEmqVhbu3aZHdgJZxF-AQyzNssVS-09rY,753326
47
47
  fontTools/feaLib/lexer.cpython-39-x86_64-linux-gnu.so,sha256=Yt5EwWwwGvhEnd2JiNfXs7nQzVOKWLoSqM4KYKg5PZU,995944
@@ -93,7 +93,7 @@ fontTools/misc/timeTools.py,sha256=e9h5pgzL04tBDXmCv_8eRGB4boFV8GKXlS6dq3ggEpw,2
93
93
  fontTools/misc/transform.py,sha256=OR8dPsAw87z77gkZQMq00iUkDWLIxYv-12XiKH1-erk,15798
94
94
  fontTools/misc/treeTools.py,sha256=tLWkwyDHeZUPVOGNnJeD4Pn7x2bQeZetwJKaEAW2J2M,1269
95
95
  fontTools/misc/vector.py,sha256=6lqZcDjAgHJFQgjzD-ULQ_PrigAMfeZKaBZmAfcC0ig,4062
96
- fontTools/misc/visitor.py,sha256=S3I_OCavPhkwGQpwIKV9XjNCaWUcafo7HQCyxDI0nQg,5314
96
+ fontTools/misc/visitor.py,sha256=c9YQs14bXfL1SmqwoAhEGCvXlmyZIKR5_Vr4n7iWaRs,5610
97
97
  fontTools/misc/xmlReader.py,sha256=igut4_d13RT4WarliqVvuuPybO1uSXVeoBOeW4j0_e4,6580
98
98
  fontTools/misc/xmlWriter.py,sha256=CA1c-Ov5vFTF9tT4bGk-f3yBvaX7lVmSdLPYygUqlAE,6046
99
99
  fontTools/misc/plistlib/__init__.py,sha256=1HfhHPt3As6u2eRSlFfl6XdnXv_ypQImeQdWIw6wK7Y,21113
@@ -101,7 +101,7 @@ fontTools/misc/plistlib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
101
101
  fontTools/mtiLib/__init__.py,sha256=EzYwNaENLf906h1THBeq6nSRHUKpOAYxuzO9x9PHzh8,46602
102
102
  fontTools/mtiLib/__main__.py,sha256=gd8X89jnZOe-752k7uaR1lWoiju-2zIT5Yx35Kl0Xek,94
103
103
  fontTools/otlLib/__init__.py,sha256=D2leUW-3gsUTOFcJYGC18edBYjIJ804ut4qitJYWsaQ,45
104
- fontTools/otlLib/builder.py,sha256=nv1bEbN-Q3OhDZJyz3t1CK4M-EoFZ1iPHIPHIQUBNB8,127669
104
+ fontTools/otlLib/builder.py,sha256=MHuQKul3Nl3vzXmY7Wb6x54ZNbJGUzRUD7-VKpOG7lE,128727
105
105
  fontTools/otlLib/error.py,sha256=cthuhBuOwZYpkTLi5gFPupUxkXkCHe-L_YgkE7N1wCI,335
106
106
  fontTools/otlLib/maxContextCalc.py,sha256=3es4Kt84TaZ49sA2ev1zrlwPJikJCAECx5KavwhyB-I,3175
107
107
  fontTools/otlLib/optimize/__init__.py,sha256=UUQRpNkHU2RczCRt-Gz7sEiYE9AQq9BHLXZEOyvsnX4,1530
@@ -312,7 +312,7 @@ fontTools/varLib/mvar.py,sha256=LTV77vH_3Ecg_qKBO5xQzjLOlJir_ppEr7mPVZRgad8,2449
312
312
  fontTools/varLib/plot.py,sha256=NoSZkJ5ndxNcDvJIvd5pQ9_jX6X1oM1K2G_tR4sdPVs,7494
313
313
  fontTools/varLib/stat.py,sha256=XuNKKZxGlBrl4OGFDAwVXhpBwJi23U3BdHmNTKoJnvE,4811
314
314
  fontTools/varLib/varStore.py,sha256=2QA9SDI6jQyQ_zq82OOwa3FBkfl-ksaSo1KGmVFpa9Q,24069
315
- fontTools/varLib/instancer/__init__.py,sha256=4I3M5PL3rLcch_yw_rflb0f09SG3zA3eADws-purFXg,71827
315
+ fontTools/varLib/instancer/__init__.py,sha256=UxmXi4zpOGxSOMRaWQB-2IsI_tsZIK0O_T4AqXPJXZQ,72266
316
316
  fontTools/varLib/instancer/__main__.py,sha256=zfULwcP01FhplS1IlcMgNQnLxk5RVfmOuinWjqeid-g,104
317
317
  fontTools/varLib/instancer/featureVars.py,sha256=oPqSlnHLMDTtOsmQMi6gkzLox7ymCrqlRAkvC_EJ4bc,7110
318
318
  fontTools/varLib/instancer/names.py,sha256=IPRqel_M8zVU0jl30WsfgufxUm9PBBQDQCY3VHapeHc,14950
@@ -324,11 +324,11 @@ fontTools/voltLib/error.py,sha256=phcQOQj-xOspCXu9hBJQRhSOBDzxHRgZd3fWQOFNJzw,39
324
324
  fontTools/voltLib/lexer.py,sha256=OvuETOSvlS6v7iCVeJ3IdH2Cg71n3OJoEyiB3-h6vhE,3368
325
325
  fontTools/voltLib/parser.py,sha256=rkw2IHBZPsrhGVC7Kw7V501m0u52kh1JSM5HXp-xchM,25396
326
326
  fontTools/voltLib/voltToFea.py,sha256=Z2yvnaZLQXzPLT86Uta0zRsXIYgj6NnvZtSWt5xmw2s,36549
327
- fonttools-4.58.3.data/data/share/man/man1/ttx.1,sha256=cLbm_pOOj1C76T2QXvDxzwDj9gk-GTd5RztvTMsouFw,5377
328
- fonttools-4.58.3.dist-info/METADATA,sha256=9_mPfB_snvl802zgL_lpHpjq0OCjQ0JZypHdVxeICLE,106477
329
- fonttools-4.58.3.dist-info/WHEEL,sha256=1lQ8uVaF0e0KhYU1_N6mtUH8lO3rq4o3quRVE11_OcQ,110
330
- fonttools-4.58.3.dist-info/entry_points.txt,sha256=8kVHddxfFWA44FSD4mBpmC-4uCynQnkoz_9aNJb227Y,147
331
- fonttools-4.58.3.dist-info/top_level.txt,sha256=rRgRylrXzekqWOsrhygzib12pQ7WILf7UGjqEwkIFDM,10
332
- fonttools-4.58.3.dist-info/RECORD,,
333
- fonttools-4.58.3.dist-info/licenses/LICENSE,sha256=Z4cgj4P2Wcy8IiOy_elS_6b36KymLxqKK_W8UbsbI4M,1072
334
- fonttools-4.58.3.dist-info/licenses/LICENSE.external,sha256=1IdixYQuQZseNUNQ1bR3SJQhW1d5SGRUR23TNBJjzwo,18687
327
+ fonttools-4.58.5.data/data/share/man/man1/ttx.1,sha256=cLbm_pOOj1C76T2QXvDxzwDj9gk-GTd5RztvTMsouFw,5377
328
+ fonttools-4.58.5.dist-info/METADATA,sha256=0pEZMdDGPPqfSxc73Y1oqegWL7klg3-JmIrl8U2eWwE,106901
329
+ fonttools-4.58.5.dist-info/WHEEL,sha256=1lQ8uVaF0e0KhYU1_N6mtUH8lO3rq4o3quRVE11_OcQ,110
330
+ fonttools-4.58.5.dist-info/entry_points.txt,sha256=8kVHddxfFWA44FSD4mBpmC-4uCynQnkoz_9aNJb227Y,147
331
+ fonttools-4.58.5.dist-info/top_level.txt,sha256=rRgRylrXzekqWOsrhygzib12pQ7WILf7UGjqEwkIFDM,10
332
+ fonttools-4.58.5.dist-info/RECORD,,
333
+ fonttools-4.58.5.dist-info/licenses/LICENSE,sha256=Z4cgj4P2Wcy8IiOy_elS_6b36KymLxqKK_W8UbsbI4M,1072
334
+ fonttools-4.58.5.dist-info/licenses/LICENSE.external,sha256=1IdixYQuQZseNUNQ1bR3SJQhW1d5SGRUR23TNBJjzwo,18687