Skip to content

Commit

Permalink
Merge pull request #501 from googlefonts/serde
Browse files Browse the repository at this point in the history
Don't lose MiscMetadata in serde
  • Loading branch information
cmyr authored Oct 23, 2023
2 parents 4e3d965 + 004ded3 commit 5c92294
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 29 deletions.
6 changes: 6 additions & 0 deletions fontir/src/coords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,12 @@ impl<T: Copy> FromIterator<(Tag, T)> for Location<T> {
}
}

impl<T: Copy> From<Vec<(Tag, T)>> for Location<T> {
fn from(value: Vec<(Tag, T)>) -> Self {
Location::<T>::from_iter(value)
}
}

impl<T: Copy> Location<T> {
pub fn new() -> Location<T> {
Location(BTreeMap::new())
Expand Down
129 changes: 102 additions & 27 deletions fontir/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ pub struct StaticMetadata {
/// used in things like gvar.
pub variation_model: VariationModel,

axes_default: NormalizedLocation,
variable_axes_default: NormalizedLocation,
default_location: NormalizedLocation,

/// See <https://learn.microsoft.com/en-us/typography/opentype/spec/name>.
pub names: HashMap<NameKey, String>,
Expand Down Expand Up @@ -265,11 +264,7 @@ impl StaticMetadata {

let variation_model = VariationModel::new(glyph_locations, variable_axes.clone())?;

let axes_default = axes
.iter()
.map(|a| (a.tag, NormalizedCoord::new(0.0)))
.collect();
let variable_axes_default = axes
let default_location = axes
.iter()
.map(|a| (a.tag, NormalizedCoord::new(0.0)))
.collect();
Expand All @@ -281,8 +276,7 @@ impl StaticMetadata {
axes: variable_axes,
named_instances,
variation_model,
axes_default,
variable_axes_default,
default_location,
postscript_names,
misc: MiscMetadata {
selection_flags: Default::default(),
Expand All @@ -301,14 +295,9 @@ impl StaticMetadata {
})
}

/// The default on all known axes.
/// The default on all variable axes.
pub fn default_location(&self) -> &NormalizedLocation {
&self.axes_default
}

/// The default on all variable (non-point) axes.
pub fn variable_axes_default(&self) -> &NormalizedLocation {
&self.variable_axes_default
&self.default_location
}
}

Expand Down Expand Up @@ -1490,17 +1479,28 @@ impl GlyphPathBuilder {
#[cfg(test)]
mod tests {

use std::str::FromStr;
use std::{
collections::{HashMap, HashSet},
fmt::Debug,
};

use font_types::Tag;
use serde::{Deserialize, Serialize};

use font_types::{NameId, Tag};
use write_fonts::tables::os2::SelectionFlags;

use crate::{
coords::{CoordConverter, UserCoord},
coords::{CoordConverter, NormalizedCoord, UserCoord},
error::PathConversionError,
ir::Axis,
variations::VariationModel,
};

use super::GlyphPathBuilder;
use pretty_assertions::assert_eq;

use super::{GlyphPathBuilder, MiscMetadata, NameKey, NamedInstance, StaticMetadata};

const WGHT: Tag = Tag::from_be_bytes(*b"wght");

fn test_axis() -> Axis {
let min = UserCoord::new(100.0);
Expand All @@ -1509,7 +1509,7 @@ mod tests {
let converter = CoordConverter::unmapped(min, default, max);
Axis {
name: String::from("Weight"),
tag: Tag::from_str("wght").unwrap(),
tag: WGHT,
min,
default,
max,
Expand All @@ -1518,18 +1518,93 @@ mod tests {
}
}

fn test_static_metadata() -> StaticMetadata {
let axis = test_axis();
let mut point_axis = axis.clone();
point_axis.min = point_axis.default;
point_axis.max = point_axis.default;

StaticMetadata {
units_per_em: 1000,
all_source_axes: vec![axis.clone(), point_axis],
axes: vec![axis.clone()],
named_instances: vec![NamedInstance {
name: "Nobody".to_string(),
location: vec![(WGHT, UserCoord::new(100.0))].into(),
}],
variation_model: VariationModel::new(
HashSet::from([
vec![(WGHT, NormalizedCoord::new(-1.0))].into(),
vec![(WGHT, NormalizedCoord::new(0.0))].into(),
vec![(WGHT, NormalizedCoord::new(1.0))].into(),
]),
vec![axis.clone()],
)
.unwrap(),
default_location: vec![(WGHT, NormalizedCoord::new(0.0))].into(),
names: HashMap::from([
(
NameKey::new_bmp_only(NameId::FAMILY_NAME),
"Fam".to_string(),
),
(
NameKey::new_bmp_only(NameId::new(256)),
"Weight".to_string(),
),
(
NameKey::new_bmp_only(NameId::new(257)),
"Nobody".to_string(),
),
]),
postscript_names: HashMap::from([("lhs".into(), "rhs".into())]),
misc: MiscMetadata {
selection_flags: SelectionFlags::default(),
vendor_id: Tag::from_be_bytes(*b"DUCK"),
underline_thickness: 0.15.into(),
underline_position: 16.0.into(),
version_major: 42,
version_minor: 24,
head_flags: 42,
lowest_rec_ppm: 42,
created: None,
},
}
}

fn assert_yml_round_trip<T>(thing: T)
where
for<'a> T: Serialize + Deserialize<'a> + PartialEq + Debug,
{
let yml = serde_yaml::to_string(&thing).unwrap();
assert_eq!(thing, serde_yaml::from_str(&yml).unwrap());
}

fn assert_bincode_round_trip<T>(thing: T)
where
for<'a> T: Serialize + Deserialize<'a> + PartialEq + Debug,
{
let bin = bincode::serialize(&thing).unwrap();
assert_eq!(thing, bincode::deserialize(&bin).unwrap());
}

#[test]
fn axis_yaml() {
let test_axis = test_axis();
let yml = serde_yaml::to_string(&test_axis).unwrap();
assert_eq!(test_axis, serde_yaml::from_str(&yml).unwrap());
assert_yml_round_trip(test_axis());
}

#[test]
fn axis_bincode() {
let test_axis = test_axis();
let bin = bincode::serialize(&test_axis).unwrap();
assert_eq!(test_axis, bincode::deserialize(&bin).unwrap());
assert_bincode_round_trip(test_axis());
}

#[test]
fn static_metadata_yaml() {
assert_yml_round_trip(test_static_metadata());
}

#[test]
fn static_metadata_bincode() {
assert_bincode_round_trip(test_static_metadata());
}

#[test]
Expand Down
6 changes: 4 additions & 2 deletions fontir/src/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,17 @@ pub(crate) struct StaticMetadataSerdeRepr {

impl From<StaticMetadataSerdeRepr> for StaticMetadata {
fn from(from: StaticMetadataSerdeRepr) -> Self {
StaticMetadata::new(
let mut static_metadata = StaticMetadata::new(
from.units_per_em,
from.names,
from.axes,
from.named_instances,
from.glyph_locations.into_iter().collect(),
from.postscript_names,
)
.unwrap()
.unwrap();
static_metadata.misc = from.misc.into();
static_metadata
}
}

Expand Down

0 comments on commit 5c92294

Please sign in to comment.