From 40c96c9855e4e3212491c6d14c89d8de0a479245 Mon Sep 17 00:00:00 2001 From: Just van Rossum Date: Mon, 4 Sep 2023 17:34:03 +0200 Subject: [PATCH] Compute the correct source location when a local axis exists with the same name as a global axis --- src/fontra/backends/designspace.py | 45 ++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/fontra/backends/designspace.py b/src/fontra/backends/designspace.py index 474d2d81f..345a787af 100644 --- a/src/fontra/backends/designspace.py +++ b/src/fontra/backends/designspace.py @@ -5,7 +5,7 @@ import os import pathlib from collections import defaultdict -from copy import copy, deepcopy +from copy import deepcopy from dataclasses import asdict, dataclass from datetime import datetime from functools import cache, cached_property @@ -205,16 +205,11 @@ async def getGlyph(self, glyphName): axes = [] sources = [] + localSources = [] layers = {} sourceNameMapping = {} layerNameMapping = {} - for dsSource in self.dsSources: - glyphSet = dsSource.layer.glyphSet - if glyphName not in glyphSet: - continue - sources.append(dsSource.newFontraSource()) - for ufoLayer in self.ufoLayers: if glyphName not in ufoLayer.glyphSet: continue @@ -226,11 +221,24 @@ async def getGlyph(self, glyphName): axes, localSources = self._unpackLocalDesignSpace( localDS, ufoLayer.name ) - sources.extend(localSources) sourceNameMapping = ufoGlyph.lib.get(SOURCE_NAME_MAPPING_LIB_KEY, {}) layerNameMapping = ufoGlyph.lib.get(LAYER_NAME_MAPPING_LIB_KEY, {}) layers[ufoLayer.fontraLayerName] = Layer(staticGlyph) + localDefaultOverride = { + axis.name: axis.defaultValue + for axis in axes + if axis.name in self.defaultLocation + } + + for dsSource in self.dsSources: + glyphSet = dsSource.layer.glyphSet + if glyphName not in glyphSet: + continue + sources.append(dsSource.newFontraSource(localDefaultOverride)) + + sources.extend(localSources) + if layerNameMapping: for source in sources: source.layerName = layerNameMapping.get( @@ -301,7 +309,7 @@ async def putGlyph(self, glyphName, glyph, unicodes): ) localAxes = packLocalAxes(glyph.axes) - localAxisNames = {axis.name for axis in glyph.axes} + localDefaultLocation = {axis.name: axis.defaultValue for axis in glyph.axes} # Prepare UFO source layers and local sources sourceNameMapping = {} @@ -309,7 +317,7 @@ async def putGlyph(self, glyphName, glyph, unicodes): localSources = [] for source in glyph.sources: sourceInfo = self._prepareUFOSourceLayer( - source, localAxisNames, revLayerNameMapping + source, localDefaultLocation, revLayerNameMapping ) if sourceInfo.sourceName != source.name: sourceNameMapping[sourceInfo.sourceName] = source.name @@ -385,10 +393,15 @@ async def putGlyph(self, glyphName, glyph, unicodes): self.savedGlyphModificationTimes[glyphName] = modTimes - def _prepareUFOSourceLayer(self, source, localAxisNames, revLayerNameMapping): + def _prepareUFOSourceLayer(self, source, localDefaultLocation, revLayerNameMapping): + sparseLocalLocation = { + name: source.location[name] + for name, value in localDefaultLocation.items() + if source.location.get(name, value) != value + } sourceLocation = {**self.defaultLocation, **source.location} globalLocation = self._getGlobalPortionOfLocation( - sourceLocation, localAxisNames + sourceLocation, localDefaultLocation ) dsSource = self.dsSources.findItem( @@ -397,7 +410,7 @@ def _prepareUFOSourceLayer(self, source, localAxisNames, revLayerNameMapping): if dsSource is None: dsSource = self._createDSSource(source, globalLocation) - if sourceLocation != globalLocation: + if sparseLocalLocation: ufoLayer = self.ufoLayers.findItem( fontraLayerName=revLayerNameMapping.get( source.layerName, source.layerName @@ -717,10 +730,12 @@ class DSSource: def locationTuple(self): return tuplifyLocation(self.location) - def newFontraSource(self): + def newFontraSource(self, localDefaultOverride=None): + if localDefaultOverride is None: + localDefaultOverride = {} return Source( name=self.name, - location=copy(self.location), + location={**self.location, **localDefaultOverride}, layerName=self.layer.fontraLayerName, )