ttf_parser/tables/
trak.rs1use crate::parser::{FromData, LazyArray16, Offset, Offset16, Offset32, Fixed, 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
39#[derive(Clone, Copy, Default, Debug)]
41pub struct Tracks<'a> {
42 data: &'a [u8], records: LazyArray16<'a, TrackTableRecord>,
44 sizes_count: u16,
45}
46
47impl<'a> Tracks<'a> {
48 pub fn get(&self, index: u16) -> Option<Track<'a>> {
50 let record = self.records.get(index)?;
51 let mut s = Stream::new(self.data.get(record.offset.to_usize()..)?);
52 Some(Track {
53 value: record.value.0,
54 values: s.read_array16::<i16>(self.sizes_count)?,
55 name_index: record.name_id,
56 })
57 }
58
59 pub fn len(&self) -> u16 {
61 self.records.len()
62 }
63}
64
65impl<'a> IntoIterator for Tracks<'a> {
66 type Item = Track<'a>;
67 type IntoIter = TracksIter<'a>;
68
69 #[inline]
70 fn into_iter(self) -> Self::IntoIter {
71 TracksIter {
72 tracks: self,
73 index: 0,
74 }
75 }
76}
77
78#[allow(missing_debug_implementations)]
80pub struct TracksIter<'a> {
81 tracks: Tracks<'a>,
82 index: u16,
83}
84
85impl<'a> Iterator for TracksIter<'a> {
86 type Item = Track<'a>;
87
88 fn next(&mut self) -> Option<Self::Item> {
89 if self.index < self.tracks.len() {
90 self.index += 1;
91 self.tracks.get(self.index - 1)
92 } else {
93 None
94 }
95 }
96}
97
98
99#[derive(Clone, Copy, Default, Debug)]
101pub struct TrackData<'a> {
102 pub tracks: Tracks<'a>,
104 pub sizes: LazyArray16<'a, Fixed>,
106}
107
108impl<'a> TrackData<'a> {
109 fn parse(offset: usize, data: &'a [u8]) -> Option<Self> {
110 let mut s = Stream::new_at(data, offset)?;
111 let tracks_count = s.read::<u16>()?;
112 let sizes_count = s.read::<u16>()?;
113 let size_table_offset = s.read::<Offset32>()?; let tracks = Tracks {
116 data,
117 records: s.read_array16::<TrackTableRecord>(tracks_count)?,
118 sizes_count,
119 };
120
121 let sizes = {
124 let mut s = Stream::new_at(data, size_table_offset.to_usize())?;
125 s.read_array16::<Fixed>(sizes_count)?
126 };
127
128 Some(TrackData { tracks, sizes })
129 }
130}
131
132
133#[derive(Clone, Copy, Debug)]
136pub struct Table<'a> {
137 pub horizontal: TrackData<'a>,
139 pub vertical: TrackData<'a>,
141}
142
143impl<'a> Table<'a> {
144 pub fn parse(data: &'a [u8]) -> Option<Self> {
146 let mut s = Stream::new(data);
147
148 let version = s.read::<u32>()?;
149 if version != 0x00010000 {
150 return None;
151 }
152
153 let format = s.read::<u16>()?;
154 if format != 0 {
155 return None;
156 }
157
158 let hor_offset = s.read::<Option<Offset16>>()?;
159 let ver_offset = s.read::<Option<Offset16>>()?;
160 s.skip::<u16>(); let horizontal = if let Some(offset) = hor_offset {
163 TrackData::parse(offset.to_usize(), data)?
164 } else {
165 TrackData::default()
166 };
167
168 let vertical = if let Some(offset) = ver_offset {
169 TrackData::parse(offset.to_usize(), data)?
170 } else {
171 TrackData::default()
172 };
173
174 Some(Table {
175 horizontal,
176 vertical,
177 })
178 }
179}