read_fonts/generated/
generated_post.rs1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8impl<'a> MinByteRange<'a> for Post<'a> {
9 fn min_byte_range(&self) -> Range<usize> {
10 0..self.max_mem_type1_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 Post<'_> {
19 const TAG: Tag = Tag::new(b"post");
21}
22
23impl<'a> FontRead<'a> for Post<'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 Post<'a> {
36 data: FontData<'a>,
37}
38
39#[allow(clippy::needless_lifetimes)]
40impl<'a> Post<'a> {
41 pub const MIN_SIZE: usize = (Version16Dot16::RAW_BYTE_LEN
42 + Fixed::RAW_BYTE_LEN
43 + FWord::RAW_BYTE_LEN
44 + FWord::RAW_BYTE_LEN
45 + u32::RAW_BYTE_LEN
46 + u32::RAW_BYTE_LEN
47 + u32::RAW_BYTE_LEN
48 + u32::RAW_BYTE_LEN
49 + u32::RAW_BYTE_LEN);
50 basic_table_impls!(impl_the_methods);
51
52 pub fn version(&self) -> Version16Dot16 {
56 let range = self.version_byte_range();
57 self.data.read_at(range.start).ok().unwrap()
58 }
59
60 pub fn italic_angle(&self) -> Fixed {
64 let range = self.italic_angle_byte_range();
65 self.data.read_at(range.start).ok().unwrap()
66 }
67
68 pub fn underline_position(&self) -> FWord {
76 let range = self.underline_position_byte_range();
77 self.data.read_at(range.start).ok().unwrap()
78 }
79
80 pub fn underline_thickness(&self) -> FWord {
85 let range = self.underline_thickness_byte_range();
86 self.data.read_at(range.start).ok().unwrap()
87 }
88
89 pub fn is_fixed_pitch(&self) -> u32 {
92 let range = self.is_fixed_pitch_byte_range();
93 self.data.read_at(range.start).ok().unwrap()
94 }
95
96 pub fn min_mem_type42(&self) -> u32 {
98 let range = self.min_mem_type42_byte_range();
99 self.data.read_at(range.start).ok().unwrap()
100 }
101
102 pub fn max_mem_type42(&self) -> u32 {
104 let range = self.max_mem_type42_byte_range();
105 self.data.read_at(range.start).ok().unwrap()
106 }
107
108 pub fn min_mem_type1(&self) -> u32 {
111 let range = self.min_mem_type1_byte_range();
112 self.data.read_at(range.start).ok().unwrap()
113 }
114
115 pub fn max_mem_type1(&self) -> u32 {
118 let range = self.max_mem_type1_byte_range();
119 self.data.read_at(range.start).ok().unwrap()
120 }
121
122 pub fn num_glyphs(&self) -> Option<u16> {
125 let range = self.num_glyphs_byte_range();
126 (!range.is_empty())
127 .then(|| self.data.read_at(range.start).ok())
128 .flatten()
129 }
130
131 pub fn glyph_name_index(&self) -> Option<&'a [BigEndian<u16>]> {
133 let range = self.glyph_name_index_byte_range();
134 (!range.is_empty())
135 .then(|| self.data.read_array(range).ok())
136 .flatten()
137 }
138
139 pub fn string_data(&self) -> Option<VarLenArray<'a, PString<'a>>> {
141 let range = self.string_data_byte_range();
142 (!range.is_empty())
143 .then(|| {
144 self.data
145 .split_off(range.start)
146 .and_then(|d| VarLenArray::read(d).ok())
147 })
148 .flatten()
149 }
150
151 pub fn version_byte_range(&self) -> Range<usize> {
152 let start = 0;
153 let end = start + Version16Dot16::RAW_BYTE_LEN;
154 start..end
155 }
156
157 pub fn italic_angle_byte_range(&self) -> Range<usize> {
158 let start = self.version_byte_range().end;
159 let end = start + Fixed::RAW_BYTE_LEN;
160 start..end
161 }
162
163 pub fn underline_position_byte_range(&self) -> Range<usize> {
164 let start = self.italic_angle_byte_range().end;
165 let end = start + FWord::RAW_BYTE_LEN;
166 start..end
167 }
168
169 pub fn underline_thickness_byte_range(&self) -> Range<usize> {
170 let start = self.underline_position_byte_range().end;
171 let end = start + FWord::RAW_BYTE_LEN;
172 start..end
173 }
174
175 pub fn is_fixed_pitch_byte_range(&self) -> Range<usize> {
176 let start = self.underline_thickness_byte_range().end;
177 let end = start + u32::RAW_BYTE_LEN;
178 start..end
179 }
180
181 pub fn min_mem_type42_byte_range(&self) -> Range<usize> {
182 let start = self.is_fixed_pitch_byte_range().end;
183 let end = start + u32::RAW_BYTE_LEN;
184 start..end
185 }
186
187 pub fn max_mem_type42_byte_range(&self) -> Range<usize> {
188 let start = self.min_mem_type42_byte_range().end;
189 let end = start + u32::RAW_BYTE_LEN;
190 start..end
191 }
192
193 pub fn min_mem_type1_byte_range(&self) -> Range<usize> {
194 let start = self.max_mem_type42_byte_range().end;
195 let end = start + u32::RAW_BYTE_LEN;
196 start..end
197 }
198
199 pub fn max_mem_type1_byte_range(&self) -> Range<usize> {
200 let start = self.min_mem_type1_byte_range().end;
201 let end = start + u32::RAW_BYTE_LEN;
202 start..end
203 }
204
205 pub fn num_glyphs_byte_range(&self) -> Range<usize> {
206 let start = self.max_mem_type1_byte_range().end;
207 let end = if self.version().compatible((2u16, 0u16)) {
208 start + u16::RAW_BYTE_LEN
209 } else {
210 start
211 };
212 start..end
213 }
214
215 pub fn glyph_name_index_byte_range(&self) -> Range<usize> {
216 let num_glyphs = self.num_glyphs().unwrap_or_default();
217 let start = self.num_glyphs_byte_range().end;
218 let end = if self.version().compatible((2u16, 0u16)) {
219 start + (transforms::to_usize(num_glyphs)).saturating_mul(u16::RAW_BYTE_LEN)
220 } else {
221 start
222 };
223 start..end
224 }
225
226 pub fn string_data_byte_range(&self) -> Range<usize> {
227 let start = self.glyph_name_index_byte_range().end;
228 let end = if self.version().compatible((2u16, 0u16)) {
229 start + self.data.len().saturating_sub(start)
230 } else {
231 start
232 };
233 start..end
234 }
235}
236
237const _: () = assert!(FontData::default_data_long_enough(Post::MIN_SIZE));
238
239impl Default for Post<'_> {
240 fn default() -> Self {
241 Self {
242 data: FontData::default_table_data(),
243 }
244 }
245}
246
247#[cfg(feature = "experimental_traverse")]
248impl<'a> SomeTable<'a> for Post<'a> {
249 fn type_name(&self) -> &str {
250 "Post"
251 }
252 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
253 match idx {
254 0usize => Some(Field::new("version", self.version())),
255 1usize => Some(Field::new("italic_angle", self.italic_angle())),
256 2usize => Some(Field::new("underline_position", self.underline_position())),
257 3usize => Some(Field::new(
258 "underline_thickness",
259 self.underline_thickness(),
260 )),
261 4usize => Some(Field::new("is_fixed_pitch", self.is_fixed_pitch())),
262 5usize => Some(Field::new("min_mem_type42", self.min_mem_type42())),
263 6usize => Some(Field::new("max_mem_type42", self.max_mem_type42())),
264 7usize => Some(Field::new("min_mem_type1", self.min_mem_type1())),
265 8usize => Some(Field::new("max_mem_type1", self.max_mem_type1())),
266 9usize if self.version().compatible((2u16, 0u16)) => {
267 Some(Field::new("num_glyphs", self.num_glyphs().unwrap()))
268 }
269 10usize if self.version().compatible((2u16, 0u16)) => Some(Field::new(
270 "glyph_name_index",
271 self.glyph_name_index().unwrap(),
272 )),
273 11usize if self.version().compatible((2u16, 0u16)) => {
274 Some(Field::new("string_data", self.traverse_string_data()))
275 }
276 _ => None,
277 }
278 }
279}
280
281#[cfg(feature = "experimental_traverse")]
282#[allow(clippy::needless_lifetimes)]
283impl<'a> std::fmt::Debug for Post<'a> {
284 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
285 (self as &dyn SomeTable<'a>).fmt(f)
286 }
287}