allsorts_subset_browser/tables/variable_fonts/
cvar.rs

1#![deny(missing_docs)]
2
3//! `cvar` CVT Variations Table
4//!
5//! <https://learn.microsoft.com/en-us/typography/opentype/spec/cvar>
6
7use crate::binary::read::{ReadArrayCow, ReadBinaryDep, ReadCtxt};
8use crate::error::ParseError;
9use crate::tables::variable_fonts::{OwnedTuple, TupleVariationStore};
10use crate::tables::CvtTable;
11use crate::SafeFrom;
12
13/// `cvar` CVT Variations Table
14///
15/// <https://learn.microsoft.com/en-us/typography/opentype/spec/cvar#table-format>
16pub struct CvarTable<'a> {
17    /// Major version number of the glyph variations table.
18    pub major_version: u16,
19    /// Minor version number of the glyph variations table.
20    pub minor_version: u16,
21    /// Variation data
22    pub store: TupleVariationStore<'a, super::Cvar>,
23}
24
25impl CvarTable<'_> {
26    /// Apply `cvar` variations to `cvt` table, returning adjusted table.
27    pub fn apply<'new>(
28        &self,
29        instance: &OwnedTuple,
30        cvt: &CvtTable<'_>,
31    ) -> Result<CvtTable<'new>, ParseError> {
32        let num_cvts = cvt.values.len() as u32;
33        let mut values = cvt.values.iter().map(|val| val as f32).collect::<Vec<_>>();
34
35        for (scale, region) in self.store.determine_applicable(self, instance) {
36            let variation_data =
37                region.variation_data(num_cvts, self.store.shared_point_numbers())?;
38            for (cvt_index, delta) in variation_data.iter() {
39                let val = values
40                    .get_mut(usize::safe_from(cvt_index))
41                    .ok_or(ParseError::BadIndex)?;
42                *val += scale * delta as f32
43            }
44        }
45
46        Ok(CvtTable {
47            values: ReadArrayCow::Owned(values.into_iter().map(|val| val.round() as i16).collect()),
48        })
49    }
50}
51
52impl ReadBinaryDep for CvarTable<'_> {
53    type Args<'a> = (u16, u32);
54    type HostType<'a> = CvarTable<'a>;
55
56    fn read_dep<'a>(
57        ctxt: &mut ReadCtxt<'a>,
58        (axis_count, num_cvts): (u16, u32),
59    ) -> Result<Self::HostType<'a>, ParseError> {
60        let table_scope = ctxt.scope();
61        let major_version = ctxt.read_u16be()?;
62        ctxt.check_version(major_version == 1)?;
63        let minor_version = ctxt.read_u16be()?;
64        let store = ctxt.read_dep::<TupleVariationStore<'_, super::Cvar>>((
65            axis_count,
66            num_cvts,
67            table_scope,
68        ))?;
69
70        Ok(CvarTable {
71            major_version,
72            minor_version,
73            store,
74        })
75    }
76}