diff --git a/fontbe/src/os2.rs b/fontbe/src/os2.rs index 37965e129..04d7cc09f 100644 --- a/fontbe/src/os2.rs +++ b/fontbe/src/os2.rs @@ -533,20 +533,27 @@ impl Work for Os2Work { fn exec(&self, context: &Context) -> Result<(), Error> { let static_metadata = context.ir.static_metadata.get(); - // We set the OS/2.us{Weight,Width}Class to the default value of 'wght'/'wdth' axes + // If the source doesn't explicitly assign a value then + // set the OS/2.us{Weight,Width}Class to the default value of 'wght'/'wdth' axes // in the same way fontmake does when building a VF: // https://github.com/fonttools/fonttools/blob/770917d8/Lib/fontTools/varLib/__init__.py#L1016-L1032 - let default_wght = static_metadata - .axis(&Tag::new(b"wght")) - .map(|axis| axis.default.into_inner().0) - .unwrap_or(400.0); - let us_weight_class: u16 = default_wght.clamp(1.0, 1000.0).ot_round(); - - let default_wdth = static_metadata - .axis(&Tag::new(b"wdth")) - .map(|axis| axis.default.into_inner().0) - .unwrap_or(100.0); - let us_width_class = WidthClass::nearest(default_wdth) as u16; + let us_x_class = |misc_value: Option, axis_tag, default, clamp: fn(f64) -> u16| { + misc_value.unwrap_or_else(|| { + clamp( + static_metadata + .axis(&Tag::new(axis_tag)) + .map(|axis| axis.default.into_inner().0) + .unwrap_or(default), + ) + }) + }; + let us_weight_class = + us_x_class(static_metadata.misc.us_weight_class, b"wght", 400.0, |v| { + v.clamp(1.0, 1000.0).ot_round() + }); + let us_width_class = us_x_class(static_metadata.misc.us_width_class, b"wdth", 100.0, |v| { + WidthClass::nearest(v) as u16 + }); let metrics = context .ir diff --git a/fontc/src/lib.rs b/fontc/src/lib.rs index 487269e67..738fb7740 100644 --- a/fontc/src/lib.rs +++ b/fontc/src/lib.rs @@ -1291,6 +1291,15 @@ mod tests { ); } + #[test] + fn prefers_explicit_os_x_class() { + let result = TestCompile::compile_source("fontinfo.designspace"); + let font = result.font(); + let os2 = font.os2().unwrap(); + + assert_eq!((800, 8), (os2.us_weight_class(), os2.us_width_class(),),); + } + #[test] fn glyphs_app_ir_categories() { let result = TestCompile::compile_source("glyphs3/Oswald-glyph-categories.glyphs"); diff --git a/fontir/src/ir.rs b/fontir/src/ir.rs index 5f27dd9b0..bde03336a 100644 --- a/fontir/src/ir.rs +++ b/fontir/src/ir.rs @@ -137,6 +137,15 @@ pub struct MiscMetadata { // Allows source to explicitly control bits. pub codepage_range_bits: Option>, pub meta_table: Option, + + /// + /// + /// If empty and there is a weight axis OS/2 will use the weight default + pub us_weight_class: Option, + /// + /// + /// If empty and there is a width axis OS/2 will use the width default + pub us_width_class: Option, } /// PANOSE bytes @@ -498,6 +507,8 @@ impl StaticMetadata { unicode_range_bits: None, codepage_range_bits: None, meta_table: None, + us_weight_class: None, + us_width_class: None, }, }) } @@ -1961,6 +1972,8 @@ mod tests { unicode_range_bits: None, codepage_range_bits: None, meta_table: None, + us_weight_class: None, + us_width_class: None, }, number_values: Default::default(), } diff --git a/resources/testdata/FontInfo-Regular.ufo/fontinfo.plist b/resources/testdata/FontInfo-Regular.ufo/fontinfo.plist index e75e8de16..668f67712 100644 --- a/resources/testdata/FontInfo-Regular.ufo/fontinfo.plist +++ b/resources/testdata/FontInfo-Regular.ufo/fontinfo.plist @@ -34,5 +34,9 @@ -290 openTypeHheaLineGap 43 + openTypeOS2WeightClass + 800 + openTypeOS2WidthClass + 8 diff --git a/ufo2fontir/src/source.rs b/ufo2fontir/src/source.rs index 55de154d4..6a5b39a10 100644 --- a/ufo2fontir/src/source.rs +++ b/ufo2fontir/src/source.rs @@ -604,6 +604,7 @@ fn names(font_info: &norad::FontInfo) -> HashMap { .into() }), ); + builder.add_if_present(NameId::UNIQUE_ID, &font_info.open_type_name_unique_id); builder.add_if_present(NameId::VERSION_STRING, &font_info.open_type_name_version); builder.add_if_present(NameId::POSTSCRIPT_NAME, &font_info.postscript_font_name); @@ -818,6 +819,13 @@ impl Work for StaticMetadataWork { })?; } + static_metadata.misc.us_weight_class = font_info_at_default + .open_type_os2_weight_class + .map(|v| v as u16); + static_metadata.misc.us_width_class = font_info_at_default + .open_type_os2_width_class + .map(|v| v as u16); + // static_metadata.misc.fs_type = Some( font_info_at_default