From e80e09552e928ded4ef7a1124dea8adeef62557a Mon Sep 17 00:00:00 2001 From: Just van Rossum Date: Mon, 4 Sep 2023 10:16:28 +0200 Subject: [PATCH 1/3] Add a source that uses both a global axis and a local axis to reproduce bug --- .../glyphs.weight=850,flip=100/contents.plist | 8 ++++++++ .../glyphs.weight=850,flip=100/varcotest2.glif | 17 +++++++++++++++++ .../layercontents.plist | 4 ++++ .../glyphs/varcotest2.glif | 16 ++++++++++++++++ 4 files changed, 45 insertions(+) create mode 100644 test-py/data/mutatorsans/MutatorSansBoldCondensed.ufo/glyphs.weight=850,flip=100/contents.plist create mode 100644 test-py/data/mutatorsans/MutatorSansBoldCondensed.ufo/glyphs.weight=850,flip=100/varcotest2.glif diff --git a/test-py/data/mutatorsans/MutatorSansBoldCondensed.ufo/glyphs.weight=850,flip=100/contents.plist b/test-py/data/mutatorsans/MutatorSansBoldCondensed.ufo/glyphs.weight=850,flip=100/contents.plist new file mode 100644 index 000000000..b66d6750a --- /dev/null +++ b/test-py/data/mutatorsans/MutatorSansBoldCondensed.ufo/glyphs.weight=850,flip=100/contents.plist @@ -0,0 +1,8 @@ + + + + + varcotest2 + varcotest2.glif + + diff --git a/test-py/data/mutatorsans/MutatorSansBoldCondensed.ufo/glyphs.weight=850,flip=100/varcotest2.glif b/test-py/data/mutatorsans/MutatorSansBoldCondensed.ufo/glyphs.weight=850,flip=100/varcotest2.glif new file mode 100644 index 000000000..90f209bd9 --- /dev/null +++ b/test-py/data/mutatorsans/MutatorSansBoldCondensed.ufo/glyphs.weight=850,flip=100/varcotest2.glif @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/test-py/data/mutatorsans/MutatorSansBoldCondensed.ufo/layercontents.plist b/test-py/data/mutatorsans/MutatorSansBoldCondensed.ufo/layercontents.plist index e9a336b25..d6d9be0ec 100644 --- a/test-py/data/mutatorsans/MutatorSansBoldCondensed.ufo/layercontents.plist +++ b/test-py/data/mutatorsans/MutatorSansBoldCondensed.ufo/layercontents.plist @@ -10,5 +10,9 @@ background glyphs.background + + weight=850,flip=100 + glyphs.weight=850,flip=100 + diff --git a/test-py/data/mutatorsans/MutatorSansLightCondensed.ufo/glyphs/varcotest2.glif b/test-py/data/mutatorsans/MutatorSansLightCondensed.ufo/glyphs/varcotest2.glif index 0ee044a72..cfc38a1fb 100644 --- a/test-py/data/mutatorsans/MutatorSansLightCondensed.ufo/glyphs/varcotest2.glif +++ b/test-py/data/mutatorsans/MutatorSansLightCondensed.ufo/glyphs/varcotest2.glif @@ -65,8 +65,24 @@ 100 + + layername + weight=850,flip=100 + location + + flip + 100 + weight + 850 + + + xyz.fontra.layer-names + + MutatorSansBoldCondensed/weight=850,flip=100 + weight=850,flip=100 + From 43a92ae1307ae32e5f980300d33fccdf4aaf0b80 Mon Sep 17 00:00:00 2001 From: Just van Rossum Date: Mon, 4 Sep 2023 10:30:48 +0200 Subject: [PATCH 2/3] Use the global portion of the source location to determine in which UFO the source is stored. --- src/fontra/backends/designspace.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/fontra/backends/designspace.py b/src/fontra/backends/designspace.py index db5567979..02e6a3e7a 100644 --- a/src/fontra/backends/designspace.py +++ b/src/fontra/backends/designspace.py @@ -224,7 +224,7 @@ async def getGlyph(self, glyphName): localDS = ufoGlyph.lib.get(GLYPH_DESIGNSPACE_LIB_KEY) if localDS is not None: axes, localSources = self._unpackLocalDesignSpace( - localDS, ufoLayer.path, ufoLayer.name + localDS, ufoLayer.name ) sources.extend(localSources) sourceNameMapping = ufoGlyph.lib.get(SOURCE_NAME_MAPPING_LIB_KEY, {}) @@ -247,7 +247,7 @@ async def getGlyph(self, glyphName): return VariableGlyph(glyphName, axes=axes, sources=sources, layers=layers) - def _unpackLocalDesignSpace(self, dsDict, ufoPath, defaultLayerName): + def _unpackLocalDesignSpace(self, dsDict, defaultLayerName): axes = [ LocalAxis( name=axis["name"], @@ -257,6 +257,8 @@ def _unpackLocalDesignSpace(self, dsDict, ufoPath, defaultLayerName): ) for axis in dsDict["axes"] ] + localAxisNames = {axis.name for axis in axes} + sources = [] for source in dsDict.get("sources", ()): ufoLayerName = source.get("layername", defaultLayerName) @@ -264,7 +266,17 @@ def _unpackLocalDesignSpace(self, dsDict, ufoPath, defaultLayerName): "name", ufoLayerName if ufoLayerName != defaultLayerName else "", ) + + sourceLocation = {**self.defaultLocation, **source["location"]} + globalLocation = getGlobalPortionOfLocation(sourceLocation, localAxisNames) + dsSource = self.dsSources.findItem( + locationTuple=tuplifyLocation(globalLocation) + ) + assert dsSource is not None + ufoPath = dsSource.layer.path + ufoLayer = self.ufoLayers.findItem(path=ufoPath, name=ufoLayerName) + assert ufoLayer is not None sources.append( Source( name=sourceName, @@ -373,11 +385,7 @@ async def putGlyph(self, glyphName, glyph, unicodes): def _prepareUFOSourceLayer(self, source, localAxisNames, revLayerNameMapping): sourceLocation = {**self.defaultLocation, **source.location} - globalLocation = { - name: value - for name, value in sourceLocation.items() - if name not in localAxisNames - } + globalLocation = getGlobalPortionOfLocation(sourceLocation, localAxisNames) dsSource = self.dsSources.findItem( locationTuple=tuplifyLocation(globalLocation) @@ -928,3 +936,9 @@ def glyphHasVariableComponents(glyph): for layer in glyph.layers.values() for compo in layer.glyph.components ) + + +def getGlobalPortionOfLocation(location, localAxisNames): + return { + name: value for name, value in location.items() if name not in localAxisNames + } From d340ede088c381622dd86c541143d72cb5e39445 Mon Sep 17 00:00:00 2001 From: Just van Rossum Date: Mon, 4 Sep 2023 10:31:07 +0200 Subject: [PATCH 3/3] Adjust expected results after edited test font --- test-py/test_font.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test-py/test_font.py b/test-py/test_font.py index e4e4017ba..dff767aeb 100644 --- a/test-py/test_font.py +++ b/test-py/test_font.py @@ -446,6 +446,13 @@ "location": {"flip": 0, "flop": 100}, "name": "varco_flop", }, + { + "name": "weight=850,flip=100", + "layerName": "weight=850,flip=100", + "location": {"flip": 100, "weight": 850}, + "inactive": False, + "customData": {}, + }, ], "layers": { "MutatorSansLightCondensed/foreground": { @@ -529,6 +536,37 @@ "xAdvance": 500, }, }, + "weight=850,flip=100": { + "glyph": { + "path": { + "coordinates": [ + 70, + 278, + 452, + 278, + 522, + 278, + 522, + 380, + 522, + 664, + 204, + 664, + 204, + 588, + 70, + 588, + ], + "pointTypes": [0, 0, 0, 0, 0, 0, 0, 0], + "contourInfo": [{"endPoint": 7, "isClosed": True}], + }, + "components": [], + "xAdvance": 500, + "yAdvance": None, + "verticalOrigin": None, + }, + "customData": {}, + }, }, }, ),