Skip to main content

read_fonts/generated/
generated_post.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 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    /// `post`
20    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/// [post (PostScript)](https://docs.microsoft.com/en-us/typography/opentype/spec/post#header) table
34#[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    /// 0x00010000 for version 1.0 0x00020000 for version 2.0
53    /// 0x00025000 for version 2.5 (deprecated) 0x00030000 for version
54    /// 3.0
55    pub fn version(&self) -> Version16Dot16 {
56        let range = self.version_byte_range();
57        self.data.read_at(range.start).ok().unwrap()
58    }
59
60    /// Italic angle in counter-clockwise degrees from the vertical.
61    /// Zero for upright text, negative for text that leans to the
62    /// right (forward).
63    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    /// This is the suggested distance of the top of the underline from
69    /// the baseline (negative values indicate below baseline). The
70    /// PostScript definition of this FontInfo dictionary key (the y
71    /// coordinate of the center of the stroke) is not used for
72    /// historical reasons. The value of the PostScript key may be
73    /// calculated by subtracting half the underlineThickness from the
74    /// value of this field.
75    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    /// Suggested values for the underline thickness. In general, the
81    /// underline thickness should match the thickness of the
82    /// underscore character (U+005F LOW LINE), and should also match
83    /// the strikeout thickness, which is specified in the OS/2 table.
84    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    /// Set to 0 if the font is proportionally spaced, non-zero if the
90    /// font is not proportionally spaced (i.e. monospaced).
91    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    /// Minimum memory usage when an OpenType font is downloaded.
97    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    /// Maximum memory usage when an OpenType font is downloaded.
103    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    /// Minimum memory usage when an OpenType font is downloaded as a
109    /// Type 1 font.
110    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    /// Maximum memory usage when an OpenType font is downloaded as a
116    /// Type 1 font.
117    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    /// Number of glyphs (this should be the same as numGlyphs in
123    /// 'maxp' table).
124    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    /// Array of indices into the string data. See below for details.
132    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    /// Storage for the string data.
140    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        start..start + Version16Dot16::RAW_BYTE_LEN
154    }
155
156    pub fn italic_angle_byte_range(&self) -> Range<usize> {
157        let start = self.version_byte_range().end;
158        start..start + Fixed::RAW_BYTE_LEN
159    }
160
161    pub fn underline_position_byte_range(&self) -> Range<usize> {
162        let start = self.italic_angle_byte_range().end;
163        start..start + FWord::RAW_BYTE_LEN
164    }
165
166    pub fn underline_thickness_byte_range(&self) -> Range<usize> {
167        let start = self.underline_position_byte_range().end;
168        start..start + FWord::RAW_BYTE_LEN
169    }
170
171    pub fn is_fixed_pitch_byte_range(&self) -> Range<usize> {
172        let start = self.underline_thickness_byte_range().end;
173        start..start + u32::RAW_BYTE_LEN
174    }
175
176    pub fn min_mem_type42_byte_range(&self) -> Range<usize> {
177        let start = self.is_fixed_pitch_byte_range().end;
178        start..start + u32::RAW_BYTE_LEN
179    }
180
181    pub fn max_mem_type42_byte_range(&self) -> Range<usize> {
182        let start = self.min_mem_type42_byte_range().end;
183        start..start + u32::RAW_BYTE_LEN
184    }
185
186    pub fn min_mem_type1_byte_range(&self) -> Range<usize> {
187        let start = self.max_mem_type42_byte_range().end;
188        start..start + u32::RAW_BYTE_LEN
189    }
190
191    pub fn max_mem_type1_byte_range(&self) -> Range<usize> {
192        let start = self.min_mem_type1_byte_range().end;
193        start..start + u32::RAW_BYTE_LEN
194    }
195
196    pub fn num_glyphs_byte_range(&self) -> Range<usize> {
197        let start = self.max_mem_type1_byte_range().end;
198        start
199            ..(self.version().compatible((2u16, 0u16)))
200                .then(|| start + u16::RAW_BYTE_LEN)
201                .unwrap_or(start)
202    }
203
204    pub fn glyph_name_index_byte_range(&self) -> Range<usize> {
205        let num_glyphs = self.num_glyphs().unwrap_or_default();
206        let start = self.num_glyphs_byte_range().end;
207        start
208            ..(self.version().compatible((2u16, 0u16)))
209                .then(|| start + (num_glyphs as usize).saturating_mul(u16::RAW_BYTE_LEN))
210                .unwrap_or(start)
211    }
212
213    pub fn string_data_byte_range(&self) -> Range<usize> {
214        let start = self.glyph_name_index_byte_range().end;
215        start
216            ..(self.version().compatible((2u16, 0u16)))
217                .then(|| start + self.data.len().saturating_sub(start))
218                .unwrap_or(start)
219    }
220}
221
222#[cfg(feature = "experimental_traverse")]
223impl<'a> SomeTable<'a> for Post<'a> {
224    fn type_name(&self) -> &str {
225        "Post"
226    }
227    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
228        match idx {
229            0usize => Some(Field::new("version", self.version())),
230            1usize => Some(Field::new("italic_angle", self.italic_angle())),
231            2usize => Some(Field::new("underline_position", self.underline_position())),
232            3usize => Some(Field::new(
233                "underline_thickness",
234                self.underline_thickness(),
235            )),
236            4usize => Some(Field::new("is_fixed_pitch", self.is_fixed_pitch())),
237            5usize => Some(Field::new("min_mem_type42", self.min_mem_type42())),
238            6usize => Some(Field::new("max_mem_type42", self.max_mem_type42())),
239            7usize => Some(Field::new("min_mem_type1", self.min_mem_type1())),
240            8usize => Some(Field::new("max_mem_type1", self.max_mem_type1())),
241            9usize if self.version().compatible((2u16, 0u16)) => {
242                Some(Field::new("num_glyphs", self.num_glyphs().unwrap()))
243            }
244            10usize if self.version().compatible((2u16, 0u16)) => Some(Field::new(
245                "glyph_name_index",
246                self.glyph_name_index().unwrap(),
247            )),
248            11usize if self.version().compatible((2u16, 0u16)) => {
249                Some(Field::new("string_data", self.traverse_string_data()))
250            }
251            _ => None,
252        }
253    }
254}
255
256#[cfg(feature = "experimental_traverse")]
257#[allow(clippy::needless_lifetimes)]
258impl<'a> std::fmt::Debug for Post<'a> {
259    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
260        (self as &dyn SomeTable<'a>).fmt(f)
261    }
262}