designSpaceDocument
designSpaceDocument copied to clipboard
Allow specifying instance coordinates in user space
If the designspace document has a map element, it is desirable that one be able to define instance locations in either the "user" space or "design" space. The default IMO should be design space, which matches what the sources are in.
I suggest we add an attribute to the location element that specifies the space. That will equally apply to source as well as instance elements.
An illustrative example. With the following axes:
<axes>
<axis default="1" maximum="1000" minimum="0" name="weight" tag="wght">
<labelname xml:lang="fa-IR">قطر</labelname>
<labelname xml:lang="en">Wéíght</labelname>
</axis>
<axis default="100" maximum="200" minimum="50" name="width" tag="wdth">
<map input="50.0" output="10.0" />
<map input="100.0" output="66.0" />
<map input="200.0" output="990.0" />
</axis>
</axes>
the following two instances point to the same conceptual location:
<instance ...>
<location>
<dimension name="width" xvalue="400" />
<dimension name="weight" xvalue="66" />
</location>
<kerning />
<info />
</instance>
and
<instance ...>
<location space="user">
<dimension name="width" xvalue="400" />
<dimension name="weight" xvalue="100" />
</location>
<kerning />
<info />
</instance>
One thing that still bothers me is that the axis default / minimum / maximum values are in the user space, whereas everything else is by default in the design space.
While I have your attention, let me suggest that an attribute of value be defined, that can be used when xvalue and yvalue are the same. Indeed, for OpenType varfonts, those two must match...
cc @anthrotype
@LettError any input?
Yeah, I was thinking.
- Do variable fonts allow multiple designspace points to map to a single userspace point?
- If we can calculate a single designspace point for any userspace point, could there be any practical problems arising from those coordinates being floats?
Do variable fonts allow multiple designspace points to map to a single userspace point? No. Currently avar requires that mapping be an increasing function. So it's well-defined to go back and forth.
If we can calculate a single designspace point for any userspace point, could there be any practical problems arising from those coordinates being floats?
No problem that I see.
- Currently Bender only transforms designspace to userspace.
- A cheap solution for going in the opposite direction would be to just build another mutator with the swapped values.
- Then when interpreting data all locations can be converted to designspace values (if they're not already) and everything can be executed normally.
For mutatorMath I've added a branch for some work on bender user spaces. https://github.com/LettError/MutatorMath/commit/499f9a05c04aff417702c6c798e39962fbcead5e
This lets the bender map in the userspace -> designspace direction. This can be used in the builder to make sure all coordinates are in designspace before making the mutators. Doesn't yet, but will look at it next.
Should axis extrema, master locations, instance locations, rule thresholds all be specifiable as mapped in userspace?
To be sure:
- user space is the value available to the user, the "output" attribute in the map element
- design space is the the "input" attribute from the map element.
I'm not happy with the names for the mapped and the unmapped spaces. Who is the user? and isn't it all "designspace"? So alternatively: "bent"/"flat", "warped"/"flat" ?
user space is the value available to the user, the "output" attribute in the map element design space is the the "input" attribute from the map element.
We've been using them in the other direction. "userspace" being mapping "input", and "designspace" being mapping "output". Only that way this mapping makes sense:
<axis default="400" maximum="900.0" minimum="100.0" name="weight" tag="wght">
<map input="100.0" output="26" />
<map input="200.0" output="39" />
<map input="300.0" output="58" />
<map input="400.0" output="90" />
<map input="500.0" output="108" />
<map input="600.0" output="128" />
<map input="700.0" output="151" />
<map input="800.0" output="169" />
<map input="900.0" output="190" />
<labelname xml:lang="en">Weight</labelname>
</axis>
I think axis default/min/max should default to "input" space. Ie. they define the user-visible range, and the mapping defines how to convert that to internal representation. For masters and instances allowing both would be great. I'm not sure how I feel about which space they should default to. I don't think it would be crazy to require explicit designation if axis maps are used.
I think the bender functions should also be retired and just replaced by a dictionary mapping...
Bender functions are retired.
"userspace" being mapping "input", and "designspace" being mapping "output". Only that way this mapping makes sense
this should probably be better documented as it's not that clear from the mere attribute names "input" and "output"
Let's make some move on this..