read_fonts/generated/
font.rs1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8impl<'a> MinByteRange<'a> for TableDirectory<'a> {
9 fn min_byte_range(&self) -> Range<usize> {
10 0..self.table_records_byte_range().end
11 }
12 fn min_table_bytes(&self) -> &'a [u8] {
13 let range = self.min_byte_range();
14 self.data.as_bytes().get(range).unwrap_or_default()
15 }
16}
17
18impl ReadArgs for TableDirectory<'_> {
19 type Args = ();
20}
21
22impl<'a> FontRead<'a> for TableDirectory<'a> {
23 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
24 #[allow(clippy::absurd_extreme_comparisons)]
25 if data.len() < Self::MIN_SIZE {
26 return Err(ReadError::OutOfBounds);
27 }
28 Ok(Self { data })
29 }
30}
31
32#[derive(Clone)]
34pub struct TableDirectory<'a> {
35 data: FontData<'a>,
36}
37
38#[allow(clippy::needless_lifetimes)]
39impl<'a> TableDirectory<'a> {
40 pub const MIN_SIZE: usize = (u32::RAW_BYTE_LEN
41 + u16::RAW_BYTE_LEN
42 + u16::RAW_BYTE_LEN
43 + u16::RAW_BYTE_LEN
44 + u16::RAW_BYTE_LEN);
45 basic_table_impls!(impl_the_methods);
46
47 pub fn sfnt_version(&self) -> u32 {
49 let range = self.sfnt_version_byte_range();
50 self.data.read_at(range.start).ok().unwrap()
51 }
52
53 pub fn num_tables(&self) -> u16 {
55 let range = self.num_tables_byte_range();
56 self.data.read_at(range.start).ok().unwrap()
57 }
58
59 pub fn search_range(&self) -> u16 {
60 let range = self.search_range_byte_range();
61 self.data.read_at(range.start).ok().unwrap()
62 }
63
64 pub fn entry_selector(&self) -> u16 {
65 let range = self.entry_selector_byte_range();
66 self.data.read_at(range.start).ok().unwrap()
67 }
68
69 pub fn range_shift(&self) -> u16 {
70 let range = self.range_shift_byte_range();
71 self.data.read_at(range.start).ok().unwrap()
72 }
73
74 pub fn table_records(&self) -> &'a [TableRecord] {
76 let range = self.table_records_byte_range();
77 self.data.read_array(range).ok().unwrap_or_default()
78 }
79
80 pub fn sfnt_version_byte_range(&self) -> Range<usize> {
81 let start = 0;
82 let end = start + u32::RAW_BYTE_LEN;
83 start..end
84 }
85
86 pub fn num_tables_byte_range(&self) -> Range<usize> {
87 let start = self.sfnt_version_byte_range().end;
88 let end = start + u16::RAW_BYTE_LEN;
89 start..end
90 }
91
92 pub fn search_range_byte_range(&self) -> Range<usize> {
93 let start = self.num_tables_byte_range().end;
94 let end = start + u16::RAW_BYTE_LEN;
95 start..end
96 }
97
98 pub fn entry_selector_byte_range(&self) -> Range<usize> {
99 let start = self.search_range_byte_range().end;
100 let end = start + u16::RAW_BYTE_LEN;
101 start..end
102 }
103
104 pub fn range_shift_byte_range(&self) -> Range<usize> {
105 let start = self.entry_selector_byte_range().end;
106 let end = start + u16::RAW_BYTE_LEN;
107 start..end
108 }
109
110 pub fn table_records_byte_range(&self) -> Range<usize> {
111 let num_tables = self.num_tables();
112 let start = self.range_shift_byte_range().end;
113 let end =
114 start + (transforms::to_usize(num_tables)).saturating_mul(TableRecord::RAW_BYTE_LEN);
115 start..end
116 }
117}
118
119const _: () = assert!(FontData::default_data_long_enough(TableDirectory::MIN_SIZE));
120
121impl Default for TableDirectory<'_> {
122 fn default() -> Self {
123 Self {
124 data: FontData::default_table_data(),
125 }
126 }
127}
128
129#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
131#[repr(C)]
132#[repr(packed)]
133pub struct TableRecord {
134 pub tag: BigEndian<Tag>,
136 pub checksum: BigEndian<u32>,
138 pub offset: BigEndian<u32>,
140 pub length: BigEndian<u32>,
142}
143
144impl TableRecord {
145 pub fn tag(&self) -> Tag {
147 self.tag.get()
148 }
149
150 pub fn checksum(&self) -> u32 {
152 self.checksum.get()
153 }
154
155 pub fn offset(&self) -> u32 {
157 self.offset.get()
158 }
159
160 pub fn length(&self) -> u32 {
162 self.length.get()
163 }
164}
165
166impl FixedSize for TableRecord {
167 const RAW_BYTE_LEN: usize =
168 Tag::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN;
169}
170
171impl<'a> MinByteRange<'a> for TTCHeader<'a> {
172 fn min_byte_range(&self) -> Range<usize> {
173 0..self.table_directory_offsets_byte_range().end
174 }
175 fn min_table_bytes(&self) -> &'a [u8] {
176 let range = self.min_byte_range();
177 self.data.as_bytes().get(range).unwrap_or_default()
178 }
179}
180
181impl ReadArgs for TTCHeader<'_> {
182 type Args = ();
183}
184
185impl<'a> FontRead<'a> for TTCHeader<'a> {
186 fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
187 #[allow(clippy::absurd_extreme_comparisons)]
188 if data.len() < Self::MIN_SIZE {
189 return Err(ReadError::OutOfBounds);
190 }
191 Ok(Self { data })
192 }
193}
194
195#[derive(Clone)]
197pub struct TTCHeader<'a> {
198 data: FontData<'a>,
199}
200
201#[allow(clippy::needless_lifetimes)]
202impl<'a> TTCHeader<'a> {
203 pub const MIN_SIZE: usize = (Tag::RAW_BYTE_LEN + MajorMinor::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
204 basic_table_impls!(impl_the_methods);
205
206 pub fn ttc_tag(&self) -> Tag {
208 let range = self.ttc_tag_byte_range();
209 self.data.read_at(range.start).ok().unwrap()
210 }
211
212 pub fn version(&self) -> MajorMinor {
214 let range = self.version_byte_range();
215 self.data.read_at(range.start).ok().unwrap()
216 }
217
218 pub fn num_fonts(&self) -> u32 {
220 let range = self.num_fonts_byte_range();
221 self.data.read_at(range.start).ok().unwrap()
222 }
223
224 pub fn table_directory_offsets(&self) -> &'a [BigEndian<u32>] {
226 let range = self.table_directory_offsets_byte_range();
227 self.data.read_array(range).ok().unwrap_or_default()
228 }
229
230 pub fn dsig_tag(&self) -> Option<u32> {
232 let range = self.dsig_tag_byte_range();
233 (!range.is_empty())
234 .then(|| self.data.read_at(range.start).ok())
235 .flatten()
236 }
237
238 pub fn dsig_length(&self) -> Option<u32> {
240 let range = self.dsig_length_byte_range();
241 (!range.is_empty())
242 .then(|| self.data.read_at(range.start).ok())
243 .flatten()
244 }
245
246 pub fn dsig_offset(&self) -> Option<u32> {
248 let range = self.dsig_offset_byte_range();
249 (!range.is_empty())
250 .then(|| self.data.read_at(range.start).ok())
251 .flatten()
252 }
253
254 pub fn ttc_tag_byte_range(&self) -> Range<usize> {
255 let start = 0;
256 let end = start + Tag::RAW_BYTE_LEN;
257 start..end
258 }
259
260 pub fn version_byte_range(&self) -> Range<usize> {
261 let start = self.ttc_tag_byte_range().end;
262 let end = start + MajorMinor::RAW_BYTE_LEN;
263 start..end
264 }
265
266 pub fn num_fonts_byte_range(&self) -> Range<usize> {
267 let start = self.version_byte_range().end;
268 let end = start + u32::RAW_BYTE_LEN;
269 start..end
270 }
271
272 pub fn table_directory_offsets_byte_range(&self) -> Range<usize> {
273 let num_fonts = self.num_fonts();
274 let start = self.num_fonts_byte_range().end;
275 let end = start + (transforms::to_usize(num_fonts)).saturating_mul(u32::RAW_BYTE_LEN);
276 start..end
277 }
278
279 pub fn dsig_tag_byte_range(&self) -> Range<usize> {
280 let start = self.table_directory_offsets_byte_range().end;
281 let end = if self.version().compatible((2u16, 0u16)) {
282 start + u32::RAW_BYTE_LEN
283 } else {
284 start
285 };
286 start..end
287 }
288
289 pub fn dsig_length_byte_range(&self) -> Range<usize> {
290 let start = self.dsig_tag_byte_range().end;
291 let end = if self.version().compatible((2u16, 0u16)) {
292 start + u32::RAW_BYTE_LEN
293 } else {
294 start
295 };
296 start..end
297 }
298
299 pub fn dsig_offset_byte_range(&self) -> Range<usize> {
300 let start = self.dsig_length_byte_range().end;
301 let end = if self.version().compatible((2u16, 0u16)) {
302 start + u32::RAW_BYTE_LEN
303 } else {
304 start
305 };
306 start..end
307 }
308}
309
310const _: () = assert!(FontData::default_data_long_enough(TTCHeader::MIN_SIZE));
311
312impl Default for TTCHeader<'_> {
313 fn default() -> Self {
314 Self {
315 data: FontData::default_table_data(),
316 }
317 }
318}