Skip to main content

read_fonts/generated/
generated_maxp.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 Maxp<'a> {
9    fn min_byte_range(&self) -> Range<usize> {
10        0..self.num_glyphs_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 Maxp<'_> {
19    /// `maxp`
20    const TAG: Tag = Tag::new(b"maxp");
21}
22
23impl ReadArgs for Maxp<'_> {
24    type Args = ();
25}
26
27impl<'a> FontRead<'a> for Maxp<'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/// [`maxp`](https://docs.microsoft.com/en-us/typography/opentype/spec/maxp)
38#[derive(Clone)]
39pub struct Maxp<'a> {
40    data: FontData<'a>,
41}
42
43#[allow(clippy::needless_lifetimes)]
44impl<'a> Maxp<'a> {
45    pub const MIN_SIZE: usize = (Version16Dot16::RAW_BYTE_LEN + u16::RAW_BYTE_LEN);
46    basic_table_impls!(impl_the_methods);
47
48    /// The version: 0x00005000 for version 0.5, 0x00010000 for version 1.0.
49    pub fn version(&self) -> Version16Dot16 {
50        let range = self.version_byte_range();
51        self.data.read_at(range.start).ok().unwrap()
52    }
53
54    /// The number of glyphs in the font.
55    pub fn num_glyphs(&self) -> u16 {
56        let range = self.num_glyphs_byte_range();
57        self.data.read_at(range.start).ok().unwrap()
58    }
59
60    /// Maximum points in a non-composite glyph.
61    pub fn max_points(&self) -> Option<u16> {
62        let range = self.max_points_byte_range();
63        (!range.is_empty())
64            .then(|| self.data.read_at(range.start).ok())
65            .flatten()
66    }
67
68    /// Maximum contours in a non-composite glyph.
69    pub fn max_contours(&self) -> Option<u16> {
70        let range = self.max_contours_byte_range();
71        (!range.is_empty())
72            .then(|| self.data.read_at(range.start).ok())
73            .flatten()
74    }
75
76    /// Maximum points in a composite glyph.
77    pub fn max_composite_points(&self) -> Option<u16> {
78        let range = self.max_composite_points_byte_range();
79        (!range.is_empty())
80            .then(|| self.data.read_at(range.start).ok())
81            .flatten()
82    }
83
84    /// Maximum contours in a composite glyph.
85    pub fn max_composite_contours(&self) -> Option<u16> {
86        let range = self.max_composite_contours_byte_range();
87        (!range.is_empty())
88            .then(|| self.data.read_at(range.start).ok())
89            .flatten()
90    }
91
92    /// 1 if instructions do not use the twilight zone (Z0), or 2 if
93    /// instructions do use Z0; should be set to 2 in most cases.
94    pub fn max_zones(&self) -> Option<u16> {
95        let range = self.max_zones_byte_range();
96        (!range.is_empty())
97            .then(|| self.data.read_at(range.start).ok())
98            .flatten()
99    }
100
101    /// Maximum points used in Z0.
102    pub fn max_twilight_points(&self) -> Option<u16> {
103        let range = self.max_twilight_points_byte_range();
104        (!range.is_empty())
105            .then(|| self.data.read_at(range.start).ok())
106            .flatten()
107    }
108
109    /// Number of Storage Area locations.
110    pub fn max_storage(&self) -> Option<u16> {
111        let range = self.max_storage_byte_range();
112        (!range.is_empty())
113            .then(|| self.data.read_at(range.start).ok())
114            .flatten()
115    }
116
117    /// Number of FDEFs, equal to the highest function number + 1.
118    pub fn max_function_defs(&self) -> Option<u16> {
119        let range = self.max_function_defs_byte_range();
120        (!range.is_empty())
121            .then(|| self.data.read_at(range.start).ok())
122            .flatten()
123    }
124
125    /// Number of IDEFs.
126    pub fn max_instruction_defs(&self) -> Option<u16> {
127        let range = self.max_instruction_defs_byte_range();
128        (!range.is_empty())
129            .then(|| self.data.read_at(range.start).ok())
130            .flatten()
131    }
132
133    /// Maximum stack depth across Font Program ('fpgm' table), CVT
134    /// Program ('prep' table) and all glyph instructions (in the
135    /// 'glyf' table).
136    pub fn max_stack_elements(&self) -> Option<u16> {
137        let range = self.max_stack_elements_byte_range();
138        (!range.is_empty())
139            .then(|| self.data.read_at(range.start).ok())
140            .flatten()
141    }
142
143    /// Maximum byte count for glyph instructions.
144    pub fn max_size_of_instructions(&self) -> Option<u16> {
145        let range = self.max_size_of_instructions_byte_range();
146        (!range.is_empty())
147            .then(|| self.data.read_at(range.start).ok())
148            .flatten()
149    }
150
151    /// Maximum number of components referenced at “top level” for
152    /// any composite glyph.
153    pub fn max_component_elements(&self) -> Option<u16> {
154        let range = self.max_component_elements_byte_range();
155        (!range.is_empty())
156            .then(|| self.data.read_at(range.start).ok())
157            .flatten()
158    }
159
160    /// Maximum levels of recursion; 1 for simple components.
161    pub fn max_component_depth(&self) -> Option<u16> {
162        let range = self.max_component_depth_byte_range();
163        (!range.is_empty())
164            .then(|| self.data.read_at(range.start).ok())
165            .flatten()
166    }
167
168    pub fn version_byte_range(&self) -> Range<usize> {
169        let start = 0;
170        let end = start + Version16Dot16::RAW_BYTE_LEN;
171        start..end
172    }
173
174    pub fn num_glyphs_byte_range(&self) -> Range<usize> {
175        let start = self.version_byte_range().end;
176        let end = start + u16::RAW_BYTE_LEN;
177        start..end
178    }
179
180    pub fn max_points_byte_range(&self) -> Range<usize> {
181        let start = self.num_glyphs_byte_range().end;
182        let end = if self.version().compatible((1u16, 0u16)) {
183            start + u16::RAW_BYTE_LEN
184        } else {
185            start
186        };
187        start..end
188    }
189
190    pub fn max_contours_byte_range(&self) -> Range<usize> {
191        let start = self.max_points_byte_range().end;
192        let end = if self.version().compatible((1u16, 0u16)) {
193            start + u16::RAW_BYTE_LEN
194        } else {
195            start
196        };
197        start..end
198    }
199
200    pub fn max_composite_points_byte_range(&self) -> Range<usize> {
201        let start = self.max_contours_byte_range().end;
202        let end = if self.version().compatible((1u16, 0u16)) {
203            start + u16::RAW_BYTE_LEN
204        } else {
205            start
206        };
207        start..end
208    }
209
210    pub fn max_composite_contours_byte_range(&self) -> Range<usize> {
211        let start = self.max_composite_points_byte_range().end;
212        let end = if self.version().compatible((1u16, 0u16)) {
213            start + u16::RAW_BYTE_LEN
214        } else {
215            start
216        };
217        start..end
218    }
219
220    pub fn max_zones_byte_range(&self) -> Range<usize> {
221        let start = self.max_composite_contours_byte_range().end;
222        let end = if self.version().compatible((1u16, 0u16)) {
223            start + u16::RAW_BYTE_LEN
224        } else {
225            start
226        };
227        start..end
228    }
229
230    pub fn max_twilight_points_byte_range(&self) -> Range<usize> {
231        let start = self.max_zones_byte_range().end;
232        let end = if self.version().compatible((1u16, 0u16)) {
233            start + u16::RAW_BYTE_LEN
234        } else {
235            start
236        };
237        start..end
238    }
239
240    pub fn max_storage_byte_range(&self) -> Range<usize> {
241        let start = self.max_twilight_points_byte_range().end;
242        let end = if self.version().compatible((1u16, 0u16)) {
243            start + u16::RAW_BYTE_LEN
244        } else {
245            start
246        };
247        start..end
248    }
249
250    pub fn max_function_defs_byte_range(&self) -> Range<usize> {
251        let start = self.max_storage_byte_range().end;
252        let end = if self.version().compatible((1u16, 0u16)) {
253            start + u16::RAW_BYTE_LEN
254        } else {
255            start
256        };
257        start..end
258    }
259
260    pub fn max_instruction_defs_byte_range(&self) -> Range<usize> {
261        let start = self.max_function_defs_byte_range().end;
262        let end = if self.version().compatible((1u16, 0u16)) {
263            start + u16::RAW_BYTE_LEN
264        } else {
265            start
266        };
267        start..end
268    }
269
270    pub fn max_stack_elements_byte_range(&self) -> Range<usize> {
271        let start = self.max_instruction_defs_byte_range().end;
272        let end = if self.version().compatible((1u16, 0u16)) {
273            start + u16::RAW_BYTE_LEN
274        } else {
275            start
276        };
277        start..end
278    }
279
280    pub fn max_size_of_instructions_byte_range(&self) -> Range<usize> {
281        let start = self.max_stack_elements_byte_range().end;
282        let end = if self.version().compatible((1u16, 0u16)) {
283            start + u16::RAW_BYTE_LEN
284        } else {
285            start
286        };
287        start..end
288    }
289
290    pub fn max_component_elements_byte_range(&self) -> Range<usize> {
291        let start = self.max_size_of_instructions_byte_range().end;
292        let end = if self.version().compatible((1u16, 0u16)) {
293            start + u16::RAW_BYTE_LEN
294        } else {
295            start
296        };
297        start..end
298    }
299
300    pub fn max_component_depth_byte_range(&self) -> Range<usize> {
301        let start = self.max_component_elements_byte_range().end;
302        let end = if self.version().compatible((1u16, 0u16)) {
303            start + u16::RAW_BYTE_LEN
304        } else {
305            start
306        };
307        start..end
308    }
309}
310
311const _: () = assert!(FontData::default_data_long_enough(Maxp::MIN_SIZE));
312
313impl Default for Maxp<'_> {
314    fn default() -> Self {
315        Self {
316            data: FontData::default_table_data(),
317        }
318    }
319}
320
321#[cfg(feature = "experimental_traverse")]
322impl<'a> SomeTable<'a> for Maxp<'a> {
323    fn type_name(&self) -> &str {
324        "Maxp"
325    }
326    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
327        match idx {
328            0usize => Some(Field::new("version", self.version())),
329            1usize => Some(Field::new("num_glyphs", self.num_glyphs())),
330            2usize if self.version().compatible((1u16, 0u16)) => {
331                Some(Field::new("max_points", self.max_points().unwrap()))
332            }
333            3usize if self.version().compatible((1u16, 0u16)) => {
334                Some(Field::new("max_contours", self.max_contours().unwrap()))
335            }
336            4usize if self.version().compatible((1u16, 0u16)) => Some(Field::new(
337                "max_composite_points",
338                self.max_composite_points().unwrap(),
339            )),
340            5usize if self.version().compatible((1u16, 0u16)) => Some(Field::new(
341                "max_composite_contours",
342                self.max_composite_contours().unwrap(),
343            )),
344            6usize if self.version().compatible((1u16, 0u16)) => {
345                Some(Field::new("max_zones", self.max_zones().unwrap()))
346            }
347            7usize if self.version().compatible((1u16, 0u16)) => Some(Field::new(
348                "max_twilight_points",
349                self.max_twilight_points().unwrap(),
350            )),
351            8usize if self.version().compatible((1u16, 0u16)) => {
352                Some(Field::new("max_storage", self.max_storage().unwrap()))
353            }
354            9usize if self.version().compatible((1u16, 0u16)) => Some(Field::new(
355                "max_function_defs",
356                self.max_function_defs().unwrap(),
357            )),
358            10usize if self.version().compatible((1u16, 0u16)) => Some(Field::new(
359                "max_instruction_defs",
360                self.max_instruction_defs().unwrap(),
361            )),
362            11usize if self.version().compatible((1u16, 0u16)) => Some(Field::new(
363                "max_stack_elements",
364                self.max_stack_elements().unwrap(),
365            )),
366            12usize if self.version().compatible((1u16, 0u16)) => Some(Field::new(
367                "max_size_of_instructions",
368                self.max_size_of_instructions().unwrap(),
369            )),
370            13usize if self.version().compatible((1u16, 0u16)) => Some(Field::new(
371                "max_component_elements",
372                self.max_component_elements().unwrap(),
373            )),
374            14usize if self.version().compatible((1u16, 0u16)) => Some(Field::new(
375                "max_component_depth",
376                self.max_component_depth().unwrap(),
377            )),
378            _ => None,
379        }
380    }
381}
382
383#[cfg(feature = "experimental_traverse")]
384#[allow(clippy::needless_lifetimes)]
385impl<'a> std::fmt::Debug for Maxp<'a> {
386    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
387        (self as &dyn SomeTable<'a>).fmt(f)
388    }
389}