read_fonts/generated/
generated_kerx.rs1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8impl<'a> MinByteRange<'a> for Kerx<'a> {
9 fn min_byte_range(&self) -> Range<usize> {
10 0..self.subtables_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 TopLevelTable for Kerx<'_> {
19 const TAG: Tag = Tag::new(b"kerx");
21}
22
23impl<'a> FontRead<'a> for Kerx<'a> {
24 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
25 #[allow(clippy::absurd_extreme_comparisons)]
26 if data.len() < Self::MIN_SIZE {
27 return Err(ReadError::OutOfBounds);
28 }
29 Ok(Self { data })
30 }
31}
32
33#[derive(Clone)]
35pub struct Kerx<'a> {
36 data: FontData<'a>,
37}
38
39#[allow(clippy::needless_lifetimes)]
40impl<'a> Kerx<'a> {
41 pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
42 basic_table_impls!(impl_the_methods);
43
44 pub fn version(&self) -> u16 {
46 let range = self.version_byte_range();
47 self.data.read_at(range.start).ok().unwrap()
48 }
49
50 pub fn n_tables(&self) -> u32 {
52 let range = self.n_tables_byte_range();
53 self.data.read_at(range.start).ok().unwrap()
54 }
55
56 pub fn subtables(&self) -> VarLenArray<'a, Subtable<'a>> {
57 let range = self.subtables_byte_range();
58 self.data
59 .split_off(range.start)
60 .and_then(|d| VarLenArray::read(d).ok())
61 .unwrap_or_default()
62 }
63
64 pub fn version_byte_range(&self) -> Range<usize> {
65 let start = 0;
66 start..start + u16::RAW_BYTE_LEN
67 }
68
69 pub fn padding_byte_range(&self) -> Range<usize> {
70 let start = self.version_byte_range().end;
71 start..start + u16::RAW_BYTE_LEN
72 }
73
74 pub fn n_tables_byte_range(&self) -> Range<usize> {
75 let start = self.padding_byte_range().end;
76 start..start + u32::RAW_BYTE_LEN
77 }
78
79 pub fn subtables_byte_range(&self) -> Range<usize> {
80 let n_tables = self.n_tables();
81 let start = self.n_tables_byte_range().end;
82 start..start + {
83 let data = self.data.split_off(start).unwrap_or_default();
84 <Subtable as VarSize>::total_len_for_count(data, n_tables as usize).unwrap_or(0)
85 }
86 }
87}
88
89const _: () = assert!(FontData::default_data_long_enough(Kerx::MIN_SIZE));
90
91impl Default for Kerx<'_> {
92 fn default() -> Self {
93 Self {
94 data: FontData::default_table_data(),
95 }
96 }
97}
98
99#[cfg(feature = "experimental_traverse")]
100impl<'a> SomeTable<'a> for Kerx<'a> {
101 fn type_name(&self) -> &str {
102 "Kerx"
103 }
104 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
105 match idx {
106 0usize => Some(Field::new("version", self.version())),
107 1usize => Some(Field::new("n_tables", self.n_tables())),
108 2usize => Some(Field::new(
109 "subtables",
110 traversal::FieldType::var_array("Subtable", self.subtables(), self.offset_data()),
111 )),
112 _ => None,
113 }
114 }
115}
116
117#[cfg(feature = "experimental_traverse")]
118#[allow(clippy::needless_lifetimes)]
119impl<'a> std::fmt::Debug for Kerx<'a> {
120 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121 (self as &dyn SomeTable<'a>).fmt(f)
122 }
123}
124
125impl<'a> MinByteRange<'a> for Subtable<'a> {
126 fn min_byte_range(&self) -> Range<usize> {
127 0..self.data_byte_range().end
128 }
129 fn min_table_bytes(&self) -> &'a [u8] {
130 let range = self.min_byte_range();
131 self.data.as_bytes().get(range).unwrap_or_default()
132 }
133}
134
135impl<'a> FontRead<'a> for Subtable<'a> {
136 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
137 #[allow(clippy::absurd_extreme_comparisons)]
138 if data.len() < Self::MIN_SIZE {
139 return Err(ReadError::OutOfBounds);
140 }
141 Ok(Self { data })
142 }
143}
144
145#[derive(Clone)]
147pub struct Subtable<'a> {
148 data: FontData<'a>,
149}
150
151#[allow(clippy::needless_lifetimes)]
152impl<'a> Subtable<'a> {
153 pub const MIN_SIZE: usize = (u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
154 basic_table_impls!(impl_the_methods);
155
156 pub fn length(&self) -> u32 {
158 let range = self.length_byte_range();
159 self.data.read_at(range.start).ok().unwrap()
160 }
161
162 pub fn coverage(&self) -> u32 {
164 let range = self.coverage_byte_range();
165 self.data.read_at(range.start).ok().unwrap()
166 }
167
168 pub fn tuple_count(&self) -> u32 {
170 let range = self.tuple_count_byte_range();
171 self.data.read_at(range.start).ok().unwrap()
172 }
173
174 pub fn data(&self) -> &'a [u8] {
176 let range = self.data_byte_range();
177 self.data.read_array(range).ok().unwrap_or_default()
178 }
179
180 pub fn length_byte_range(&self) -> Range<usize> {
181 let start = 0;
182 start..start + u32::RAW_BYTE_LEN
183 }
184
185 pub fn coverage_byte_range(&self) -> Range<usize> {
186 let start = self.length_byte_range().end;
187 start..start + u32::RAW_BYTE_LEN
188 }
189
190 pub fn tuple_count_byte_range(&self) -> Range<usize> {
191 let start = self.coverage_byte_range().end;
192 start..start + u32::RAW_BYTE_LEN
193 }
194
195 pub fn data_byte_range(&self) -> Range<usize> {
196 let start = self.tuple_count_byte_range().end;
197 start..start + self.data.len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN
198 }
199}
200
201const _: () = assert!(FontData::default_data_long_enough(Subtable::MIN_SIZE));
202
203impl Default for Subtable<'_> {
204 fn default() -> Self {
205 Self {
206 data: FontData::default_table_data(),
207 }
208 }
209}
210
211#[cfg(feature = "experimental_traverse")]
212impl<'a> SomeTable<'a> for Subtable<'a> {
213 fn type_name(&self) -> &str {
214 "Subtable"
215 }
216 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
217 match idx {
218 0usize => Some(Field::new("length", self.length())),
219 1usize => Some(Field::new("coverage", self.coverage())),
220 2usize => Some(Field::new("tuple_count", self.tuple_count())),
221 3usize => Some(Field::new("data", self.data())),
222 _ => None,
223 }
224 }
225}
226
227#[cfg(feature = "experimental_traverse")]
228#[allow(clippy::needless_lifetimes)]
229impl<'a> std::fmt::Debug for Subtable<'a> {
230 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
231 (self as &dyn SomeTable<'a>).fmt(f)
232 }
233}
234
235impl<'a> MinByteRange<'a> for Subtable0<'a> {
236 fn min_byte_range(&self) -> Range<usize> {
237 0..self.pairs_byte_range().end
238 }
239 fn min_table_bytes(&self) -> &'a [u8] {
240 let range = self.min_byte_range();
241 self.data.as_bytes().get(range).unwrap_or_default()
242 }
243}
244
245impl<'a> FontRead<'a> for Subtable0<'a> {
246 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
247 #[allow(clippy::absurd_extreme_comparisons)]
248 if data.len() < Self::MIN_SIZE {
249 return Err(ReadError::OutOfBounds);
250 }
251 Ok(Self { data })
252 }
253}
254
255#[derive(Clone)]
257pub struct Subtable0<'a> {
258 data: FontData<'a>,
259}
260
261#[allow(clippy::needless_lifetimes)]
262impl<'a> Subtable0<'a> {
263 pub const MIN_SIZE: usize =
264 (u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
265 basic_table_impls!(impl_the_methods);
266
267 pub fn n_pairs(&self) -> u32 {
269 let range = self.n_pairs_byte_range();
270 self.data.read_at(range.start).ok().unwrap()
271 }
272
273 pub fn search_range(&self) -> u32 {
275 let range = self.search_range_byte_range();
276 self.data.read_at(range.start).ok().unwrap()
277 }
278
279 pub fn entry_selector(&self) -> u32 {
281 let range = self.entry_selector_byte_range();
282 self.data.read_at(range.start).ok().unwrap()
283 }
284
285 pub fn range_shift(&self) -> u32 {
287 let range = self.range_shift_byte_range();
288 self.data.read_at(range.start).ok().unwrap()
289 }
290
291 pub fn pairs(&self) -> &'a [Subtable0Pair] {
293 let range = self.pairs_byte_range();
294 self.data.read_array(range).ok().unwrap_or_default()
295 }
296
297 pub fn n_pairs_byte_range(&self) -> Range<usize> {
298 let start = 0;
299 start..start + u32::RAW_BYTE_LEN
300 }
301
302 pub fn search_range_byte_range(&self) -> Range<usize> {
303 let start = self.n_pairs_byte_range().end;
304 start..start + u32::RAW_BYTE_LEN
305 }
306
307 pub fn entry_selector_byte_range(&self) -> Range<usize> {
308 let start = self.search_range_byte_range().end;
309 start..start + u32::RAW_BYTE_LEN
310 }
311
312 pub fn range_shift_byte_range(&self) -> Range<usize> {
313 let start = self.entry_selector_byte_range().end;
314 start..start + u32::RAW_BYTE_LEN
315 }
316
317 pub fn pairs_byte_range(&self) -> Range<usize> {
318 let n_pairs = self.n_pairs();
319 let start = self.range_shift_byte_range().end;
320 start..start + (n_pairs as usize).saturating_mul(Subtable0Pair::RAW_BYTE_LEN)
321 }
322}
323
324const _: () = assert!(FontData::default_data_long_enough(Subtable0::MIN_SIZE));
325
326impl Default for Subtable0<'_> {
327 fn default() -> Self {
328 Self {
329 data: FontData::default_table_data(),
330 }
331 }
332}
333
334#[cfg(feature = "experimental_traverse")]
335impl<'a> SomeTable<'a> for Subtable0<'a> {
336 fn type_name(&self) -> &str {
337 "Subtable0"
338 }
339 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
340 match idx {
341 0usize => Some(Field::new("n_pairs", self.n_pairs())),
342 1usize => Some(Field::new("search_range", self.search_range())),
343 2usize => Some(Field::new("entry_selector", self.entry_selector())),
344 3usize => Some(Field::new("range_shift", self.range_shift())),
345 4usize => Some(Field::new(
346 "pairs",
347 traversal::FieldType::array_of_records(
348 stringify!(Subtable0Pair),
349 self.pairs(),
350 self.offset_data(),
351 ),
352 )),
353 _ => None,
354 }
355 }
356}
357
358#[cfg(feature = "experimental_traverse")]
359#[allow(clippy::needless_lifetimes)]
360impl<'a> std::fmt::Debug for Subtable0<'a> {
361 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
362 (self as &dyn SomeTable<'a>).fmt(f)
363 }
364}
365
366#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
368#[repr(C)]
369#[repr(packed)]
370pub struct Subtable0Pair {
371 pub left: BigEndian<GlyphId16>,
373 pub right: BigEndian<GlyphId16>,
375 pub value: BigEndian<i16>,
377}
378
379impl Subtable0Pair {
380 pub fn left(&self) -> GlyphId16 {
382 self.left.get()
383 }
384
385 pub fn right(&self) -> GlyphId16 {
387 self.right.get()
388 }
389
390 pub fn value(&self) -> i16 {
392 self.value.get()
393 }
394}
395
396impl FixedSize for Subtable0Pair {
397 const RAW_BYTE_LEN: usize =
398 GlyphId16::RAW_BYTE_LEN + GlyphId16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN;
399}
400
401#[cfg(feature = "experimental_traverse")]
402impl<'a> SomeRecord<'a> for Subtable0Pair {
403 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
404 RecordResolver {
405 name: "Subtable0Pair",
406 get_field: Box::new(move |idx, _data| match idx {
407 0usize => Some(Field::new("left", self.left())),
408 1usize => Some(Field::new("right", self.right())),
409 2usize => Some(Field::new("value", self.value())),
410 _ => None,
411 }),
412 data,
413 }
414 }
415}