Repository navigation
designspace v5 (take 2) - #418
Conversation
Adds the v5 elements: elidedfallbackname, axis STAT labels, top-level location labels, variable-fonts with axis-subsets, localised source family names, and instance location labels and localised names. The same structs handle 4.x and 5.x; the only API breakage is new pub fields on existing structs. An axis-subset is modelled as a name plus SubsetValue (Whole, Tent or Discrete), parsed via a raw struct rather than an untagged enum, which quick-xml can't handle. On save, format is bumped to the minimum version the content needs, as fontTools does.
|
Thank you for working on this! This LGTM. I added a tiny change to make sure the DSv5 test data exercises two probably seldom used attributes. About the various libs that have been added to element structs, I had the thought of extracting and parsing the |
| (None, None, None) => SubsetValue::Full, | ||
| _ => { | ||
| return Err(AxisSubsetError( | ||
| "axis-subset element must have min/max/default values or none at all", |
There was a problem hiding this comment.
so.. this error matches fontTools designspace reader
https://github.com/fonttools/fonttools/blob/718b61b552841de3964ba5b691fcf6102a2ebb3c/Lib/fontTools/designspaceLib/__init__.py#L2377
however the spec https://fonttools.readthedocs.io/en/latest/designspaceLib/xml.html#axis-subset-element explicitly makes userminimum, usermaximum and userdefault individually optional. The missing bounds come from the parent axis, whereas an omitted default should use the parent default clamped into the subset, something like max(subset_min, min(parent_default, subset_max)).
The problem is fontTools designspace writer is inconsistent with its reader: e.g. create an axis Weight 100/400/900 and a variable-font RangeAxisSubsetDescriptor(name=”Weight”, userMinimum=700), then serialize. fontTools writes:
<axis-subset name="Weight" userminimum="700"/>which both readers reject.
Since we are adding this here, might be worth following the spec and update fonttools impl separately?
There was a problem hiding this comment.
fwiw I opened fonttools/fonttools#4205 for the fontTools side.
For the model here, what if we fold Full into Range and make all three fields optional?
pub enum SubsetValue {
/// Missing values default to the parent axis (default clamped to the subset).
Range { minimum: Option<f64>, default: Option<f64>, maximum: Option<f64> },
Discrete(f64),
}That's how fontTools models it too (the whole axis is just a RangeAxisSubsetDescriptor with no bounds set), and it would avoid having two ways to spell the whole axis (Full vs an all-None Range). The TryFrom only needs to reject uservalue mixed with any of the range attributes. The all-None Range can be the #[default], maybe with an is_full() helper so we don't lose the readability of Full.
anthrotype
left a comment
There was a problem hiding this comment.
LGTM, but see my comments above on partial axis-subset ranges
Make the axis-subset range values individually optional, as the spec allows, and fold SubsetValue::Full into Range, per #418 (comment)
Make the axis-subset range values individually optional, as the spec allows, and fold SubsetValue::Full into Range, per #418 (comment)
Make the axis-subset range values individually optional, as the spec allows, and fold SubsetValue::Full into Range, per #418 (comment)
|
@cmyr @anthrotype What do you think of the font_info field idea above? I'm unsure if it's a good idea or not. |
I'd keep it out of the structs. With both a raw lib entry and a typed font_info field, it isn't clear which one wins when norad writes the file back. If anything, you could add an accessor that parses on demand, e.g. something like |
Adds the v5 elements from #416: elidedfallbackname, axis STAT labels, top-level location labels, variable-fonts with axis-subsets, localised source family names, and instance location labels and localised names. The same structs handle 4.x and 5.x; the only API breakage is new pub fields on existing structs.
An axis-subset is modelled as a name plus SubsetValue (Whole, Tent or Discrete), parsed via a raw struct rather than an untagged enum, which quick-xml can't handle. On save, format is bumped to the minimum version the content needs, as fontTools does.
Based on #340 by @madig; the test file is fontTools' test_v5.designspace plus his additions.