diff --git a/fontc/src/lib.rs b/fontc/src/lib.rs index 076773cf0..62b1b1cdc 100644 --- a/fontc/src/lib.rs +++ b/fontc/src/lib.rs @@ -1883,7 +1883,7 @@ mod tests { let font = FontRef::new(&buf).unwrap(); assert_eq!( - vec!["wght"], + vec!["CPHT", "wght"], font.fvar() .unwrap() .axes() @@ -1902,14 +1902,14 @@ mod tests { Rect::new(191.0, 0.0, 410.0, 761.0), ], vec![ - cbox_of_char(0x69, &font, vec![0.0]), // wght=400 - cbox_of_char(0x69, &font, vec![0.6]), // wght=700 - cbox_of_char(0x69, &font, vec![1.0]), // wght=900 + cbox_of_char(0x69, &font, vec![0.0, 0.0]), // CPHT=700, wght=400 + cbox_of_char(0x69, &font, vec![0.0, 0.6]), // CPHT=700, wght=700 + cbox_of_char(0x69, &font, vec![0.0, 1.0]), // CPHT=700, wght=900 ] ); - // glyph "I" (char 0x49) only defines two masters at wght=400 and wght=900, - // so wght=700 should be interpolated between them. + // glyph "I" (char 0x49) only defines two masters along wght at 400 and 900 + // (and default CPHT=700) so wght=700 should be interpolated between them. assert_eq!( vec![ Rect::new(231.0, 0.0, 364.0, 700.0), @@ -1917,11 +1917,29 @@ mod tests { Rect::new(171.0, 0.0, 424.0, 700.0), ], vec![ - cbox_of_char(0x49, &font, vec![0.0]), // wght=400 - cbox_of_char(0x49, &font, vec![0.6]), // wght=700 - cbox_of_char(0x49, &font, vec![1.0]), // wght=900 + cbox_of_char(0x49, &font, vec![0.0, 0.0]), // CPHT=700, wght=400 + cbox_of_char(0x49, &font, vec![0.0, 0.6]), // CPHT=700, wght=700 + cbox_of_char(0x49, &font, vec![0.0, 1.0]), // CPHT=700, wght=900 ] ); + + // glyph "I" also defines two additional ('virtual') masters along CPHT at 600 and 800 + // (and default wght=400), check that the cap-height (bbox.yMax) matches that throughout + // the wght axis. + assert_eq!( + vec![ + Rect::new(231.0, 0.0, 364.0, 600.0), + Rect::new(171.0, 0.0, 424.0, 600.0), + Rect::new(231.0, 0.0, 364.0, 800.0), + Rect::new(171.0, 0.0, 424.0, 800.0), + ], + vec![ + cbox_of_char(0x49, &font, vec![-1.0, 0.0]), // CPHT=600, wght=400 + cbox_of_char(0x49, &font, vec![-1.0, 1.0]), // CPHT=600, wght=900 + cbox_of_char(0x49, &font, vec![1.0, 0.0]), // CPHT=800, wght=400 + cbox_of_char(0x49, &font, vec![1.0, 1.0]), // CPHT=800, wght=900 + ] + ) } #[test] @@ -1939,9 +1957,7 @@ mod tests { #[test] fn intermediate_layer_in_designspace() { // https://github.com/googlefonts/fontc/issues/400 - assert_intermediate_layer( - "designspace_from_glyphs/IntermediateLayer/IntermediateLayer.designspace", - ); + assert_intermediate_layer("designspace_from_glyphs/IntermediateLayer.designspace"); } #[test] diff --git a/fontdrasil/src/coords.rs b/fontdrasil/src/coords.rs index c0a3b82bd..025bae04d 100644 --- a/fontdrasil/src/coords.rs +++ b/fontdrasil/src/coords.rs @@ -101,14 +101,14 @@ impl CoordConverter { /// Initialize a converter from just min/default/max user coords, e.g. a source with no mapping pub fn unmapped(min: UserCoord, default: UserCoord, max: UserCoord) -> CoordConverter { - CoordConverter::new( - vec![ - (min, DesignCoord::new(min.into_inner())), - (default, DesignCoord::new(default.into_inner())), - (max, DesignCoord::new(max.into_inner())), - ], - 1, - ) + let mut mappings = vec![ + (min, DesignCoord::new(min.into_inner())), + (default, DesignCoord::new(default.into_inner())), + (max, DesignCoord::new(max.into_inner())), + ]; + mappings.dedup(); + let default_idx = mappings.iter().position(|(u, _)| *u == default).unwrap(); + CoordConverter::new(mappings, default_idx) } /// Walk the vertices of the mappings, viewing the user/design/normalized value at each stop. @@ -550,4 +550,48 @@ mod tests { .into_inner() ); } + + #[test] + fn unmapped_coords_get_deduped() { + // min==default==max + assert_eq!( + CoordConverter::unmapped( + UserCoord(100.0.into()), + UserCoord(100.0.into()), + UserCoord(100.0.into()), + ) + .default_idx, + 0 + ); + // min==default>, // tag => (user:design) tuples pub axis_mappings: RawUserToDesignMapping, + pub virtual_masters: Vec>>, pub features: Vec, pub names: BTreeMap, pub instances: Vec, @@ -273,12 +274,19 @@ struct RawFont { pub custom_parameters: CustomParameters, } +// we use a vec of tuples instead of a map because there can be multiple +// values for the same name (e.g. 'Virtual Master') #[derive(Clone, Default, Debug, PartialEq, Eq, Hash)] -pub(crate) struct CustomParameters(BTreeMap); +pub(crate) struct CustomParameters(Vec<(String, CustomParameterValue)>); impl CustomParameters { + /// Get the first parameter with the given name, or `None` if not found. + fn get(&self, name: &str) -> Option<&CustomParameterValue> { + self.0.iter().find_map(|(n, v)| (n == name).then_some(v)) + } + fn int(&self, name: &str) -> Option { - let Some(CustomParameterValue::Int(i)) = self.0.get(name) else { + let Some(CustomParameterValue::Int(i)) = self.get(name) else { return None; }; Some(*i) @@ -289,40 +297,51 @@ impl CustomParameters { } fn string(&self, name: &str) -> Option<&str> { - let Some(CustomParameterValue::String(str)) = self.0.get(name) else { + let Some(CustomParameterValue::String(str)) = self.get(name) else { return None; }; Some(str) } fn axes(&self) -> Option<&Vec> { - let Some(CustomParameterValue::Axes(axes)) = self.0.get("Axes") else { + let Some(CustomParameterValue::Axes(axes)) = self.get("Axes") else { return None; }; Some(axes) } fn axis_mappings(&self) -> Option<&Vec> { - let Some(CustomParameterValue::AxesMappings(mappings)) = self.0.get("Axis Mappings") else { + let Some(CustomParameterValue::AxesMappings(mappings)) = self.get("Axis Mappings") else { return None; }; Some(mappings) } fn axis_locations(&self) -> Option<&Vec> { - let Some(CustomParameterValue::AxisLocations(locations)) = self.0.get("Axis Location") - else { + let Some(CustomParameterValue::AxisLocations(locations)) = self.get("Axis Location") else { return None; }; Some(locations) } fn glyph_order(&self) -> Option<&Vec> { - let Some(CustomParameterValue::GlyphOrder(names)) = self.0.get("glyphOrder") else { + let Some(CustomParameterValue::GlyphOrder(names)) = self.get("glyphOrder") else { return None; }; Some(names) } + + fn virtual_masters(&self) -> impl Iterator> { + self.0.iter().filter_map(|(name, value)| { + if name == "Virtual Master" { + let CustomParameterValue::VirtualMaster(locations) = value else { + panic!("Virtual Master parameter has wrong type!"); + }; + return Some(locations); + } + None + }) + } } #[derive(Clone, Debug, PartialEq, Eq, Hash)] @@ -333,13 +352,14 @@ enum CustomParameterValue { AxesMappings(Vec), AxisLocations(Vec), GlyphOrder(Vec), + VirtualMaster(Vec), } /// Hand-parse these because they take multiple shapes impl FromPlist for CustomParameters { fn parse(tokenizer: &mut Tokenizer<'_>) -> Result { use crate::plist::Error; - let mut params = BTreeMap::new(); + let mut params = Vec::new(); tokenizer.eat(b'(')?; @@ -415,6 +435,13 @@ impl FromPlist for CustomParameters { value = Some(CustomParameterValue::AxisLocations(tokenizer.parse()?)); } + _ if name == Some(String::from("Virtual Master")) => { + let Token::OpenParen = peek else { + return Err(Error::UnexpectedChar('(')); + }; + value = + Some(CustomParameterValue::VirtualMaster(tokenizer.parse()?)); + } _ => tokenizer.skip_rec()?, } } @@ -424,7 +451,7 @@ impl FromPlist for CustomParameters { } if let (Some(name), Some(value)) = (name, value) { - params.insert(name, value); + params.push((name, value)); } tokenizer.eat(b'}')?; @@ -1407,6 +1434,10 @@ impl RawAxisUserToDesignMap { pub fn iter(&self) -> impl Iterator, OrderedFloat)> { self.0.iter() } + + pub fn is_identity(&self) -> bool { + self.0.iter().all(|(u, d)| u == d) + } } impl RawUserToDesignMapping { @@ -1860,6 +1891,21 @@ impl TryFrom for Font { }) .collect(); + let virtual_masters = from + .custom_parameters + .virtual_masters() + .map(|vm| { + vm.iter() + .map( + |AxisLocation { + axis_name, + location, + }| (axis_name.clone(), *location), + ) + .collect() + }) + .collect(); + Ok(Font { units_per_em, use_typo_metrics, @@ -1871,6 +1917,7 @@ impl TryFrom for Font { glyph_order, glyph_to_codepoints, axis_mappings, + virtual_masters, features, names, instances, diff --git a/glyphs2fontir/src/source.rs b/glyphs2fontir/src/source.rs index 934cc9613..020252e0b 100644 --- a/glyphs2fontir/src/source.rs +++ b/glyphs2fontir/src/source.rs @@ -86,6 +86,7 @@ impl GlyphsIrSource { glyph_order: Default::default(), glyph_to_codepoints: Default::default(), axis_mappings: font.axis_mappings.clone(), + virtual_masters: Default::default(), features: Default::default(), names: Default::default(), instances: font.instances.clone(), @@ -114,6 +115,7 @@ impl GlyphsIrSource { glyph_order: Default::default(), glyph_to_codepoints: Default::default(), axis_mappings: Default::default(), + virtual_masters: Default::default(), features: Default::default(), names: Default::default(), instances: font.instances.clone(), @@ -804,20 +806,16 @@ impl Work for GlyphIrWork { } } - // It's helpful if glyphs are defined at min, default, and max (some of which may be cooincident) + // It's helpful if glyphs are defined at default for axis in axes.iter() { - let min = axis.min.to_normalized(&axis.converter); - let max = axis.max.to_normalized(&axis.converter); - let default = axis.max.to_normalized(&axis.converter); + let default = axis.default.to_normalized(&axis.converter); let Some(positions) = axis_positions.get(&axis.tag) else { return Err(WorkError::NoAxisPosition( self.glyph_name.clone(), axis.name.clone(), )); }; - check_pos(&self.glyph_name, positions, axis, &min)?; check_pos(&self.glyph_name, positions, axis, &default)?; - check_pos(&self.glyph_name, positions, axis, &max)?; } context.anchors.set(ir_anchors.try_into()?); @@ -1206,25 +1204,6 @@ mod tests { assert_eq!(expected_locations, actual_locations); } - #[test] - fn glyph_must_define_min() { - let glyph_name = GlyphName::from("min-undefined"); - let (source, context) = build_static_metadata(glyphs2_dir().join("MinUndef.glyphs")); - let result = build_glyphs(&source, &context, &[&glyph_name]); - assert!(result.is_err()); - let Err(WorkError::GlyphUndefAtNormalizedPosition { - glyph_name, - axis, - pos, - }) = result - else { - panic!("Wrong error"); - }; - assert_eq!("min-undefined", glyph_name.as_str()); - assert_eq!(Tag::new(b"wght"), axis); - assert_eq!(NormalizedCoord::new(-1.0), pos); - } - #[test] fn read_axis_location() { let (_, context) = build_static_metadata(glyphs3_dir().join("WghtVar_AxisLocation.glyphs")); diff --git a/glyphs2fontir/src/toir.rs b/glyphs2fontir/src/toir.rs index 251b89b6a..8b6138330 100644 --- a/glyphs2fontir/src/toir.rs +++ b/glyphs2fontir/src/toir.rs @@ -179,7 +179,9 @@ fn to_ir_axis( let min = DesignCoord::new(min); let max = DesignCoord::new(max); - let converter = if font.axis_mappings.contains(&axis.name) { + let converter = if font.axis_mappings.contains(&axis.name) + && !font.axis_mappings.get(&axis.name).unwrap().is_identity() + { let mappings: Vec<_> = font .axis_mappings .get(&axis.name) @@ -193,7 +195,7 @@ fn to_ir_axis( find_by_design_coord(&mappings, max, axis.name.as_str(), "max")?; CoordConverter::new(mappings, default_idx) } else { - // There is no mapping; design == user + // There is no meaningful mapping; design == user let min = UserCoord::new(min.into_inner()); let max = UserCoord::new(max.into_inner()); let default = UserCoord::new(default.into_inner()); @@ -226,7 +228,22 @@ fn ir_axes(font: &Font) -> Result, Error> { .iter() .enumerate() .map(|(idx, glyphs_axis)| { - let axis_values: Vec<_> = font.masters.iter().map(|m| m.axes_values[idx]).collect(); + let axis_values: Vec<_> = font + .masters + .iter() + .map(|m| m.axes_values[idx]) + // extend the masters' axis values with the virtual masters' if any; + // they will be used to compute the axis min/max values + .chain(font.virtual_masters.iter().flat_map(|vm| { + vm.iter().filter_map(|(axis_name, location)| { + if axis_name == &glyphs_axis.name { + Some(*location) + } else { + None + } + }) + })) + .collect(); to_ir_axis(font, &axis_values, font.default_master_idx, glyphs_axis) }) .collect() diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/H_.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/H_.glif new file mode 100644 index 000000000..eec084f7f --- /dev/null +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/H_.glif @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/acutecomb.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/acutecomb.glif new file mode 100644 index 000000000..2ae65e27f --- /dev/null +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/acutecomb.glif @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + com.schriftgestaltung.Glyphs.originalWidth + 300 + + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/contents.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/contents.plist index 7c4bd3c61..e7eb32de2 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/contents.plist +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/contents.plist @@ -4,10 +4,18 @@ .notdef _notdef.glif + H + H_.glif I I_.glif + acutecomb + acutecomb.glif i i.glif + iacute + iacute.glif + idotless + idotless.glif space space.glif diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/i.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/i.glif index 7d7b6e138..060cec82e 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/i.glif +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/i.glif @@ -17,11 +17,12 @@ - - - - - - + + + + com.schriftgestaltung.Glyphs.shapeOrder + PC + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/iacute.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/iacute.glif new file mode 100644 index 000000000..f2e0dd522 --- /dev/null +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/iacute.glif @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/idotless.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/idotless.glif new file mode 100644 index 000000000..853e4608d --- /dev/null +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/glyphs/idotless.glif @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/lib.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/lib.plist index f8f894772..561c12b14 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/lib.plist +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Black.ufo/lib.plist @@ -34,6 +34,37 @@ + com.schriftgestaltung.customParameter.GSFont.Virtual Master + + + + Axis + Cap Height + Location + 600 + + + Axis + Weight + Location + 400 + + + + + Axis + Cap Height + Location + 800 + + + Axis + Weight + Location + 400 + + + com.schriftgestaltung.customParameter.GSFont.Write lastChange 0 com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment @@ -51,21 +82,35 @@ com.schriftgestaltung.customParameter.GSFontMaster.iconName com.schriftgestaltung.customParameter.GSFontMaster.weightValue - 900 + 700 com.schriftgestaltung.customParameter.GSFontMaster.widthValue - 100 + 900 com.schriftgestaltung.fontMasterOrder 1 com.schriftgestaltung.weightValue - 900 + 700 com.schriftgestaltung.widthValue - 100 + 900 public.glyphOrder .notdef space + H I i + idotless + acutecomb + iacute + public.openTypeCategories + + acutecomb + mark + + public.postscriptNames + + idotless + dotlessi + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{600, 400}/H_.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{600, 400}/H_.glif new file mode 100644 index 000000000..a545a4f4f --- /dev/null +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{600, 400}/H_.glif @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/I_.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{600, 400}/I_.glif similarity index 75% rename from resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/I_.glif rename to resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{600, 400}/I_.glif index 300f81c9e..4f623779e 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/I_.glif +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{600, 400}/I_.glif @@ -4,10 +4,10 @@ - + - + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs.{700}/contents.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{600, 400}/contents.plist similarity index 67% rename from resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs.{700}/contents.plist rename to resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{600, 400}/contents.plist index c097e8fa1..cdb4fba2f 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs.{700}/contents.plist +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{600, 400}/contents.plist @@ -2,7 +2,9 @@ - i - i.glif + H + H_.glif + I + I_.glif diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700}/contents.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700, 700}/contents.plist similarity index 80% rename from resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700}/contents.plist rename to resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700, 700}/contents.plist index c097e8fa1..a1a3ff4b9 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700}/contents.plist +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700, 700}/contents.plist @@ -4,5 +4,7 @@ i i.glif + idotless + idotless.glif diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700}/i.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700, 700}/i.glif similarity index 76% rename from resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700}/i.glif rename to resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700, 700}/i.glif index 0b54988c4..5d484034b 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700}/i.glif +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700, 700}/i.glif @@ -17,11 +17,12 @@ - - - - - - + + + + com.schriftgestaltung.Glyphs.shapeOrder + PC + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700, 700}/idotless.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700, 700}/idotless.glif new file mode 100644 index 000000000..dde3d4915 --- /dev/null +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{700, 700}/idotless.glif @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{800, 400}/H_.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{800, 400}/H_.glif new file mode 100644 index 000000000..a331f5e94 --- /dev/null +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{800, 400}/H_.glif @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/I_.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{800, 400}/I_.glif similarity index 51% rename from resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/I_.glif rename to resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{800, 400}/I_.glif index ac39c32b3..974f41869 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/I_.glif +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{800, 400}/I_.glif @@ -4,10 +4,10 @@ - - - - + + + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/contents.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{800, 400}/contents.plist similarity index 60% rename from resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/contents.plist rename to resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{800, 400}/contents.plist index 7c4bd3c61..cdb4fba2f 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/contents.plist +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs.{800, 400}/contents.plist @@ -2,13 +2,9 @@ - .notdef - _notdef.glif + H + H_.glif I I_.glif - i - i.glif - space - space.glif diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/H_.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/H_.glif new file mode 100644 index 000000000..078df0d04 --- /dev/null +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/H_.glif @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/acutecomb.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/acutecomb.glif new file mode 100644 index 000000000..339593f72 --- /dev/null +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/acutecomb.glif @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + com.schriftgestaltung.Glyphs.originalWidth + 300 + + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/contents.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/contents.plist index 7c4bd3c61..e7eb32de2 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/contents.plist +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/contents.plist @@ -4,10 +4,18 @@ .notdef _notdef.glif + H + H_.glif I I_.glif + acutecomb + acutecomb.glif i i.glif + iacute + iacute.glif + idotless + idotless.glif space space.glif diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/i.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/i.glif index 1905c4d48..d18db32ab 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/i.glif +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/i.glif @@ -17,11 +17,12 @@ - - - - - - + + + + com.schriftgestaltung.Glyphs.shapeOrder + PC + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/iacute.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/iacute.glif new file mode 100644 index 000000000..afdb6ecc7 --- /dev/null +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/iacute.glif @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/idotless.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/idotless.glif new file mode 100644 index 000000000..5fba88edb --- /dev/null +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/glyphs/idotless.glif @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/layercontents.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/layercontents.plist index d11f2dfca..0c10b5c80 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/layercontents.plist +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/layercontents.plist @@ -7,8 +7,16 @@ glyphs - {700} - glyphs.{700} + {600, 400} + glyphs.{600, 400} + + + {800, 400} + glyphs.{800, 400} + + + {700, 700} + glyphs.{700, 700} diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/lib.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/lib.plist index 879fd8100..e382319bf 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/lib.plist +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer-Regular.ufo/lib.plist @@ -34,6 +34,37 @@ + com.schriftgestaltung.customParameter.GSFont.Virtual Master + + + + Axis + Cap Height + Location + 600 + + + Axis + Weight + Location + 400 + + + + + Axis + Cap Height + Location + 800 + + + Axis + Weight + Location + 400 + + + com.schriftgestaltung.customParameter.GSFont.Write lastChange 0 com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment @@ -51,21 +82,35 @@ com.schriftgestaltung.customParameter.GSFontMaster.iconName com.schriftgestaltung.customParameter.GSFontMaster.weightValue - 400 + 700 com.schriftgestaltung.customParameter.GSFontMaster.widthValue - 100 + 400 com.schriftgestaltung.fontMasterOrder 0 com.schriftgestaltung.weightValue - 400 + 700 com.schriftgestaltung.widthValue - 100 + 400 public.glyphOrder .notdef space + H I i + idotless + acutecomb + iacute + public.openTypeCategories + + acutecomb + mark + + public.postscriptNames + + idotless + dotlessi + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer.designspace b/resources/testdata/designspace_from_glyphs/IntermediateLayer.designspace index 72e92c517..1e5464d8f 100644 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer.designspace +++ b/resources/testdata/designspace_from_glyphs/IntermediateLayer.designspace @@ -1,6 +1,7 @@ + @@ -10,16 +11,31 @@ + - + + + + + + + + + + + + + + + @@ -27,16 +43,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/fontinfo.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/fontinfo.plist deleted file mode 100644 index 5ead060a1..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/fontinfo.plist +++ /dev/null @@ -1,56 +0,0 @@ - - - - - ascender - 800 - capHeight - 700 - descender - -200 - familyName - Intermediate Layer - italicAngle - 0 - openTypeHeadCreated - 2023/07/20 13:49:39 - openTypeOS2Type - - 3 - - postscriptBlueValues - - -16 - 0 - 500 - 516 - 700 - 716 - 800 - 816 - - postscriptOtherBlues - - -216 - -200 - - postscriptUnderlinePosition - -100 - postscriptUnderlineThickness - 50 - styleMapFamilyName - Intermediate Layer Black - styleMapStyleName - regular - styleName - Black - unitsPerEm - 1000 - versionMajor - 1 - versionMinor - 0 - xHeight - 500 - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/_notdef.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/_notdef.glif deleted file mode 100644 index 4bf333dc3..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/_notdef.glif +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/contents.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/contents.plist deleted file mode 100644 index 7c4bd3c61..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/contents.plist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - .notdef - _notdef.glif - I - I_.glif - i - i.glif - space - space.glif - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/i.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/i.glif deleted file mode 100644 index 7d7b6e138..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/i.glif +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/space.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/space.glif deleted file mode 100644 index 983348125..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/glyphs/space.glif +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/layercontents.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/layercontents.plist deleted file mode 100644 index b9c1a4f27..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/layercontents.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - public.default - glyphs - - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/lib.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/lib.plist deleted file mode 100644 index f8f894772..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/lib.plist +++ /dev/null @@ -1,71 +0,0 @@ - - - - - com.github.googlei18n.ufo2ft.featureWriters - - - class - KernFeatureWriter - - - class - ContextualMarkFeatureWriter - module - glyphsLib.featureWriters.markFeatureWriter - - - class - GdefFeatureWriter - - - class - CursFeatureWriter - - - com.github.googlei18n.ufo2ft.filters - - - name - eraseOpenCorners - namespace - glyphsLib.filters - pre - - - - com.schriftgestaltung.customParameter.GSFont.Write lastChange - 0 - com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment - - com.schriftgestaltung.customParameter.GSFont.useNiceNames - 1 - com.schriftgestaltung.customParameter.GSFontMaster.customValue - 0 - com.schriftgestaltung.customParameter.GSFontMaster.customValue1 - 0 - com.schriftgestaltung.customParameter.GSFontMaster.customValue2 - 0 - com.schriftgestaltung.customParameter.GSFontMaster.customValue3 - 0 - com.schriftgestaltung.customParameter.GSFontMaster.iconName - - com.schriftgestaltung.customParameter.GSFontMaster.weightValue - 900 - com.schriftgestaltung.customParameter.GSFontMaster.widthValue - 100 - com.schriftgestaltung.fontMasterOrder - 1 - com.schriftgestaltung.weightValue - 900 - com.schriftgestaltung.widthValue - 100 - public.glyphOrder - - .notdef - space - I - i - - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/metainfo.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/metainfo.plist deleted file mode 100644 index 7b8b34ac6..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Black.ufo/metainfo.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - creator - com.github.fonttools.ufoLib - formatVersion - 3 - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/fontinfo.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/fontinfo.plist deleted file mode 100644 index 23fb34250..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/fontinfo.plist +++ /dev/null @@ -1,56 +0,0 @@ - - - - - ascender - 800 - capHeight - 700 - descender - -200 - familyName - Intermediate Layer - italicAngle - 0 - openTypeHeadCreated - 2023/07/20 13:49:39 - openTypeOS2Type - - 3 - - postscriptBlueValues - - -16 - 0 - 500 - 516 - 700 - 716 - 800 - 816 - - postscriptOtherBlues - - -216 - -200 - - postscriptUnderlinePosition - -100 - postscriptUnderlineThickness - 50 - styleMapFamilyName - Intermediate Layer - styleMapStyleName - regular - styleName - Regular - unitsPerEm - 1000 - versionMajor - 1 - versionMinor - 0 - xHeight - 500 - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs.{700}/i.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs.{700}/i.glif deleted file mode 100644 index 0b54988c4..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs.{700}/i.glif +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/_notdef.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/_notdef.glif deleted file mode 100644 index 4bf333dc3..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/_notdef.glif +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/i.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/i.glif deleted file mode 100644 index 1905c4d48..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/i.glif +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/space.glif b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/space.glif deleted file mode 100644 index 983348125..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/glyphs/space.glif +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/layercontents.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/layercontents.plist deleted file mode 100644 index d11f2dfca..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/layercontents.plist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - public.default - glyphs - - - {700} - glyphs.{700} - - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/lib.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/lib.plist deleted file mode 100644 index 879fd8100..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/lib.plist +++ /dev/null @@ -1,71 +0,0 @@ - - - - - com.github.googlei18n.ufo2ft.featureWriters - - - class - KernFeatureWriter - - - class - ContextualMarkFeatureWriter - module - glyphsLib.featureWriters.markFeatureWriter - - - class - GdefFeatureWriter - - - class - CursFeatureWriter - - - com.github.googlei18n.ufo2ft.filters - - - name - eraseOpenCorners - namespace - glyphsLib.filters - pre - - - - com.schriftgestaltung.customParameter.GSFont.Write lastChange - 0 - com.schriftgestaltung.customParameter.GSFont.disablesAutomaticAlignment - - com.schriftgestaltung.customParameter.GSFont.useNiceNames - 1 - com.schriftgestaltung.customParameter.GSFontMaster.customValue - 0 - com.schriftgestaltung.customParameter.GSFontMaster.customValue1 - 0 - com.schriftgestaltung.customParameter.GSFontMaster.customValue2 - 0 - com.schriftgestaltung.customParameter.GSFontMaster.customValue3 - 0 - com.schriftgestaltung.customParameter.GSFontMaster.iconName - - com.schriftgestaltung.customParameter.GSFontMaster.weightValue - 400 - com.schriftgestaltung.customParameter.GSFontMaster.widthValue - 100 - com.schriftgestaltung.fontMasterOrder - 0 - com.schriftgestaltung.weightValue - 400 - com.schriftgestaltung.widthValue - 100 - public.glyphOrder - - .notdef - space - I - i - - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/metainfo.plist b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/metainfo.plist deleted file mode 100644 index 7b8b34ac6..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer-Regular.ufo/metainfo.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - creator - com.github.fonttools.ufoLib - formatVersion - 3 - - diff --git a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer.designspace b/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer.designspace deleted file mode 100644 index 6b25d37ae..000000000 --- a/resources/testdata/designspace_from_glyphs/IntermediateLayer/IntermediateLayer.designspace +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GSDontShowVersionAlert - 1 - - - diff --git a/resources/testdata/glyphs2/IntermediateLayer.glyphs b/resources/testdata/glyphs2/IntermediateLayer.glyphs index 0b381e4a5..ca521edca 100644 --- a/resources/testdata/glyphs2/IntermediateLayer.glyphs +++ b/resources/testdata/glyphs2/IntermediateLayer.glyphs @@ -1,10 +1,5 @@ { -.appVersion = "3210"; -DisplayStrings = ( -i, -I, -"/.notdef" -); +.appVersion = "3226"; customParameters = ( { name = "Disable Last Change"; @@ -15,14 +10,48 @@ name = glyphOrder; value = ( .notdef, space, +H, I, -i +i, +idotless, +acutecomb, +iacute +); +}, +{ +name = "Virtual Master"; +value = ( +{ +Axis = "Cap Height"; +Location = 600; +}, +{ +Axis = Weight; +Location = 400; +} +); +}, +{ +name = "Virtual Master"; +value = ( +{ +Axis = "Cap Height"; +Location = 800; +}, +{ +Axis = Weight; +Location = 400; +} ); }, { name = Axes; value = ( { +Name = "Cap Height"; +Tag = CPHT; +}, +{ Name = Weight; Tag = wght; } @@ -44,7 +73,8 @@ ascender = 800; capHeight = 700; descender = -200; id = "F969B945-4602-464F-B67C-A69BED6E6A4A"; -weightValue = 400; +weightValue = 700; +widthValue = 400; xHeight = 500; }, { @@ -60,7 +90,8 @@ capHeight = 700; custom = Black; descender = -200; id = m01; -weightValue = 900; +weightValue = 700; +widthValue = 900; xHeight = 500; } ); @@ -133,6 +164,148 @@ width = 600; unicode = 0020; }, { +glyphname = H; +layers = ( +{ +layerId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +paths = ( +{ +closed = 1; +nodes = ( +"31 0 LINE", +"164 0 LINE", +"164 700 LINE", +"31 700 LINE" +); +}, +{ +closed = 1; +nodes = ( +"431 0 LINE", +"564 0 LINE", +"564 700 LINE", +"431 700 LINE" +); +}, +{ +closed = 1; +nodes = ( +"89 324 LINE", +"508 324 LINE", +"508 439 LINE", +"89 439 LINE" +); +} +); +width = 600; +}, +{ +associatedMasterId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +layerId = "674E3FAD-1F7C-4698-A483-3B70C8F3D3AE"; +name = "{600, 400}"; +paths = ( +{ +closed = 1; +nodes = ( +"31 0 LINE", +"164 0 LINE", +"164 600 LINE", +"31 600 LINE" +); +}, +{ +closed = 1; +nodes = ( +"431 0 LINE", +"564 0 LINE", +"564 600 LINE", +"431 600 LINE" +); +}, +{ +closed = 1; +nodes = ( +"89 274 LINE", +"508 274 LINE", +"508 389 LINE", +"89 389 LINE" +); +} +); +width = 600; +}, +{ +associatedMasterId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +layerId = "1FD5C09D-F887-4ED3-BF54-15FEA26CDF14"; +name = "{800, 400}"; +paths = ( +{ +closed = 1; +nodes = ( +"31 0 LINE", +"164 0 LINE", +"164 800 LINE", +"31 800 LINE" +); +}, +{ +closed = 1; +nodes = ( +"431 0 LINE", +"564 0 LINE", +"564 800 LINE", +"431 800 LINE" +); +}, +{ +closed = 1; +nodes = ( +"89 379 LINE", +"508 379 LINE", +"508 494 LINE", +"89 494 LINE" +); +} +); +width = 600; +}, +{ +layerId = m01; +paths = ( +{ +closed = 1; +nodes = ( +"31 0 LINE", +"214 0 LINE", +"214 700 LINE", +"31 700 LINE" +); +}, +{ +closed = 1; +nodes = ( +"381 0 LINE", +"564 0 LINE", +"564 700 LINE", +"381 700 LINE" +); +}, +{ +closed = 1; +nodes = ( +"99 304 LINE", +"508 304 LINE", +"508 459 LINE", +"99 459 LINE" +); +} +); +width = 600; +} +); +unicode = 0048; +}, +{ glyphname = I; layers = ( { @@ -151,6 +324,40 @@ nodes = ( width = 600; }, { +associatedMasterId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +layerId = "1DD0DB79-DD15-42DF-A361-B703688AC628"; +name = "{600, 400}"; +paths = ( +{ +closed = 1; +nodes = ( +"231 0 LINE", +"364 0 LINE", +"364 600 LINE", +"231 600 LINE" +); +} +); +width = 600; +}, +{ +associatedMasterId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +layerId = "6550B861-E396-4850-9BB2-CA4B38E05F2F"; +name = "{800, 400}"; +paths = ( +{ +closed = 1; +nodes = ( +"231 0 LINE", +"364 0 LINE", +"364 800 LINE", +"231 800 LINE" +); +} +); +width = 600; +}, +{ layerId = m01; paths = ( { @@ -172,6 +379,11 @@ unicode = 0049; glyphname = i; layers = ( { +components = ( +{ +name = idotless; +} +); layerId = m01; paths = ( { @@ -190,20 +402,16 @@ nodes = ( "243 546 OFFCURVE", "303 546 CURVE SMOOTH" ); -}, -{ -closed = 1; -nodes = ( -"404 0 LINE", -"404 500 LINE", -"191 500 LINE", -"191 0 LINE" -); } ); width = 600; }, { +components = ( +{ +name = idotless; +} +); layerId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; paths = ( { @@ -222,23 +430,19 @@ nodes = ( "267.333 584 OFFCURVE", "302 584 CURVE SMOOTH" ); -}, -{ -closed = 1; -nodes = ( -"354 0 LINE", -"354 500 LINE", -"241 500 LINE", -"241 0 LINE" -); } ); width = 600; }, { associatedMasterId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +components = ( +{ +name = idotless; +} +); layerId = "5807B081-E05E-4C8E-94C2-CB3F0EF9A1F4"; -name = "{700}"; +name = "{700, 700}"; paths = ( { closed = 1; @@ -256,8 +460,52 @@ nodes = ( "252 556 OFFCURVE", "301 556 CURVE SMOOTH" ); +} +); +width = 600; +} +); +unicode = 0069; }, { +glyphname = idotless; +layers = ( +{ +layerId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +paths = ( +{ +closed = 1; +nodes = ( +"354 0 LINE", +"354 500 LINE", +"241 500 LINE", +"241 0 LINE" +); +} +); +width = 600; +}, +{ +layerId = m01; +paths = ( +{ +closed = 1; +nodes = ( +"404 0 LINE", +"404 500 LINE", +"191 500 LINE", +"191 0 LINE" +); +} +); +width = 600; +}, +{ +associatedMasterId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +layerId = "5AB430A1-B6BB-4175-8EC8-C9DE3FBA6DF5"; +name = "{700, 700}"; +paths = ( +{ closed = 1; nodes = ( "374 0 LINE", @@ -270,12 +518,81 @@ nodes = ( width = 600; } ); -unicode = 0069; +unicode = 0131; +}, +{ +glyphname = acutecomb; +layers = ( +{ +layerId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +paths = ( +{ +closed = 1; +nodes = ( +"68 637 LINE", +"149 637 LINE", +"328 800 LINE", +"206 802 LINE" +); +} +); +width = 300; +}, +{ +layerId = m01; +paths = ( +{ +closed = 1; +nodes = ( +"68 637 LINE", +"206 637 LINE", +"427 814 LINE", +"225 814 LINE" +); +} +); +width = 300; +} +); +unicode = 0301; +}, +{ +glyphname = iacute; +layers = ( +{ +components = ( +{ +name = idotless; +}, +{ +name = acutecomb; +transform = "{1, 0, 0, 1, 184, -26}"; +} +); +layerId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +width = 600; +}, +{ +components = ( +{ +name = idotless; +}, +{ +name = acutecomb; +transform = "{1, 0, 0, 1, 159, -38}"; +} +); +layerId = m01; +width = 600; +} +); +unicode = 00ED; } ); instances = ( { -interpolationWeight = 400; +interpolationWeight = 700; +interpolationWidth = 400; instanceInterpolations = { "F969B945-4602-464F-B67C-A69BED6E6A4A" = 1; }; @@ -283,6 +600,7 @@ name = Regular; }, { interpolationWeight = 700; +interpolationWidth = 700; instanceInterpolations = { "F969B945-4602-464F-B67C-A69BED6E6A4A" = 0.4; m01 = 0.6; @@ -292,12 +610,68 @@ name = Bold; weightClass = Bold; }, { -interpolationWeight = 900; +interpolationWeight = 700; +interpolationWidth = 900; instanceInterpolations = { m01 = 1; }; name = Black; weightClass = Black; +}, +{ +interpolationWeight = 600; +interpolationWidth = 400; +instanceInterpolations = { +"F969B945-4602-464F-B67C-A69BED6E6A4A" = 1; +}; +name = "Short Caps"; +}, +{ +interpolationWeight = 600; +interpolationWidth = 700; +instanceInterpolations = { +"F969B945-4602-464F-B67C-A69BED6E6A4A" = 0.4; +m01 = 0.6; +}; +name = "Short Caps Bold"; +weightClass = Bold; +}, +{ +interpolationWeight = 600; +interpolationWidth = 900; +instanceInterpolations = { +m01 = 1; +}; +name = "Short Caps Black"; +weightClass = Black; +}, +{ +interpolationWeight = 800; +interpolationWidth = 400; +instanceInterpolations = { +"F969B945-4602-464F-B67C-A69BED6E6A4A" = 1; +}; +name = "Tall Caps"; +}, +{ +interpolationWeight = 800; +interpolationWidth = 700; +instanceInterpolations = { +"F969B945-4602-464F-B67C-A69BED6E6A4A" = 0.4; +m01 = 0.6; +}; +name = "Tall Caps Bold"; +weightClass = Bold; +}, +{ +interpolationWeight = 800; +interpolationWidth = 700; +instanceInterpolations = { +"F969B945-4602-464F-B67C-A69BED6E6A4A" = 0.4; +m01 = 0.6; +}; +name = "Tall Caps Black"; +weightClass = Black; } ); unitsPerEm = 1000; diff --git a/resources/testdata/glyphs2/MinUndef.glyphs b/resources/testdata/glyphs2/MinUndef.glyphs deleted file mode 100644 index 697ce6a46..000000000 --- a/resources/testdata/glyphs2/MinUndef.glyphs +++ /dev/null @@ -1,70 +0,0 @@ -{ -.appVersion = "3148"; -customParameters = ( -{ -name = Axes; -value = ( -{ -Name = Weight; -Tag = wght; -} -); -}, -{ -name = "Variable Font Origin"; -value = "medium"; -} -); -date = "2022-12-01 04:52:20 +0000"; -familyName = WghtVar; -fontMaster = ( -{ -ascender = 800; -capHeight = 0; -descender = -200; -id = thin; -weightValue = 200; -xHeight = 0; -}, -{ -ascender = 800; -capHeight = 500; -descender = -200; -id = "medium"; -weight = Medium; -weightValue = 500; -xHeight = 400; -}, -{ -ascender = 800; -capHeight = 700; -descender = -200; -id = "bold"; -weight = Bold; -weightValue = 700; -xHeight = 500; -} -); -glyphs = ( -{ -glyphname = "min-undefined"; -lastChange = "2022-12-01 05:10:49 +0000"; -layers = ( -{ -layerId = medium; -paths = (); -width = 600; -}, -{ -layerId = "bold"; -paths = (); -width = 600; -} -); -unicode = 0021; -} -); -unitsPerEm = 1000; -versionMajor = 1; -versionMinor = 0; -} \ No newline at end of file diff --git a/resources/testdata/glyphs3/IntermediateLayer.glyphs b/resources/testdata/glyphs3/IntermediateLayer.glyphs index b323c113a..fbeeea4db 100644 --- a/resources/testdata/glyphs3/IntermediateLayer.glyphs +++ b/resources/testdata/glyphs3/IntermediateLayer.glyphs @@ -1,13 +1,12 @@ { -.appVersion = "3210"; +.appVersion = "3226"; .formatVersion = 3; -DisplayStrings = ( -i, -I, -"/.notdef" -); axes = ( { +name = "Cap Height"; +tag = CPHT; +}, +{ name = Weight; tag = wght; } @@ -22,8 +21,38 @@ name = glyphOrder; value = ( .notdef, space, +H, I, -i +i, +idotless, +acutecomb, +iacute +); +}, +{ +name = "Virtual Master"; +value = ( +{ +Axis = "Cap Height"; +Location = 600; +}, +{ +Axis = Weight; +Location = 400; +} +); +}, +{ +name = "Virtual Master"; +value = ( +{ +Axis = "Cap Height"; +Location = 800; +}, +{ +Axis = Weight; +Location = 400; +} ); } ); @@ -32,6 +61,7 @@ familyName = "Intermediate Layer"; fontMaster = ( { axesValues = ( +700, 400 ); id = "F969B945-4602-464F-B67C-A69BED6E6A4A"; @@ -62,6 +92,7 @@ name = Regular; }, { axesValues = ( +700, 900 ); id = m01; @@ -86,7 +117,6 @@ over = -16; pos = -200; }, { -over = -16; } ); name = Black; @@ -161,6 +191,160 @@ width = 600; unicode = 32; }, { +glyphname = H; +layers = ( +{ +layerId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +shapes = ( +{ +closed = 1; +nodes = ( +(31,0,l), +(164,0,l), +(164,700,l), +(31,700,l) +); +}, +{ +closed = 1; +nodes = ( +(431,0,l), +(564,0,l), +(564,700,l), +(431,700,l) +); +}, +{ +closed = 1; +nodes = ( +(89,324,l), +(508,324,l), +(508,439,l), +(89,439,l) +); +} +); +width = 600; +}, +{ +associatedMasterId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +attr = { +coordinates = ( +600, +400 +); +}; +layerId = "674E3FAD-1F7C-4698-A483-3B70C8F3D3AE"; +name = "8 Nov 23 at 15:24"; +shapes = ( +{ +closed = 1; +nodes = ( +(31,0,l), +(164,0,l), +(164,600,l), +(31,600,l) +); +}, +{ +closed = 1; +nodes = ( +(431,0,l), +(564,0,l), +(564,600,l), +(431,600,l) +); +}, +{ +closed = 1; +nodes = ( +(89,274,l), +(508,274,l), +(508,389,l), +(89,389,l) +); +} +); +width = 600; +}, +{ +associatedMasterId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +attr = { +coordinates = ( +800, +400 +); +}; +layerId = "1FD5C09D-F887-4ED3-BF54-15FEA26CDF14"; +name = "8 Nov 23 at 15:14"; +shapes = ( +{ +closed = 1; +nodes = ( +(31,0,l), +(164,0,l), +(164,800,l), +(31,800,l) +); +}, +{ +closed = 1; +nodes = ( +(431,0,l), +(564,0,l), +(564,800,l), +(431,800,l) +); +}, +{ +closed = 1; +nodes = ( +(89,379,l), +(508,379,l), +(508,494,l), +(89,494,l) +); +} +); +width = 600; +}, +{ +layerId = m01; +shapes = ( +{ +closed = 1; +nodes = ( +(31,0,l), +(214,0,l), +(214,700,l), +(31,700,l) +); +}, +{ +closed = 1; +nodes = ( +(381,0,l), +(564,0,l), +(564,700,l), +(381,700,l) +); +}, +{ +closed = 1; +nodes = ( +(99,304,l), +(508,304,l), +(508,459,l), +(99,459,l) +); +} +); +width = 600; +} +); +unicode = 72; +}, +{ glyphname = I; layers = ( { @@ -179,6 +363,52 @@ nodes = ( width = 600; }, { +associatedMasterId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +attr = { +coordinates = ( +600, +400 +); +}; +layerId = "1DD0DB79-DD15-42DF-A361-B703688AC628"; +name = "8 Nov 23 at 15:24"; +shapes = ( +{ +closed = 1; +nodes = ( +(231,0,l), +(364,0,l), +(364,600,l), +(231,600,l) +); +} +); +width = 600; +}, +{ +associatedMasterId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +attr = { +coordinates = ( +800, +400 +); +}; +layerId = "6550B861-E396-4850-9BB2-CA4B38E05F2F"; +name = "8 Nov 23 at 15:21"; +shapes = ( +{ +closed = 1; +nodes = ( +(231,0,l), +(364,0,l), +(364,800,l), +(231,800,l) +); +} +); +width = 600; +}, +{ layerId = m01; shapes = ( { @@ -220,13 +450,7 @@ nodes = ( ); }, { -closed = 1; -nodes = ( -(404,0,l), -(404,500,l), -(191,500,l), -(191,0,l) -); +ref = idotless; } ); width = 600; @@ -252,13 +476,7 @@ nodes = ( ); }, { -closed = 1; -nodes = ( -(354,0,l), -(354,500,l), -(241,500,l), -(241,0,l) -); +ref = idotless; } ); width = 600; @@ -267,6 +485,7 @@ width = 600; associatedMasterId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; attr = { coordinates = ( +700, 700 ); }; @@ -291,6 +510,59 @@ nodes = ( ); }, { +ref = idotless; +} +); +width = 600; +} +); +unicode = 105; +}, +{ +glyphname = idotless; +layers = ( +{ +layerId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +shapes = ( +{ +closed = 1; +nodes = ( +(354,0,l), +(354,500,l), +(241,500,l), +(241,0,l) +); +} +); +width = 600; +}, +{ +layerId = m01; +shapes = ( +{ +closed = 1; +nodes = ( +(404,0,l), +(404,500,l), +(191,500,l), +(191,0,l) +); +} +); +width = 600; +}, +{ +associatedMasterId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +attr = { +coordinates = ( +700, +700 +); +}; +layerId = "5AB430A1-B6BB-4175-8EC8-C9DE3FBA6DF5"; +name = "8 Nov 23 at 13:00"; +shapes = ( +{ closed = 1; nodes = ( (374,0,l), @@ -303,7 +575,75 @@ nodes = ( width = 600; } ); -unicode = 105; +unicode = 305; +}, +{ +glyphname = acutecomb; +layers = ( +{ +layerId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +shapes = ( +{ +closed = 1; +nodes = ( +(68,637,l), +(149,637,l), +(328,800,l), +(206,802,l) +); +} +); +width = 300; +}, +{ +layerId = m01; +shapes = ( +{ +closed = 1; +nodes = ( +(68,637,l), +(206,637,l), +(427,814,l), +(225,814,l) +); +} +); +width = 300; +} +); +unicode = 769; +}, +{ +glyphname = iacute; +layers = ( +{ +layerId = "F969B945-4602-464F-B67C-A69BED6E6A4A"; +shapes = ( +{ +ref = idotless; +}, +{ +pos = (184,-26); +ref = acutecomb; +} +); +width = 600; +}, +{ +layerId = m01; +shapes = ( +{ +ref = idotless; +}, +{ +pos = (159,-38); +ref = acutecomb; +} +); +width = 600; +} +); +unicode = 237; } ); instances = ( @@ -313,6 +653,7 @@ type = variable; }, { axesValues = ( +700, 400 ); instanceInterpolations = { @@ -322,6 +663,7 @@ name = Regular; }, { axesValues = ( +700, 700 ); instanceInterpolations = { @@ -334,6 +676,7 @@ weightClass = 700; }, { axesValues = ( +700, 900 ); instanceInterpolations = { @@ -341,6 +684,72 @@ m01 = 1; }; name = Black; weightClass = 900; +}, +{ +axesValues = ( +600, +400 +); +instanceInterpolations = { +"F969B945-4602-464F-B67C-A69BED6E6A4A" = 1; +}; +name = "Short Caps"; +}, +{ +axesValues = ( +600, +700 +); +instanceInterpolations = { +"F969B945-4602-464F-B67C-A69BED6E6A4A" = 0.4; +m01 = 0.6; +}; +name = "Short Caps Bold"; +weightClass = 700; +}, +{ +axesValues = ( +600, +900 +); +instanceInterpolations = { +m01 = 1; +}; +name = "Short Caps Black"; +weightClass = 900; +}, +{ +axesValues = ( +800, +400 +); +instanceInterpolations = { +"F969B945-4602-464F-B67C-A69BED6E6A4A" = 1; +}; +name = "Tall Caps"; +}, +{ +axesValues = ( +800, +700 +); +instanceInterpolations = { +"F969B945-4602-464F-B67C-A69BED6E6A4A" = 0.4; +m01 = 0.6; +}; +name = "Tall Caps Bold"; +weightClass = 700; +}, +{ +axesValues = ( +800, +900 +); +instanceInterpolations = { +m01 = 1; +}; +name = "Tall Caps Black"; +weightClass = 900; } ); metrics = (