/src/fontations/read-fonts/generated/generated_morx.rs
Line | Count | Source |
1 | | // THIS FILE IS AUTOGENERATED. |
2 | | // Any changes to this file will be overwritten. |
3 | | // For more information about how codegen works, see font-codegen/README.md |
4 | | |
5 | | #[allow(unused_imports)] |
6 | | use crate::codegen_prelude::*; |
7 | | |
8 | | impl<'a> MinByteRange<'a> for Morx<'a> { |
9 | 0 | fn min_byte_range(&self) -> Range<usize> { |
10 | 0 | 0..self.chains_byte_range().end |
11 | 0 | } |
12 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
13 | 0 | let range = self.min_byte_range(); |
14 | 0 | self.data.as_bytes().get(range).unwrap_or_default() |
15 | 0 | } |
16 | | } |
17 | | |
18 | | impl TopLevelTable for Morx<'_> { |
19 | | /// `morx` |
20 | | const TAG: Tag = Tag::new(b"morx"); |
21 | | } |
22 | | |
23 | | impl ReadArgs for Morx<'_> { |
24 | | type Args = (); |
25 | | } |
26 | | |
27 | | impl<'a> FontRead<'a> for Morx<'a> { |
28 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
29 | | #[allow(clippy::absurd_extreme_comparisons)] |
30 | 0 | if data.len() < Self::MIN_SIZE { |
31 | 0 | return Err(ReadError::OutOfBounds); |
32 | 0 | } |
33 | 0 | Ok(Self { data }) |
34 | 0 | } |
35 | | } |
36 | | |
37 | | /// The [morx (Extended Glyph Metamorphosis)](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html) table. |
38 | | #[derive(Clone)] |
39 | | pub struct Morx<'a> { |
40 | | data: FontData<'a>, |
41 | | } |
42 | | |
43 | | #[allow(clippy::needless_lifetimes)] |
44 | | impl<'a> Morx<'a> { |
45 | | pub const MIN_SIZE: usize = (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN); |
46 | | basic_table_impls!(impl_the_methods); |
47 | | |
48 | | /// Version number of the extended glyph metamorphosis table (either 2 or 3). |
49 | 0 | pub fn version(&self) -> u16 { |
50 | 0 | let range = self.version_byte_range(); |
51 | 0 | self.data.read_at(range.start).ok().unwrap() |
52 | 0 | } |
53 | | |
54 | | /// Number of metamorphosis chains contained in this table. |
55 | 0 | pub fn n_chains(&self) -> u32 { |
56 | 0 | let range = self.n_chains_byte_range(); |
57 | 0 | self.data.read_at(range.start).ok().unwrap() |
58 | 0 | } |
59 | | |
60 | 0 | pub fn chains(&self) -> VarLenArray<'a, Chain<'a>> { |
61 | 0 | let range = self.chains_byte_range(); |
62 | 0 | self.data |
63 | 0 | .split_off(range.start) |
64 | 0 | .and_then(|d| VarLenArray::read(d).ok()) |
65 | 0 | .unwrap_or_default() |
66 | 0 | } |
67 | | |
68 | 0 | pub fn version_byte_range(&self) -> Range<usize> { |
69 | 0 | let start = 0; |
70 | 0 | let end = start + u16::RAW_BYTE_LEN; |
71 | 0 | start..end |
72 | 0 | } |
73 | | |
74 | 0 | pub fn unused_byte_range(&self) -> Range<usize> { |
75 | 0 | let start = self.version_byte_range().end; |
76 | 0 | let end = start + u16::RAW_BYTE_LEN; |
77 | 0 | start..end |
78 | 0 | } |
79 | | |
80 | 0 | pub fn n_chains_byte_range(&self) -> Range<usize> { |
81 | 0 | let start = self.unused_byte_range().end; |
82 | 0 | let end = start + u32::RAW_BYTE_LEN; |
83 | 0 | start..end |
84 | 0 | } |
85 | | |
86 | 0 | pub fn chains_byte_range(&self) -> Range<usize> { |
87 | 0 | let n_chains = self.n_chains(); |
88 | 0 | let start = self.n_chains_byte_range().end; |
89 | 0 | let end = start + { |
90 | 0 | let data = self.data.split_off(start).unwrap_or_default(); |
91 | 0 | <Chain as VarSize>::total_len_for_count(data, transforms::to_usize(n_chains)) |
92 | 0 | .unwrap_or(0) |
93 | 0 | }; |
94 | 0 | start..end |
95 | 0 | } |
96 | | } |
97 | | |
98 | | const _: () = assert!(FontData::default_data_long_enough(Morx::MIN_SIZE)); |
99 | | |
100 | | impl Default for Morx<'_> { |
101 | 0 | fn default() -> Self { |
102 | 0 | Self { |
103 | 0 | data: FontData::default_table_data(), |
104 | 0 | } |
105 | 0 | } |
106 | | } |
107 | | |
108 | | #[cfg(feature = "experimental_traverse")] |
109 | | impl<'a> SomeTable<'a> for Morx<'a> { |
110 | | fn type_name(&self) -> &str { |
111 | | "Morx" |
112 | | } |
113 | | fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
114 | | match idx { |
115 | | 0usize => Some(Field::new("version", self.version())), |
116 | | 1usize => Some(Field::new("n_chains", self.n_chains())), |
117 | | 2usize => Some(Field::new( |
118 | | "chains", |
119 | | traversal::FieldType::var_array("Chain", self.chains(), self.offset_data()), |
120 | | )), |
121 | | _ => None, |
122 | | } |
123 | | } |
124 | | } |
125 | | |
126 | | #[cfg(feature = "experimental_traverse")] |
127 | | #[allow(clippy::needless_lifetimes)] |
128 | | impl<'a> std::fmt::Debug for Morx<'a> { |
129 | | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
130 | | (self as &dyn SomeTable<'a>).fmt(f) |
131 | | } |
132 | | } |
133 | | |
134 | | impl<'a> MinByteRange<'a> for Chain<'a> { |
135 | 0 | fn min_byte_range(&self) -> Range<usize> { |
136 | 0 | 0..self.subtables_byte_range().end |
137 | 0 | } |
138 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
139 | 0 | let range = self.min_byte_range(); |
140 | 0 | self.data.as_bytes().get(range).unwrap_or_default() |
141 | 0 | } |
142 | | } |
143 | | |
144 | | impl ReadArgs for Chain<'_> { |
145 | | type Args = (); |
146 | | } |
147 | | |
148 | | impl<'a> FontRead<'a> for Chain<'a> { |
149 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
150 | | #[allow(clippy::absurd_extreme_comparisons)] |
151 | 0 | if data.len() < Self::MIN_SIZE { |
152 | 0 | return Err(ReadError::OutOfBounds); |
153 | 0 | } |
154 | 0 | Ok(Self { data }) |
155 | 0 | } |
156 | | } |
157 | | |
158 | | /// A chain in a `morx` table. |
159 | | #[derive(Clone)] |
160 | | pub struct Chain<'a> { |
161 | | data: FontData<'a>, |
162 | | } |
163 | | |
164 | | #[allow(clippy::needless_lifetimes)] |
165 | | impl<'a> Chain<'a> { |
166 | | pub const MIN_SIZE: usize = |
167 | | (u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN); |
168 | | basic_table_impls!(impl_the_methods); |
169 | | |
170 | | /// The default specification for subtables. |
171 | 0 | pub fn default_flags(&self) -> u32 { |
172 | 0 | let range = self.default_flags_byte_range(); |
173 | 0 | self.data.read_at(range.start).ok().unwrap() |
174 | 0 | } |
175 | | |
176 | | /// Total byte count, including this header; must be a multiple of 4. |
177 | 0 | pub fn chain_length(&self) -> u32 { |
178 | 0 | let range = self.chain_length_byte_range(); |
179 | 0 | self.data.read_at(range.start).ok().unwrap() |
180 | 0 | } |
181 | | |
182 | | /// Number of feature subtable entries. |
183 | 0 | pub fn n_feature_entries(&self) -> u32 { |
184 | 0 | let range = self.n_feature_entries_byte_range(); |
185 | 0 | self.data.read_at(range.start).ok().unwrap() |
186 | 0 | } |
187 | | |
188 | | /// The number of subtables in the chain. |
189 | 0 | pub fn n_subtables(&self) -> u32 { |
190 | 0 | let range = self.n_subtables_byte_range(); |
191 | 0 | self.data.read_at(range.start).ok().unwrap() |
192 | 0 | } |
193 | | |
194 | | /// Feature entries for this chain. |
195 | 0 | pub fn features(&self) -> &'a [Feature] { |
196 | 0 | let range = self.features_byte_range(); |
197 | 0 | self.data.read_array(range).ok().unwrap_or_default() |
198 | 0 | } |
199 | | |
200 | | /// Array of chain subtables. |
201 | 0 | pub fn subtables(&self) -> VarLenArray<'a, Subtable<'a>> { |
202 | 0 | let range = self.subtables_byte_range(); |
203 | 0 | self.data |
204 | 0 | .split_off(range.start) |
205 | 0 | .and_then(|d| VarLenArray::read(d).ok()) |
206 | 0 | .unwrap_or_default() |
207 | 0 | } |
208 | | |
209 | 0 | pub fn default_flags_byte_range(&self) -> Range<usize> { |
210 | 0 | let start = 0; |
211 | 0 | let end = start + u32::RAW_BYTE_LEN; |
212 | 0 | start..end |
213 | 0 | } |
214 | | |
215 | 0 | pub fn chain_length_byte_range(&self) -> Range<usize> { |
216 | 0 | let start = self.default_flags_byte_range().end; |
217 | 0 | let end = start + u32::RAW_BYTE_LEN; |
218 | 0 | start..end |
219 | 0 | } |
220 | | |
221 | 0 | pub fn n_feature_entries_byte_range(&self) -> Range<usize> { |
222 | 0 | let start = self.chain_length_byte_range().end; |
223 | 0 | let end = start + u32::RAW_BYTE_LEN; |
224 | 0 | start..end |
225 | 0 | } |
226 | | |
227 | 0 | pub fn n_subtables_byte_range(&self) -> Range<usize> { |
228 | 0 | let start = self.n_feature_entries_byte_range().end; |
229 | 0 | let end = start + u32::RAW_BYTE_LEN; |
230 | 0 | start..end |
231 | 0 | } |
232 | | |
233 | 0 | pub fn features_byte_range(&self) -> Range<usize> { |
234 | 0 | let n_feature_entries = self.n_feature_entries(); |
235 | 0 | let start = self.n_subtables_byte_range().end; |
236 | 0 | let end = |
237 | 0 | start + (transforms::to_usize(n_feature_entries)).saturating_mul(Feature::RAW_BYTE_LEN); |
238 | 0 | start..end |
239 | 0 | } |
240 | | |
241 | 0 | pub fn subtables_byte_range(&self) -> Range<usize> { |
242 | 0 | let n_subtables = self.n_subtables(); |
243 | 0 | let start = self.features_byte_range().end; |
244 | 0 | let end = start + { |
245 | 0 | let data = self.data.split_off(start).unwrap_or_default(); |
246 | 0 | <Subtable as VarSize>::total_len_for_count(data, transforms::to_usize(n_subtables)) |
247 | 0 | .unwrap_or(0) |
248 | 0 | }; |
249 | 0 | start..end |
250 | 0 | } |
251 | | } |
252 | | |
253 | | const _: () = assert!(FontData::default_data_long_enough(Chain::MIN_SIZE)); |
254 | | |
255 | | impl Default for Chain<'_> { |
256 | 0 | fn default() -> Self { |
257 | 0 | Self { |
258 | 0 | data: FontData::default_table_data(), |
259 | 0 | } |
260 | 0 | } |
261 | | } |
262 | | |
263 | | #[cfg(feature = "experimental_traverse")] |
264 | | impl<'a> SomeTable<'a> for Chain<'a> { |
265 | | fn type_name(&self) -> &str { |
266 | | "Chain" |
267 | | } |
268 | | fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
269 | | match idx { |
270 | | 0usize => Some(Field::new("default_flags", self.default_flags())), |
271 | | 1usize => Some(Field::new("chain_length", self.chain_length())), |
272 | | 2usize => Some(Field::new("n_feature_entries", self.n_feature_entries())), |
273 | | 3usize => Some(Field::new("n_subtables", self.n_subtables())), |
274 | | 4usize => Some(Field::new( |
275 | | "features", |
276 | | traversal::FieldType::array_of_records( |
277 | | stringify!(Feature), |
278 | | self.features(), |
279 | | self.offset_data(), |
280 | | ), |
281 | | )), |
282 | | 5usize => Some(Field::new( |
283 | | "subtables", |
284 | | traversal::FieldType::var_array("Subtable", self.subtables(), self.offset_data()), |
285 | | )), |
286 | | _ => None, |
287 | | } |
288 | | } |
289 | | } |
290 | | |
291 | | #[cfg(feature = "experimental_traverse")] |
292 | | #[allow(clippy::needless_lifetimes)] |
293 | | impl<'a> std::fmt::Debug for Chain<'a> { |
294 | | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
295 | | (self as &dyn SomeTable<'a>).fmt(f) |
296 | | } |
297 | | } |
298 | | |
299 | | /// Used to compute the sub-feature flags for a list of requested features and settings. |
300 | | #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
301 | | #[repr(C)] |
302 | | #[repr(packed)] |
303 | | pub struct Feature { |
304 | | /// The type of feature. |
305 | | pub feature_type: BigEndian<u16>, |
306 | | /// The feature's setting (aka selector). |
307 | | pub feature_settings: BigEndian<u16>, |
308 | | /// Flags for the settings that this feature and setting enables. |
309 | | pub enable_flags: BigEndian<u32>, |
310 | | /// Complement of flags for the settings that this feature and setting disable. |
311 | | pub disable_flags: BigEndian<u32>, |
312 | | } |
313 | | |
314 | | impl Feature { |
315 | | /// The type of feature. |
316 | 0 | pub fn feature_type(&self) -> u16 { |
317 | 0 | self.feature_type.get() |
318 | 0 | } |
319 | | |
320 | | /// The feature's setting (aka selector). |
321 | 0 | pub fn feature_settings(&self) -> u16 { |
322 | 0 | self.feature_settings.get() |
323 | 0 | } |
324 | | |
325 | | /// Flags for the settings that this feature and setting enables. |
326 | 0 | pub fn enable_flags(&self) -> u32 { |
327 | 0 | self.enable_flags.get() |
328 | 0 | } |
329 | | |
330 | | /// Complement of flags for the settings that this feature and setting disable. |
331 | 0 | pub fn disable_flags(&self) -> u32 { |
332 | 0 | self.disable_flags.get() |
333 | 0 | } |
334 | | } |
335 | | |
336 | | impl FixedSize for Feature { |
337 | | const RAW_BYTE_LEN: usize = |
338 | | u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN; |
339 | | } |
340 | | |
341 | | #[cfg(feature = "experimental_traverse")] |
342 | | impl<'a> SomeRecord<'a> for Feature { |
343 | | fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
344 | | RecordResolver { |
345 | | name: "Feature", |
346 | | get_field: Box::new(move |idx, _data| match idx { |
347 | | 0usize => Some(Field::new("feature_type", self.feature_type())), |
348 | | 1usize => Some(Field::new("feature_settings", self.feature_settings())), |
349 | | 2usize => Some(Field::new("enable_flags", self.enable_flags())), |
350 | | 3usize => Some(Field::new("disable_flags", self.disable_flags())), |
351 | | _ => None, |
352 | | }), |
353 | | data, |
354 | | } |
355 | | } |
356 | | } |
357 | | |
358 | | impl<'a> MinByteRange<'a> for Subtable<'a> { |
359 | 0 | fn min_byte_range(&self) -> Range<usize> { |
360 | 0 | 0..self.data_byte_range().end |
361 | 0 | } |
362 | 0 | fn min_table_bytes(&self) -> &'a [u8] { |
363 | 0 | let range = self.min_byte_range(); |
364 | 0 | self.data.as_bytes().get(range).unwrap_or_default() |
365 | 0 | } |
366 | | } |
367 | | |
368 | | impl ReadArgs for Subtable<'_> { |
369 | | type Args = (); |
370 | | } |
371 | | |
372 | | impl<'a> FontRead<'a> for Subtable<'a> { |
373 | 0 | fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> { |
374 | | #[allow(clippy::absurd_extreme_comparisons)] |
375 | 0 | if data.len() < Self::MIN_SIZE { |
376 | 0 | return Err(ReadError::OutOfBounds); |
377 | 0 | } |
378 | 0 | Ok(Self { data }) |
379 | 0 | } |
380 | | } |
381 | | |
382 | | /// A subtable in a `morx` chain. |
383 | | #[derive(Clone)] |
384 | | pub struct Subtable<'a> { |
385 | | data: FontData<'a>, |
386 | | } |
387 | | |
388 | | #[allow(clippy::needless_lifetimes)] |
389 | | impl<'a> Subtable<'a> { |
390 | | pub const MIN_SIZE: usize = (u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN); |
391 | | basic_table_impls!(impl_the_methods); |
392 | | |
393 | | /// Total subtable length, including this header. |
394 | 0 | pub fn length(&self) -> u32 { |
395 | 0 | let range = self.length_byte_range(); |
396 | 0 | self.data.read_at(range.start).ok().unwrap() |
397 | 0 | } |
398 | | |
399 | | /// Coverage flags and subtable type. |
400 | 0 | pub fn coverage(&self) -> u32 { |
401 | 0 | let range = self.coverage_byte_range(); |
402 | 0 | self.data.read_at(range.start).ok().unwrap() |
403 | 0 | } |
404 | | |
405 | | /// The 32-bit mask identifying which subtable this is (the subtable being executed if the AND of this value and the processed defaultFlags is nonzero). |
406 | 0 | pub fn sub_feature_flags(&self) -> u32 { |
407 | 0 | let range = self.sub_feature_flags_byte_range(); |
408 | 0 | self.data.read_at(range.start).ok().unwrap() |
409 | 0 | } |
410 | | |
411 | | /// Data for specific subtable. |
412 | 0 | pub fn data(&self) -> &'a [u8] { |
413 | 0 | let range = self.data_byte_range(); |
414 | 0 | self.data.read_array(range).ok().unwrap_or_default() |
415 | 0 | } |
416 | | |
417 | 0 | pub fn length_byte_range(&self) -> Range<usize> { |
418 | 0 | let start = 0; |
419 | 0 | let end = start + u32::RAW_BYTE_LEN; |
420 | 0 | start..end |
421 | 0 | } |
422 | | |
423 | 0 | pub fn coverage_byte_range(&self) -> Range<usize> { |
424 | 0 | let start = self.length_byte_range().end; |
425 | 0 | let end = start + u32::RAW_BYTE_LEN; |
426 | 0 | start..end |
427 | 0 | } |
428 | | |
429 | 0 | pub fn sub_feature_flags_byte_range(&self) -> Range<usize> { |
430 | 0 | let start = self.coverage_byte_range().end; |
431 | 0 | let end = start + u32::RAW_BYTE_LEN; |
432 | 0 | start..end |
433 | 0 | } |
434 | | |
435 | 0 | pub fn data_byte_range(&self) -> Range<usize> { |
436 | 0 | let start = self.sub_feature_flags_byte_range().end; |
437 | 0 | let end = |
438 | 0 | start + self.data.len().saturating_sub(start) / u8::RAW_BYTE_LEN * u8::RAW_BYTE_LEN; |
439 | 0 | start..end |
440 | 0 | } |
441 | | } |
442 | | |
443 | | const _: () = assert!(FontData::default_data_long_enough(Subtable::MIN_SIZE)); |
444 | | |
445 | | impl Default for Subtable<'_> { |
446 | 0 | fn default() -> Self { |
447 | 0 | Self { |
448 | 0 | data: FontData::default_table_data(), |
449 | 0 | } |
450 | 0 | } |
451 | | } |
452 | | |
453 | | #[cfg(feature = "experimental_traverse")] |
454 | | impl<'a> SomeTable<'a> for Subtable<'a> { |
455 | | fn type_name(&self) -> &str { |
456 | | "Subtable" |
457 | | } |
458 | | fn get_field(&self, idx: usize) -> Option<Field<'a>> { |
459 | | match idx { |
460 | | 0usize => Some(Field::new("length", self.length())), |
461 | | 1usize => Some(Field::new("coverage", self.coverage())), |
462 | | 2usize => Some(Field::new("sub_feature_flags", self.sub_feature_flags())), |
463 | | 3usize => Some(Field::new("data", self.data())), |
464 | | _ => None, |
465 | | } |
466 | | } |
467 | | } |
468 | | |
469 | | #[cfg(feature = "experimental_traverse")] |
470 | | #[allow(clippy::needless_lifetimes)] |
471 | | impl<'a> std::fmt::Debug for Subtable<'a> { |
472 | | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
473 | | (self as &dyn SomeTable<'a>).fmt(f) |
474 | | } |
475 | | } |
476 | | |
477 | | /// Entry payload in a contextual subtable state machine. |
478 | | #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
479 | | #[repr(C)] |
480 | | #[repr(packed)] |
481 | | pub struct ContextualEntryData { |
482 | | /// Index of the substitution table for the marked glyph (use 0xFFFF for |
483 | | /// none). |
484 | | pub mark_index: BigEndian<u16>, |
485 | | /// Index of the substitution table for the current glyph (use 0xFFFF for |
486 | | /// none) |
487 | | pub current_index: BigEndian<u16>, |
488 | | } |
489 | | |
490 | | impl ContextualEntryData { |
491 | | /// Index of the substitution table for the marked glyph (use 0xFFFF for |
492 | | /// none). |
493 | 0 | pub fn mark_index(&self) -> u16 { |
494 | 0 | self.mark_index.get() |
495 | 0 | } |
496 | | |
497 | | /// Index of the substitution table for the current glyph (use 0xFFFF for |
498 | | /// none) |
499 | 0 | pub fn current_index(&self) -> u16 { |
500 | 0 | self.current_index.get() |
501 | 0 | } |
502 | | } |
503 | | |
504 | | impl FixedSize for ContextualEntryData { |
505 | | const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; |
506 | | } |
507 | | |
508 | | #[cfg(feature = "experimental_traverse")] |
509 | | impl<'a> SomeRecord<'a> for ContextualEntryData { |
510 | | fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
511 | | RecordResolver { |
512 | | name: "ContextualEntryData", |
513 | | get_field: Box::new(move |idx, _data| match idx { |
514 | | 0usize => Some(Field::new("mark_index", self.mark_index())), |
515 | | 1usize => Some(Field::new("current_index", self.current_index())), |
516 | | _ => None, |
517 | | }), |
518 | | data, |
519 | | } |
520 | | } |
521 | | } |
522 | | |
523 | | /// Entry payload in an insertion subtable state machine. |
524 | | #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)] |
525 | | #[repr(C)] |
526 | | #[repr(packed)] |
527 | | pub struct InsertionEntryData { |
528 | | /// Zero-based index into the insertion glyph table. The number of glyphs |
529 | | /// to be inserted is contained in the currentInsertCount field in the |
530 | | /// flags (see below). A value of 0xFFFF indicates no insertion is to be done. |
531 | | pub current_insert_index: BigEndian<u16>, |
532 | | /// Zero-based index into the insertion glyph table. The number of glyphs |
533 | | /// to be inserted is contained in the markedInsertCount field in the |
534 | | /// flags (see below). A value of 0xFFFF indicates no insertion is to be |
535 | | /// done. |
536 | | pub marked_insert_index: BigEndian<u16>, |
537 | | } |
538 | | |
539 | | impl InsertionEntryData { |
540 | | /// Zero-based index into the insertion glyph table. The number of glyphs |
541 | | /// to be inserted is contained in the currentInsertCount field in the |
542 | | /// flags (see below). A value of 0xFFFF indicates no insertion is to be done. |
543 | 0 | pub fn current_insert_index(&self) -> u16 { |
544 | 0 | self.current_insert_index.get() |
545 | 0 | } |
546 | | |
547 | | /// Zero-based index into the insertion glyph table. The number of glyphs |
548 | | /// to be inserted is contained in the markedInsertCount field in the |
549 | | /// flags (see below). A value of 0xFFFF indicates no insertion is to be |
550 | | /// done. |
551 | 0 | pub fn marked_insert_index(&self) -> u16 { |
552 | 0 | self.marked_insert_index.get() |
553 | 0 | } |
554 | | } |
555 | | |
556 | | impl FixedSize for InsertionEntryData { |
557 | | const RAW_BYTE_LEN: usize = u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN; |
558 | | } |
559 | | |
560 | | #[cfg(feature = "experimental_traverse")] |
561 | | impl<'a> SomeRecord<'a> for InsertionEntryData { |
562 | | fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> { |
563 | | RecordResolver { |
564 | | name: "InsertionEntryData", |
565 | | get_field: Box::new(move |idx, _data| match idx { |
566 | | 0usize => Some(Field::new( |
567 | | "current_insert_index", |
568 | | self.current_insert_index(), |
569 | | )), |
570 | | 1usize => Some(Field::new( |
571 | | "marked_insert_index", |
572 | | self.marked_insert_index(), |
573 | | )), |
574 | | _ => None, |
575 | | }), |
576 | | data, |
577 | | } |
578 | | } |
579 | | } |