read_fonts/generated/
generated_feat.rs1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8impl<'a> MinByteRange<'a> for Feat<'a> {
9 fn min_byte_range(&self) -> Range<usize> {
10 0..self.names_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 Feat<'_> {
19 const TAG: Tag = Tag::new(b"feat");
21}
22
23impl<'a> FontRead<'a> for Feat<'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 Feat<'a> {
36 data: FontData<'a>,
37}
38
39#[allow(clippy::needless_lifetimes)]
40impl<'a> Feat<'a> {
41 pub const MIN_SIZE: usize =
42 (MajorMinor::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
43 basic_table_impls!(impl_the_methods);
44
45 pub fn version(&self) -> MajorMinor {
48 let range = self.version_byte_range();
49 self.data.read_at(range.start).ok().unwrap()
50 }
51
52 pub fn feature_name_count(&self) -> u16 {
54 let range = self.feature_name_count_byte_range();
55 self.data.read_at(range.start).ok().unwrap()
56 }
57
58 pub fn names(&self) -> &'a [FeatureName] {
60 let range = self.names_byte_range();
61 self.data.read_array(range).ok().unwrap_or_default()
62 }
63
64 pub fn version_byte_range(&self) -> Range<usize> {
65 let start = 0;
66 let end = start + MajorMinor::RAW_BYTE_LEN;
67 start..end
68 }
69
70 pub fn feature_name_count_byte_range(&self) -> Range<usize> {
71 let start = self.version_byte_range().end;
72 let end = start + u16::RAW_BYTE_LEN;
73 start..end
74 }
75
76 pub fn _reserved1_byte_range(&self) -> Range<usize> {
77 let start = self.feature_name_count_byte_range().end;
78 let end = start + u16::RAW_BYTE_LEN;
79 start..end
80 }
81
82 pub fn _reserved2_byte_range(&self) -> Range<usize> {
83 let start = self._reserved1_byte_range().end;
84 let end = start + u32::RAW_BYTE_LEN;
85 start..end
86 }
87
88 pub fn names_byte_range(&self) -> Range<usize> {
89 let feature_name_count = self.feature_name_count();
90 let start = self._reserved2_byte_range().end;
91 let end = start
92 + (transforms::to_usize(feature_name_count)).saturating_mul(FeatureName::RAW_BYTE_LEN);
93 start..end
94 }
95}
96
97const _: () = assert!(FontData::default_data_long_enough(Feat::MIN_SIZE));
98
99impl Default for Feat<'_> {
100 fn default() -> Self {
101 Self {
102 data: FontData::default_table_data(),
103 }
104 }
105}
106
107#[cfg(feature = "experimental_traverse")]
108impl<'a> SomeTable<'a> for Feat<'a> {
109 fn type_name(&self) -> &str {
110 "Feat"
111 }
112 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
113 match idx {
114 0usize => Some(Field::new("version", self.version())),
115 1usize => Some(Field::new("feature_name_count", self.feature_name_count())),
116 2usize => Some(Field::new(
117 "names",
118 traversal::FieldType::array_of_records(
119 stringify!(FeatureName),
120 self.names(),
121 self.offset_data(),
122 ),
123 )),
124 _ => None,
125 }
126 }
127}
128
129#[cfg(feature = "experimental_traverse")]
130#[allow(clippy::needless_lifetimes)]
131impl<'a> std::fmt::Debug for Feat<'a> {
132 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133 (self as &dyn SomeTable<'a>).fmt(f)
134 }
135}
136
137#[derive(Clone, Debug, Copy, bytemuck :: AnyBitPattern)]
139#[repr(C)]
140#[repr(packed)]
141pub struct FeatureName {
142 pub feature: BigEndian<u16>,
144 pub n_settings: BigEndian<u16>,
146 pub setting_table_offset: BigEndian<Offset32>,
150 pub feature_flags: BigEndian<u16>,
152 pub name_index: BigEndian<NameId>,
154}
155
156impl FeatureName {
157 pub fn feature(&self) -> u16 {
159 self.feature.get()
160 }
161
162 pub fn n_settings(&self) -> u16 {
164 self.n_settings.get()
165 }
166
167 pub fn setting_table_offset(&self) -> Offset32 {
171 self.setting_table_offset.get()
172 }
173
174 pub fn setting_table<'a>(&self, data: FontData<'a>) -> Result<SettingNameArray<'a>, ReadError> {
181 let args = self.n_settings();
182 self.setting_table_offset().resolve_with_args(data, &args)
183 }
184
185 pub fn feature_flags(&self) -> u16 {
187 self.feature_flags.get()
188 }
189
190 pub fn name_index(&self) -> NameId {
192 self.name_index.get()
193 }
194}
195
196impl FixedSize for FeatureName {
197 const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN
198 + u16::RAW_BYTE_LEN
199 + Offset32::RAW_BYTE_LEN
200 + u16::RAW_BYTE_LEN
201 + NameId::RAW_BYTE_LEN;
202}
203
204#[cfg(feature = "experimental_traverse")]
205impl<'a> SomeRecord<'a> for FeatureName {
206 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
207 RecordResolver {
208 name: "FeatureName",
209 get_field: Box::new(move |idx, _data| match idx {
210 0usize => Some(Field::new("feature", self.feature())),
211 1usize => Some(Field::new("n_settings", self.n_settings())),
212 2usize => Some(Field::new(
213 "setting_table_offset",
214 FieldType::offset(self.setting_table_offset(), self.setting_table(_data)),
215 )),
216 3usize => Some(Field::new("feature_flags", self.feature_flags())),
217 4usize => Some(Field::new("name_index", self.name_index())),
218 _ => None,
219 }),
220 data,
221 }
222 }
223}
224
225impl<'a> MinByteRange<'a> for SettingNameArray<'a> {
226 fn min_byte_range(&self) -> Range<usize> {
227 0..self.settings_byte_range().end
228 }
229 fn min_table_bytes(&self) -> &'a [u8] {
230 let range = self.min_byte_range();
231 self.data.as_bytes().get(range).unwrap_or_default()
232 }
233}
234
235impl ReadArgs for SettingNameArray<'_> {
236 type Args = u16;
237}
238
239impl<'a> FontReadWithArgs<'a> for SettingNameArray<'a> {
240 fn read_with_args(data: FontData<'a>, args: &u16) -> Result<Self, ReadError> {
241 let n_settings = *args;
242
243 #[allow(clippy::absurd_extreme_comparisons)]
244 if data.len() < Self::MIN_SIZE {
245 return Err(ReadError::OutOfBounds);
246 }
247 Ok(Self { data, n_settings })
248 }
249}
250
251impl<'a> SettingNameArray<'a> {
252 pub fn read(data: FontData<'a>, n_settings: u16) -> Result<Self, ReadError> {
257 let args = n_settings;
258 Self::read_with_args(data, &args)
259 }
260}
261
262#[derive(Clone)]
263pub struct SettingNameArray<'a> {
264 data: FontData<'a>,
265 n_settings: u16,
266}
267
268#[allow(clippy::needless_lifetimes)]
269impl<'a> SettingNameArray<'a> {
270 pub const MIN_SIZE: usize = 0;
271 basic_table_impls!(impl_the_methods);
272
273 pub fn settings(&self) -> &'a [SettingName] {
275 let range = self.settings_byte_range();
276 self.data.read_array(range).ok().unwrap_or_default()
277 }
278
279 pub(crate) fn n_settings(&self) -> u16 {
280 self.n_settings
281 }
282
283 pub fn settings_byte_range(&self) -> Range<usize> {
284 let n_settings = self.n_settings();
285 let start = 0;
286 let end =
287 start + (transforms::to_usize(n_settings)).saturating_mul(SettingName::RAW_BYTE_LEN);
288 start..end
289 }
290}
291
292#[allow(clippy::absurd_extreme_comparisons)]
293const _: () = assert!(FontData::default_data_long_enough(
294 SettingNameArray::MIN_SIZE
295));
296
297impl Default for SettingNameArray<'_> {
298 fn default() -> Self {
299 Self {
300 data: FontData::default_table_data(),
301 n_settings: Default::default(),
302 }
303 }
304}
305
306#[cfg(feature = "experimental_traverse")]
307impl<'a> SomeTable<'a> for SettingNameArray<'a> {
308 fn type_name(&self) -> &str {
309 "SettingNameArray"
310 }
311 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
312 match idx {
313 0usize => Some(Field::new(
314 "settings",
315 traversal::FieldType::array_of_records(
316 stringify!(SettingName),
317 self.settings(),
318 self.offset_data(),
319 ),
320 )),
321 _ => None,
322 }
323 }
324}
325
326#[cfg(feature = "experimental_traverse")]
327#[allow(clippy::needless_lifetimes)]
328impl<'a> std::fmt::Debug for SettingNameArray<'a> {
329 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
330 (self as &dyn SomeTable<'a>).fmt(f)
331 }
332}
333
334#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
336#[repr(C)]
337#[repr(packed)]
338pub struct SettingName {
339 pub setting: BigEndian<u16>,
341 pub name_index: BigEndian<NameId>,
343}
344
345impl SettingName {
346 pub fn setting(&self) -> u16 {
348 self.setting.get()
349 }
350
351 pub fn name_index(&self) -> NameId {
353 self.name_index.get()
354 }
355}
356
357impl FixedSize for SettingName {
358 const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + NameId::RAW_BYTE_LEN;
359}
360
361#[cfg(feature = "experimental_traverse")]
362impl<'a> SomeRecord<'a> for SettingName {
363 fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
364 RecordResolver {
365 name: "SettingName",
366 get_field: Box::new(move |idx, _data| match idx {
367 0usize => Some(Field::new("setting", self.setting())),
368 1usize => Some(Field::new("name_index", self.name_index())),
369 _ => None,
370 }),
371 data,
372 }
373 }
374}