ttf_parser/tables/
trak.rs1use crate::parser::{Fixed, FromData, LazyArray16, Offset, Offset16, Offset32, Stream};
5
6#[derive(Clone, Copy, Debug)]
7struct TrackTableRecord {
8 value: Fixed,
9 name_id: u16,
10 offset: Offset16, }
12
13impl FromData for TrackTableRecord {
14 const SIZE: usize = 8;
15
16 #[inline]
17 fn parse(data: &[u8]) -> Option<Self> {
18 let mut s = Stream::new(data);
19 Some(TrackTableRecord {
20 value: s.read::<Fixed>()?,
21 name_id: s.read::<u16>()?,
22 offset: s.read::<Offset16>()?,
23 })
24 }
25}
26
27#[derive(Clone, Copy, Debug)]
29pub struct Track<'a> {
30 pub value: f32,
32 pub name_index: u16,
34 pub values: LazyArray16<'a, i16>,
36}
37
38#[derive(Clone, Copy, Default, Debug)]
40pub struct Tracks<'a> {
41 data: &'a [u8], records: LazyArray16<'a, TrackTableRecord>,
43 sizes_count: u16,
44}
45
46impl<'a> Tracks<'a> {
47 pub fn get(&self, index: u16) -> Option<Track<'a>> {
49 let record = self.records.get(index)?;
50 let mut s = Stream::new(self.data.get(record.offset.to_usize()..)?);
51 Some(Track {
52 value: record.value.0,
53 values: s.read_array16::<i16>(self.sizes_count)?,
54 name_index: record.name_id,
55 })
56 }
57
58 pub fn len(&self) -> u16 {
60 self.records.len()
61 }
62
63 pub fn is_empty(&self) -> bool {
65 self.records.is_empty()
66 }
67}
68
69impl<'a> IntoIterator for Tracks<'a> {
70 type Item = Track<'a>;
71 type IntoIter = TracksIter<'a>;
72
73 #[inline]
74 fn into_iter(self) -> Self::IntoIter {
75 TracksIter {
76 tracks: self,
77 index: 0,
78 }
79 }
80}
81
82#[allow(missing_debug_implementations)]
84pub struct TracksIter<'a> {
85 tracks: Tracks<'a>,
86 index: u16,
87}
88
89impl<'a> Iterator for TracksIter<'a> {
90 type Item = Track<'a>;
91
92 fn next(&mut self) -> Option<Self::Item> {
93 if self.index < self.tracks.len() {
94 self.index += 1;
95 self.tracks.get(self.index - 1)
96 } else {
97 None
98 }
99 }
100}
101
102#[derive(Clone, Copy, Default, Debug)]
104pub struct TrackData<'a> {
105 pub tracks: Tracks<'a>,
107 pub sizes: LazyArray16<'a, Fixed>,
109}
110
111impl<'a> TrackData<'a> {
112 fn parse(offset: usize, data: &'a [u8]) -> Option<Self> {
113 let mut s = Stream::new_at(data, offset)?;
114 let tracks_count = s.read::<u16>()?;
115 let sizes_count = s.read::<u16>()?;
116 let size_table_offset = s.read::<Offset32>()?; let tracks = Tracks {
119 data,
120 records: s.read_array16::<TrackTableRecord>(tracks_count)?,
121 sizes_count,
122 };
123
124 let sizes = {
127 let mut s = Stream::new_at(data, size_table_offset.to_usize())?;
128 s.read_array16::<Fixed>(sizes_count)?
129 };
130
131 Some(TrackData { tracks, sizes })
132 }
133}
134
135#[derive(Clone, Copy, Debug)]
138pub struct Table<'a> {
139 pub horizontal: TrackData<'a>,
141 pub vertical: TrackData<'a>,
143}
144
145impl<'a> Table<'a> {
146 pub fn parse(data: &'a [u8]) -> Option<Self> {
148 let mut s = Stream::new(data);
149
150 let version = s.read::<u32>()?;
151 if version != 0x00010000 {
152 return None;
153 }
154
155 let format = s.read::<u16>()?;
156 if format != 0 {
157 return None;
158 }
159
160 let hor_offset = s.read::<Option<Offset16>>()?;
161 let ver_offset = s.read::<Option<Offset16>>()?;
162 s.skip::<u16>(); let horizontal = if let Some(offset) = hor_offset {
165 TrackData::parse(offset.to_usize(), data)?
166 } else {
167 TrackData::default()
168 };
169
170 let vertical = if let Some(offset) = ver_offset {
171 TrackData::parse(offset.to_usize(), data)?
172 } else {
173 TrackData::default()
174 };
175
176 Some(Table {
177 horizontal,
178 vertical,
179 })
180 }
181}