Skip to content
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

Add support for ufo openTypeOs2Weight/WidthClass #1191

Merged
merged 1 commit into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions fontbe/src/os2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,20 +533,27 @@ impl Work<Context, AnyWorkId, Error> 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<u16>, 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
Expand Down
9 changes: 9 additions & 0 deletions fontc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
13 changes: 13 additions & 0 deletions fontir/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ pub struct MiscMetadata {
// Allows source to explicitly control bits. <https://github.com/googlefonts/fontc/issues/1027>
pub codepage_range_bits: Option<HashSet<u32>>,
pub meta_table: Option<MetaTableValues>,

/// <https://learn.microsoft.com/en-us/typography/opentype/spec/os2#usweightclass>
///
/// If empty and there is a weight axis OS/2 will use the weight default
pub us_weight_class: Option<u16>,
/// <https://learn.microsoft.com/en-us/typography/opentype/spec/os2#uswidthclass>
///
/// If empty and there is a width axis OS/2 will use the width default
pub us_width_class: Option<u16>,
}

/// PANOSE bytes
Expand Down Expand Up @@ -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,
},
})
}
Expand Down Expand Up @@ -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(),
}
Expand Down
4 changes: 4 additions & 0 deletions resources/testdata/FontInfo-Regular.ufo/fontinfo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,9 @@
<integer>-290</integer>
<key>openTypeHheaLineGap</key>
<integer>43</integer>
<key>openTypeOS2WeightClass</key>
<integer>800</integer>
<key>openTypeOS2WidthClass</key>
<integer>8</integer>
</dict>
</plist>
8 changes: 8 additions & 0 deletions ufo2fontir/src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,7 @@ fn names(font_info: &norad::FontInfo) -> HashMap<NameKey, String> {
.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);
Expand Down Expand Up @@ -818,6 +819,13 @@ impl Work<Context, WorkId, Error> 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);

// <https://github.com/googlefonts/glyphsLib/blob/cb8a4a914b0a33431f0a77f474bf57eec2f19bcc/Lib/glyphsLib/builder/custom_params.py#L1117-L1119>
static_metadata.misc.fs_type = Some(
font_info_at_default
Expand Down
Loading