-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[designspace] Can't generate variable font fixed axis subset #920
Comments
It's a current limitation of the implementation of designspace 5 in fontmake. The format allows you to specify that, and from an implementation point of view it would make sense and there's something we could do to produce what you specified, however it's more complicated than the case where there are sources at the locations where you want to slice and so it's not implemented at the moment. A related feature is the code in fontTools.instancer that implements slicing VFs in various ways. What you're asking for here sounds like "L4" as per the levels defined in the docs: https://fonttools.readthedocs.io/en/latest/varLib/instancer.html But I think the latest news are that L4 is not implemented either in fontTools.instancer: fonttools/fonttools#2157 |
Implementation idea in pseudo-code (not tested I mean) in case someone wants to take this: for _location, subSpace in ds.splitInterpolable():
# We split the big DS5 with potentially discrete axes into smaller spaces that are interpolable (no discrete axes)
instantiator = fontmake.instantiator.from_designspace(subSpace)
for vfName, vfSpace in subSpace.splitVariableFonts():
# vfSpace is a designspace for each <variable-font> element
axisExtremes = []
for axis in vfSpace.axes:
axisExtremes.append([
(axis.name, axis.minimum), (axis.name, axis.default), (axis.name, axis.maximum)
])
# Make the user locations of all "corners" of the designspace
cornerUserLocations = [dict(combo) for combo in itertools.product(*axisExtremes)]
for cornerUserLocation in cornerUserLocations:
# Make sure there's a source in that corner, if not create it with the instantiator and insert it
for source in vfSpace.sources:
if vfSpace.map_backward(source.getFullDesignLocation(vfSpace)) == cornerUserLocation:
break;
else:
# No source found
# Find the VF descriptor in subSpace so we can extract from it the axis-subsets with just 1 value
# (= coordinates of new default location)
for vf in subSpace.getVariableFonts():
if vf.name == name:
break;
vfRegion = fontTools.designspaceLib.types.getVFUserRegion(subSpace, vf)
newSourceUserLocation = {
**cornerUserLocation,
**{ axisName: value for axisName, value in vfRegion if isintance(value, numbers.Number) }
}
vfSpace.addSourceDescriptor(
location=vfSpace.map_forward(newSourceUserLocation),
font=instantiator.generate_instance(InstanceDescriptor(userLocation=cornerUserLocation))
)
# Then build the vfSpace designspace, it should work now because all the corners have been instantiated (edit: forgot to mix in the the axis subsets with just one value) |
Pinging on this |
@benkiel This is probably already obvious to you, but I think the FontTools Instancer would be able to handle this pretty well, in a post-build step. But, I agree that it would be great if it could be specified in and directly output from the designspace. |
Doing it with FontTools Instancer is a workaround: DS5 specified this as a huge convenience win, we have what we need in code now (at first it wasn't there), so this should be supported. |
Totally agreed! I found this because I am having a related issue (#1011), where an italic variable font fails even though it does have a source to support its default location. It just doesn’t have a location that matches the default of the entire designspace. |
Pinging on this; again this is a pretty large pain point and blocks some of the really nice benefits of DS5 (yes, back to that project and tested with the latest FontMake just now, same issue — really hoped that I wouldn't need to do a complex thing for information that is best encoded in the DS5 file. Post processing is hell) |
I have a large family with a weight and optical size axis. Currently trying to use designspace 5 to split the family into multiple variable fonts: specific values for weight with the whole optical size axis.
I get a
InvalidDesignSpaceData("No default source.")
error if I include a stop on the weight axis that doesn't have a corresponding source: i.e.uservalue="100"
works, as it has a corresponding source, butuservalue="200"
doesn't — it doesn't have a corresponding source in the sources for the weight axis.This is unexpected—I was under the impressing that you could slice to a specific value anywhere on an axis, which would be so very nice. This behavior isn't documented anywhere as far as I can find; is it the correct behavior?
The text was updated successfully, but these errors were encountered: