Skip to main content

read_fonts/generated/
generated_ankr.rs

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)]
6use crate::codegen_prelude::*;
7
8impl<'a> MinByteRange<'a> for Ankr<'a> {
9    fn min_byte_range(&self) -> Range<usize> {
10        0..self.glyph_data_table_offset_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 Ankr<'_> {
19    /// `ankr`
20    const TAG: Tag = Tag::new(b"ankr");
21}
22
23impl ReadArgs for Ankr<'_> {
24    type Args = ();
25}
26
27impl<'a> FontRead<'a> for Ankr<'a> {
28    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
29        #[allow(clippy::absurd_extreme_comparisons)]
30        if data.len() < Self::MIN_SIZE {
31            return Err(ReadError::OutOfBounds);
32        }
33        Ok(Self { data })
34    }
35}
36
37/// The [anchor point](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6ankr.html) table.
38#[derive(Clone)]
39pub struct Ankr<'a> {
40    data: FontData<'a>,
41}
42
43#[allow(clippy::needless_lifetimes)]
44impl<'a> Ankr<'a> {
45    pub const MIN_SIZE: usize =
46        (u16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN + Offset32::RAW_BYTE_LEN + u32::RAW_BYTE_LEN);
47    basic_table_impls!(impl_the_methods);
48
49    /// Version number (set to zero).
50    pub fn version(&self) -> u16 {
51        let range = self.version_byte_range();
52        self.data.read_at(range.start).ok().unwrap()
53    }
54
55    /// Flags (currently unused; set to zero).
56    pub fn flags(&self) -> u16 {
57        let range = self.flags_byte_range();
58        self.data.read_at(range.start).ok().unwrap()
59    }
60
61    /// Offset to the table's lookup table; currently this is always `0x0000000C`.
62    ///
63    /// Lookup values are two byte offsets into the glyph data table.
64    pub fn lookup_table_offset(&self) -> Offset32 {
65        let range = self.lookup_table_offset_byte_range();
66        self.data.read_at(range.start).ok().unwrap()
67    }
68
69    /// Attempt to resolve [`lookup_table_offset`][Self::lookup_table_offset].
70    pub fn lookup_table(&self) -> Result<LookupU16<'a>, ReadError> {
71        let data = self.data;
72        self.lookup_table_offset().resolve(data)
73    }
74
75    /// Offset to the glyph data table.
76    pub fn glyph_data_table_offset(&self) -> u32 {
77        let range = self.glyph_data_table_offset_byte_range();
78        self.data.read_at(range.start).ok().unwrap()
79    }
80
81    pub fn version_byte_range(&self) -> Range<usize> {
82        let start = 0;
83        let end = start + u16::RAW_BYTE_LEN;
84        start..end
85    }
86
87    pub fn flags_byte_range(&self) -> Range<usize> {
88        let start = self.version_byte_range().end;
89        let end = start + u16::RAW_BYTE_LEN;
90        start..end
91    }
92
93    pub fn lookup_table_offset_byte_range(&self) -> Range<usize> {
94        let start = self.flags_byte_range().end;
95        let end = start + Offset32::RAW_BYTE_LEN;
96        start..end
97    }
98
99    pub fn glyph_data_table_offset_byte_range(&self) -> Range<usize> {
100        let start = self.lookup_table_offset_byte_range().end;
101        let end = start + u32::RAW_BYTE_LEN;
102        start..end
103    }
104}
105
106const _: () = assert!(FontData::default_data_long_enough(Ankr::MIN_SIZE));
107
108impl Default for Ankr<'_> {
109    fn default() -> Self {
110        Self {
111            data: FontData::default_table_data(),
112        }
113    }
114}
115
116#[cfg(feature = "experimental_traverse")]
117impl<'a> SomeTable<'a> for Ankr<'a> {
118    fn type_name(&self) -> &str {
119        "Ankr"
120    }
121    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
122        match idx {
123            0usize => Some(Field::new("version", self.version())),
124            1usize => Some(Field::new("flags", self.flags())),
125            2usize => Some(Field::new(
126                "lookup_table_offset",
127                FieldType::offset(self.lookup_table_offset(), self.lookup_table()),
128            )),
129            3usize => Some(Field::new(
130                "glyph_data_table_offset",
131                self.glyph_data_table_offset(),
132            )),
133            _ => None,
134        }
135    }
136}
137
138#[cfg(feature = "experimental_traverse")]
139#[allow(clippy::needless_lifetimes)]
140impl<'a> std::fmt::Debug for Ankr<'a> {
141    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
142        (self as &dyn SomeTable<'a>).fmt(f)
143    }
144}
145
146impl<'a> MinByteRange<'a> for GlyphDataEntry<'a> {
147    fn min_byte_range(&self) -> Range<usize> {
148        0..self.anchor_points_byte_range().end
149    }
150    fn min_table_bytes(&self) -> &'a [u8] {
151        let range = self.min_byte_range();
152        self.data.as_bytes().get(range).unwrap_or_default()
153    }
154}
155
156impl ReadArgs for GlyphDataEntry<'_> {
157    type Args = ();
158}
159
160impl<'a> FontRead<'a> for GlyphDataEntry<'a> {
161    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
162        #[allow(clippy::absurd_extreme_comparisons)]
163        if data.len() < Self::MIN_SIZE {
164            return Err(ReadError::OutOfBounds);
165        }
166        Ok(Self { data })
167    }
168}
169
170#[derive(Clone)]
171pub struct GlyphDataEntry<'a> {
172    data: FontData<'a>,
173}
174
175#[allow(clippy::needless_lifetimes)]
176impl<'a> GlyphDataEntry<'a> {
177    pub const MIN_SIZE: usize = u32::RAW_BYTE_LEN;
178    basic_table_impls!(impl_the_methods);
179
180    /// Number of anchor points for this glyph.
181    pub fn num_points(&self) -> u32 {
182        let range = self.num_points_byte_range();
183        self.data.read_at(range.start).ok().unwrap()
184    }
185
186    /// Individual anchor points.
187    pub fn anchor_points(&self) -> &'a [AnchorPoint] {
188        let range = self.anchor_points_byte_range();
189        self.data.read_array(range).ok().unwrap_or_default()
190    }
191
192    pub fn num_points_byte_range(&self) -> Range<usize> {
193        let start = 0;
194        let end = start + u32::RAW_BYTE_LEN;
195        start..end
196    }
197
198    pub fn anchor_points_byte_range(&self) -> Range<usize> {
199        let num_points = self.num_points();
200        let start = self.num_points_byte_range().end;
201        let end =
202            start + (transforms::to_usize(num_points)).saturating_mul(AnchorPoint::RAW_BYTE_LEN);
203        start..end
204    }
205}
206
207const _: () = assert!(FontData::default_data_long_enough(GlyphDataEntry::MIN_SIZE));
208
209impl Default for GlyphDataEntry<'_> {
210    fn default() -> Self {
211        Self {
212            data: FontData::default_table_data(),
213        }
214    }
215}
216
217#[cfg(feature = "experimental_traverse")]
218impl<'a> SomeTable<'a> for GlyphDataEntry<'a> {
219    fn type_name(&self) -> &str {
220        "GlyphDataEntry"
221    }
222    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
223        match idx {
224            0usize => Some(Field::new("num_points", self.num_points())),
225            1usize => Some(Field::new(
226                "anchor_points",
227                traversal::FieldType::array_of_records(
228                    stringify!(AnchorPoint),
229                    self.anchor_points(),
230                    self.offset_data(),
231                ),
232            )),
233            _ => None,
234        }
235    }
236}
237
238#[cfg(feature = "experimental_traverse")]
239#[allow(clippy::needless_lifetimes)]
240impl<'a> std::fmt::Debug for GlyphDataEntry<'a> {
241    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
242        (self as &dyn SomeTable<'a>).fmt(f)
243    }
244}
245
246/// Individual anchor point.
247#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
248#[repr(C)]
249#[repr(packed)]
250pub struct AnchorPoint {
251    pub x: BigEndian<i16>,
252    pub y: BigEndian<i16>,
253}
254
255impl AnchorPoint {
256    pub fn x(&self) -> i16 {
257        self.x.get()
258    }
259
260    pub fn y(&self) -> i16 {
261        self.y.get()
262    }
263}
264
265impl FixedSize for AnchorPoint {
266    const RAW_BYTE_LEN: usize = i16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN;
267}
268
269#[cfg(feature = "experimental_traverse")]
270impl<'a> SomeRecord<'a> for AnchorPoint {
271    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
272        RecordResolver {
273            name: "AnchorPoint",
274            get_field: Box::new(move |idx, _data| match idx {
275                0usize => Some(Field::new("x", self.x())),
276                1usize => Some(Field::new("y", self.y())),
277                _ => None,
278            }),
279            data,
280        }
281    }
282}