From 48b8e383f6534e5853efee0793d844f4f544881d Mon Sep 17 00:00:00 2001 From: Colin Rofls Date: Mon, 21 Aug 2023 16:17:59 -0400 Subject: [PATCH] [features] Update fea-rs to allow axis unit suffixes That is, axis locations can now exist in one of user, design, or normalized coordinates. --- Cargo.toml | 2 +- fontbe/src/features.rs | 48 ++++++++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8ed59da4..ddaedb03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ env_logger = "0.10.0" parking_lot = "0.12.1" -fea-rs = "0.13.2" +fea-rs = "0.14.0" font-types = { version = "0.3.3", features = ["serde"] } read-fonts = "0.10.0" write-fonts = "0.14.1" diff --git a/fontbe/src/features.rs b/fontbe/src/features.rs index cba7ee7f..84a50f9c 100644 --- a/fontbe/src/features.rs +++ b/fontbe/src/features.rs @@ -10,13 +10,13 @@ use std::{ }; use fea_rs::{ - compile::{Compilation, VariationInfo}, + compile::{AxisLocation, Compilation, VariationInfo}, parse::{SourceLoadError, SourceResolver}, Compiler, GlyphMap, GlyphName as FeaRsGlyphName, }; -use font_types::{F2Dot14, Fixed, Tag}; +use font_types::{F2Dot14, Tag}; use fontir::{ - coords::{CoordConverter, UserCoord, UserLocation}, + coords::{CoordConverter, DesignCoord, NormalizedCoord, NormalizedLocation, UserCoord}, ir::{Axis, Features, GlyphOrder, KernParticipant, Kerning, StaticMetadata}, orchestration::{Flags, WorkId as FeWorkId}, }; @@ -112,6 +112,28 @@ impl<'a> FeaVariationInfo<'a> { static_metadata, } } + + fn normalize_location( + &self, + fears_location: &BTreeMap, + ) -> NormalizedLocation { + fears_location + .iter() + .map(|(tag, pos)| { + let axis = self.axes.get(tag).unwrap(); + let pos = match pos { + AxisLocation::User(coord) => { + UserCoord::new(coord.to_f32()).to_normalized(&axis.converter) + } + AxisLocation::Design(coord) => { + DesignCoord::new(coord.to_f32()).to_normalized(&axis.converter) + } + AxisLocation::Normalized(coord) => NormalizedCoord::new(coord.to_f32()), + }; + (*tag, pos) + }) + .collect() + } } impl<'a> VariationInfo for FeaVariationInfo<'a> { @@ -135,7 +157,7 @@ impl<'a> VariationInfo for FeaVariationInfo<'a> { fn resolve_variable_metric( &self, - values: &HashMap, i16>, + values: &HashMap, i16>, ) -> Result< ( i16, @@ -150,11 +172,8 @@ impl<'a> VariationInfo for FeaVariationInfo<'a> { let point_seqs: HashMap<_, _> = values .iter() .map(|(pos, value)| { - let user = UserLocation::from_iter( - pos.iter() - .map(|(tag, value)| (*tag, UserCoord::new(value.to_f64() as f32))), - ); - (user.to_normalized(&self.axes), vec![*value as f64]) + let normalized = self.normalize_location(pos); + (normalized, vec![*value as f64]) }) .collect(); @@ -525,7 +544,7 @@ impl Work for FeatureWork { mod tests { use std::collections::{BTreeMap, HashMap, HashSet}; - use fea_rs::compile::VariationInfo; + use fea_rs::compile::{AxisLocation, VariationInfo}; use font_types::{Fixed, Tag}; use fontir::{ coords::{CoordConverter, DesignCoord, NormalizedCoord, NormalizedLocation, UserCoord}, @@ -585,6 +604,9 @@ mod tests { #[test] fn resolve_kern() { let _ = env_logger::builder().is_test(true).try_init(); + fn make_axis_location(user_coord: f64) -> AxisLocation { + AxisLocation::User(Fixed::from_f64(user_coord)) + } let wght = Tag::new(b"wght"); let static_metadata = weight_variable_static_metadata(300.0, 400.0, 700.0); @@ -592,9 +614,9 @@ mod tests { let (default, regions) = var_info .resolve_variable_metric(&HashMap::from([ - (BTreeMap::from([(wght, Fixed::from_f64(300.0))]), 10), - (BTreeMap::from([(wght, Fixed::from_f64(400.0))]), 15), - (BTreeMap::from([(wght, Fixed::from_f64(700.0))]), 20), + (BTreeMap::from([(wght, make_axis_location(300.0))]), 10), + (BTreeMap::from([(wght, make_axis_location(400.0))]), 15), + (BTreeMap::from([(wght, make_axis_location(700.0))]), 20), ])) .unwrap(); assert!(!regions.iter().any(|(r, _)| is_default(r)));