1use read_fonts::{types::F2Dot14, ReadError, TableProvider};
2use skrifa::FontRef;
3
4use crate::monkeypatching::DenormalizeLocation;
5
6use super::namemap::NameMap;
7
8pub(crate) struct SerializationContext<'a> {
9 pub(crate) font: &'a FontRef<'a>,
10 pub(crate) names: NameMap,
11 pub(crate) gdef_regions: Vec<Vec<F2Dot14>>,
12 pub(crate) gdef_locations: Vec<String>,
13}
14
15impl<'a> SerializationContext<'a> {
16 pub fn new(font: &'a FontRef<'a>, names: NameMap) -> Result<Self, ReadError> {
17 let (gdef_regions, gdef_locations) = if let Ok(Some(ivs)) = font
18 .gdef()
19 .and_then(|gdef| gdef.item_var_store().transpose())
20 {
21 let regions = ivs.variation_region_list()?.variation_regions();
22
23 let all_tuples: Vec<Vec<F2Dot14>> = regions
25 .iter()
26 .flatten()
27 .map(|r| r.region_axes().iter().map(|x| x.peak_coord()).collect())
28 .collect();
29 let locations: Vec<String> = all_tuples
31 .iter()
32 .map(|tuple| {
33 let coords: Vec<f32> = tuple.iter().map(|x| x.to_f32()).collect();
34 if let Ok(location) = font.denormalize_location(&coords) {
35 let mut loc_str: Vec<String> = location
36 .iter()
37 .map(|setting| {
38 setting.selector.to_string() + "=" + &setting.value.to_string()
39 })
40 .collect();
41 loc_str.sort();
42 loc_str.join(",")
43 } else {
44 "Unknown".to_string()
45 }
46 })
47 .collect();
48 (all_tuples, locations)
49 } else {
50 (Vec::new(), Vec::new())
51 };
52
53 Ok(SerializationContext {
54 font,
55 names,
56 gdef_regions,
57 gdef_locations,
58 })
59 }
60}