Skip to main content

ttf_view/tables/
maxp.rs

1use crate::{
2    tables::{Table, TableDirectory, TableError},
3    types::{BigEndian, Tag, Version16Dot16, tags, uint16},
4};
5
6#[repr(C)]
7pub struct MaxpV0 {
8    _exhaustive_but_dont_instantiate: (),
9    // version any:
10    pub version: BigEndian<Version16Dot16>,
11}
12#[repr(C)]
13pub struct MaxpV05 {
14    v0: MaxpV0,
15    // version ≥ 0.5:
16    pub num_glyphs: uint16,
17}
18#[repr(C)]
19pub struct MaxpV1 {
20    v05: MaxpV05,
21    // version = 1.x:
22    pub max_points: uint16,
23    pub max_contours: uint16,
24    pub max_composite_points: uint16,
25    pub max_composite_contours: uint16,
26    pub max_zones: uint16,
27    pub max_twilight_points: uint16,
28    pub max_storage: uint16,
29    pub max_function_defs: uint16,
30    pub max_instruction_defs: uint16,
31    pub max_stack_elements: uint16,
32    pub max_size_of_instructions: uint16,
33    pub max_component_elements: uint16,
34    pub max_component_depth: uint16,
35}
36
37const impl std::ops::Deref for MaxpV05 {
38    type Target = MaxpV0;
39    fn deref(&self) -> &Self::Target {
40        &self.v0
41    }
42}
43const impl std::ops::Deref for MaxpV1 {
44    type Target = MaxpV05;
45    fn deref(&self) -> &Self::Target {
46        &self.v05
47    }
48}
49
50impl<'a> Table<'a> for Maxp<'a> {
51    const TAG: Tag = tags::maxp;
52    fn new_in(dir: &'a TableDirectory) -> Result<Self, TableError> {
53        let rec = dir.table_record(Self::TAG).ok_or(TableError::NotFound)?;
54        let v0 = rec.raw_as::<MaxpV0>().ok_or(TableError::InvalidLen)?;
55
56        let required_len = match v0.version.get().tuple() {
57            (0, ..=4) => size_of::<MaxpV0>() as u32,
58            (0, 5..) => size_of::<MaxpV05>() as u32,
59            (1, _) => size_of::<MaxpV1>() as u32,
60            _ => return Err(TableError::UnknownVersion),
61        };
62        if rec.length.get() < required_len {
63            return Err(TableError::InvalidLen);
64        }
65
66        Ok(Self { maxp: v0 })
67    }
68}
69
70#[derive(Copy)]
71#[derive_const(Clone)]
72pub struct Maxp<'a> {
73    maxp: &'a MaxpV0,
74}
75
76const impl<'a> std::ops::Deref for Maxp<'a> {
77    type Target = &'a MaxpV0;
78    fn deref(&self) -> &Self::Target {
79        &self.maxp
80    }
81}
82
83impl<'a> Maxp<'a> {
84    pub const fn v05(&self) -> Option<&'a MaxpV05> {
85        let (major, minor) = self.version.get().tuple();
86        if major == 0 && minor >= 5 || major == 1 {
87            Some(unsafe { std::mem::transmute::<&MaxpV0, &MaxpV05>(self.maxp) })
88        } else {
89            None
90        }
91    }
92    pub const fn v1(&self) -> Option<&'a MaxpV1> {
93        if self.version.get().major() == 1 {
94            Some(unsafe { std::mem::transmute::<&MaxpV0, &MaxpV1>(self.maxp) })
95        } else {
96            None
97        }
98    }
99
100    // version ≥ 0.5:
101    pub const fn num_glyphs(&self) -> Option<uint16> {
102        Some(self.v05()?.num_glyphs)
103    }
104
105    // version ≥ 1.0:
106    pub const fn max_points(&self) -> Option<uint16> {
107        Some(self.v1()?.max_points)
108    }
109    pub const fn max_contours(&self) -> Option<uint16> {
110        Some(self.v1()?.max_contours)
111    }
112    pub const fn max_composite_points(&self) -> Option<uint16> {
113        Some(self.v1()?.max_composite_points)
114    }
115    pub const fn max_composite_contours(&self) -> Option<uint16> {
116        Some(self.v1()?.max_composite_contours)
117    }
118    pub const fn max_zones(&self) -> Option<uint16> {
119        Some(self.v1()?.max_zones)
120    }
121    pub const fn max_twilight_points(&self) -> Option<uint16> {
122        Some(self.v1()?.max_twilight_points)
123    }
124    pub const fn max_storage(&self) -> Option<uint16> {
125        Some(self.v1()?.max_storage)
126    }
127    pub const fn max_function_defs(&self) -> Option<uint16> {
128        Some(self.v1()?.max_function_defs)
129    }
130    pub const fn max_instruction_defs(&self) -> Option<uint16> {
131        Some(self.v1()?.max_instruction_defs)
132    }
133    pub const fn max_stack_elements(&self) -> Option<uint16> {
134        Some(self.v1()?.max_stack_elements)
135    }
136    pub const fn max_size_of_instructions(&self) -> Option<uint16> {
137        Some(self.v1()?.max_size_of_instructions)
138    }
139    pub const fn max_component_elements(&self) -> Option<uint16> {
140        Some(self.v1()?.max_component_elements)
141    }
142    pub const fn max_component_depth(&self) -> Option<uint16> {
143        Some(self.v1()?.max_component_depth)
144    }
145}
146
147impl std::fmt::Debug for Maxp<'_> {
148    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
149        let mut f = f.debug_struct("MaxpTable");
150        f.field("version", &self.version);
151
152        if let Some(v05) = self.v05() {
153            f.field("num_glyphs", &v05.num_glyphs.get());
154        }
155        if let Some(v1) = self.v1() {
156            f.field("max_points", &v1.max_points.get());
157            f.field("max_contours", &v1.max_contours.get());
158            f.field("max_composite_points", &v1.max_composite_points.get());
159            f.field("max_composite_contours", &v1.max_composite_contours.get());
160            f.field("max_zones", &v1.max_zones.get());
161            f.field("max_twilight_points", &v1.max_twilight_points.get());
162            f.field("max_storage", &v1.max_storage.get());
163            f.field("max_function_defs", &v1.max_function_defs.get());
164            f.field("max_instruction_defs", &v1.max_instruction_defs.get());
165            f.field("max_stack_elements", &v1.max_stack_elements.get());
166            f.field("max_size_of_instructions", &v1.max_size_of_instructions.get());
167            f.field("max_component_elements", &v1.max_component_elements.get());
168            f.field("max_component_depth", &v1.max_component_depth.get());
169        }
170
171        f.finish()
172    }
173}
174
175// Monomorphize all fmts to the above fmt for Maxp<'a>
176impl std::fmt::Debug for MaxpV0 {
177    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
178        Maxp { maxp: self }.fmt(f)
179    }
180}
181impl std::fmt::Debug for MaxpV05 {
182    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
183        Maxp { maxp: self }.fmt(f)
184    }
185}
186impl std::fmt::Debug for MaxpV1 {
187    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
188        Maxp { maxp: self }.fmt(f)
189    }
190}