Skip to main content

ttj/
context.rs

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            // Find all the peaks
24            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's turn these back to userspace
30            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}