Skip to main content

write_fonts/tables/
gdef.rs

1//! the [GDEF] table
2//!
3//! [GDEF]: https://docs.microsoft.com/en-us/typography/opentype/spec/gdef
4
5use types::MajorMinor;
6
7use crate::tables::layout::VariationIndex;
8
9use super::{
10    layout::{ClassDef, CoverageTable, DeviceOrVariationIndex},
11    variations::{
12        common_builder::RemapVarStore, ivs_builder::VariationIndexRemapping, ItemVariationStore,
13    },
14};
15
16include!("../../generated/generated_gdef.rs");
17
18#[cfg(test)]
19mod extended;
20
21impl RemapVarStore<VariationIndex> for LigCaretList2 {
22    fn remap_variation_indices(&mut self, key_map: &VariationIndexRemapping) {
23        self.lig_glyphs.iter_mut().for_each(|lig| {
24            lig.caret_values
25                .iter_mut()
26                .for_each(|caret| caret.remap_variation_indices(key_map))
27        })
28    }
29}
30
31impl Gdef {
32    fn compute_version(&self) -> MajorMinor {
33        if self.glyph_class_def2.is_some()
34            || self.attach_list2.is_some()
35            || self.lig_caret_list2.is_some()
36            || self.mark_attach_class_def2.is_some()
37            || self.mark_glyph_sets_def2.is_some()
38        {
39            MajorMinor::new(1, 4)
40        } else if self.item_var_store.is_some() {
41            MajorMinor::VERSION_1_3
42        } else if self.mark_glyph_sets_def.is_some() {
43            MajorMinor::VERSION_1_2
44        } else {
45            MajorMinor::VERSION_1_0
46        }
47    }
48}
49
50impl RemapVarStore<VariationIndex> for Gdef {
51    fn remap_variation_indices(&mut self, key_map: &VariationIndexRemapping) {
52        if let Some(ligs) = self.lig_caret_list.as_mut() {
53            ligs.remap_variation_indices(key_map);
54        }
55        if let Some(ligs) = self.lig_caret_list2.as_mut() {
56            ligs.remap_variation_indices(key_map);
57        }
58    }
59}
60
61impl RemapVarStore<VariationIndex> for LigCaretList {
62    fn remap_variation_indices(&mut self, key_map: &VariationIndexRemapping) {
63        self.lig_glyphs.iter_mut().for_each(|lig| {
64            lig.caret_values
65                .iter_mut()
66                .for_each(|caret| caret.remap_variation_indices(key_map))
67        })
68    }
69}
70
71impl RemapVarStore<VariationIndex> for CaretValue {
72    fn remap_variation_indices(&mut self, key_map: &VariationIndexRemapping) {
73        if let CaretValue::Format3(table) = self {
74            table.remap_variation_indices(key_map)
75        }
76    }
77}
78
79impl RemapVarStore<VariationIndex> for CaretValueFormat3 {
80    fn remap_variation_indices(&mut self, key_map: &VariationIndexRemapping) {
81        self.device.remap_variation_indices(key_map)
82    }
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88
89    #[test]
90    fn var_store_without_glyph_sets() {
91        // this should compile, and version should be 1.3
92        let gdef = Gdef {
93            item_var_store: ItemVariationStore::default().into(),
94            ..Default::default()
95        };
96
97        assert_eq!(gdef.compute_version(), MajorMinor::VERSION_1_3);
98        let _dumped = crate::write::dump_table(&gdef).unwrap();
99        let data = FontData::new(&_dumped);
100        let loaded = read_fonts::tables::gdef::Gdef::read(data).unwrap();
101
102        assert_eq!(loaded.version(), MajorMinor::VERSION_1_3);
103        assert!(!loaded.item_var_store_offset().unwrap().is_null());
104    }
105}