ttf_parser/tables/
mvar.rs1use crate::{Tag, NormalizedCoordinate};
5use crate::parser::{Stream, FromData, Offset, Offset16, LazyArray16};
6use crate::var_store::ItemVariationStore;
7
8#[derive(Clone, Copy)]
9struct ValueRecord {
10 value_tag: Tag,
11 delta_set_outer_index: u16,
12 delta_set_inner_index: u16,
13}
14
15impl FromData for ValueRecord {
16 const SIZE: usize = 8;
17
18 #[inline]
19 fn parse(data: &[u8]) -> Option<Self> {
20 let mut s = Stream::new(data);
21 Some(ValueRecord {
22 value_tag: s.read::<Tag>()?,
23 delta_set_outer_index: s.read::<u16>()?,
24 delta_set_inner_index: s.read::<u16>()?,
25 })
26 }
27}
28
29
30#[derive(Clone, Copy)]
33pub struct Table<'a> {
34 variation_store: ItemVariationStore<'a>,
35 records: LazyArray16<'a, ValueRecord>,
36}
37
38impl<'a> Table<'a> {
39 pub fn parse(data: &'a [u8]) -> Option<Self> {
41 let mut s = Stream::new(data);
42
43 let version = s.read::<u32>()?;
44 if version != 0x00010000 {
45 return None;
46 }
47
48 s.skip::<u16>(); let value_record_size = s.read::<u16>()?;
50
51 if usize::from(value_record_size) != ValueRecord::SIZE {
52 return None;
53 }
54
55 let count = s.read::<u16>()?;
56 if count == 0 {
57 return None;
58 }
59
60 let var_store_offset = s.read::<Option<Offset16>>()??.to_usize();
61 let records = s.read_array16::<ValueRecord>(count)?;
62 let variation_store = ItemVariationStore::parse(Stream::new_at(data, var_store_offset)?)?;
63
64 Some(Table {
65 variation_store,
66 records,
67 })
68 }
69
70 pub fn metric_offset(&self, tag: Tag, coordinates: &[NormalizedCoordinate]) -> Option<f32> {
72 let (_, record) = self.records.binary_search_by(|r| r.value_tag.cmp(&tag))?;
73 self.variation_store.parse_delta(
74 record.delta_set_outer_index,
75 record.delta_set_inner_index,
76 coordinates
77 )
78 }
79}
80
81impl core::fmt::Debug for Table<'_> {
82 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
83 write!(f, "Table {{ ... }}")
84 }
85}