Speed up varscalar with caching (#2798)

* Speed up varscalar with caching

* Don't use cached_property

* Make model pool a class attribute

* Don't catch things on the values side

* Remove unused import
This commit is contained in:
Simon Cozens 2022-09-05 14:27:08 +01:00 committed by GitHub
parent 17feda4608
commit 5d5c16207b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 1 deletions

View File

@ -770,6 +770,7 @@ class Builder(object):
gdef.remap_device_varidxes(varidx_map)
if 'GPOS' in self.font:
self.font['GPOS'].table.remap_device_varidxes(varidx_map)
VariableScalar.clear_cache()
if any(
(
gdef.GlyphClassDef,

View File

@ -8,6 +8,15 @@ def Location(loc):
class VariableScalar:
"""A scalar with different values at different points in the designspace."""
# We will often use exactly the same locations (i.e. the font's
# masters) for a large number of variable scalars. Instead of
# creating a model for each, let's share the models.
model_pool = {}
@classmethod
def clear_cache(cls):
cls.model_pool = {}
def __init__(self, location_value={}):
self.values = {}
self.axes = {}
@ -84,7 +93,12 @@ class VariableScalar:
@property
def model(self):
locations = [dict(self._normalized_location(k)) for k in self.values.keys()]
return VariationModel(locations)
key = tuple([tuple(x.items()) for x in locations])
if key in self.model_pool:
return self.model_pool[key]
m = VariationModel(locations)
self.model_pool[key] = m
return m
def get_deltas_and_supports(self):
values = list(self.values.values())