Coverage Report

Created: 2026-10-24 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/read-fonts-0.46.0/generated/generated_post.rs
Line
Count
Source
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)]
6
use crate::codegen_prelude::*;
7
8
impl<'a> MinByteRange<'a> for Post<'a> {
9
0
    fn min_byte_range(&self) -> Range<usize> {
10
0
        0..self.max_mem_type1_byte_range().end
11
0
    }
12
0
    fn min_table_bytes(&self) -> &'a [u8] {
13
0
        let range = self.min_byte_range();
14
0
        self.offset_data().as_bytes().get(range).unwrap_or_default()
15
0
    }
16
}
17
18
impl TopLevelTable for Post<'_> {
19
    /// `post`
20
    const TAG: Tag = Tag::new(b"post");
21
}
22
23
impl ReadArgs for Post<'_> {
24
    type Args = ();
25
}
26
27
impl<'a> FontRead<'a> for Post<'a> {
28
0
    fn read_with_args(data: FontData<'a>, _: ()) -> Result<Self, ReadError> {
29
        #[allow(clippy::absurd_extreme_comparisons)]
30
0
        if data.len() < Self::MIN_SIZE {
31
0
            return Err(ReadError::OutOfBounds);
32
0
        }
33
0
        let Some(data) = TableDataRef::new(data.as_bytes()) else {
34
0
            return Err(ReadError::OutOfBounds);
35
        };
36
0
        Ok(Self { data })
37
0
    }
38
}
39
40
/// The fields at the start of the table, which are read directly.
41
#[derive(Clone, Copy, bytemuck :: AnyBitPattern)]
42
#[repr(C, packed)]
43
#[doc(hidden)]
44
pub struct PostFixedHeader {
45
    pub version: BigEndian<Version16Dot16>,
46
    pub italic_angle: BigEndian<Fixed>,
47
    pub underline_position: BigEndian<FWord>,
48
    pub underline_thickness: BigEndian<FWord>,
49
    pub is_fixed_pitch: BigEndian<u32>,
50
    pub min_mem_type42: BigEndian<u32>,
51
    pub max_mem_type42: BigEndian<u32>,
52
    pub min_mem_type1: BigEndian<u32>,
53
    pub max_mem_type1: BigEndian<u32>,
54
}
55
56
#[allow(clippy::absurd_extreme_comparisons)]
57
const _: () = assert!(std::mem::size_of::<PostFixedHeader>() <= Post::MIN_SIZE);
58
59
/// [post (PostScript)](https://docs.microsoft.com/en-us/typography/opentype/spec/post#header) table
60
#[derive(Clone)]
61
pub struct Post<'a> {
62
    data: TableDataRef<'a, PostFixedHeader>,
63
}
64
65
#[allow(clippy::needless_lifetimes)]
66
impl<'a> Post<'a> {
67
    pub const MIN_SIZE: usize = (Version16Dot16::RAW_BYTE_LEN
68
        + Fixed::RAW_BYTE_LEN
69
        + FWord::RAW_BYTE_LEN
70
        + FWord::RAW_BYTE_LEN
71
        + u32::RAW_BYTE_LEN
72
        + u32::RAW_BYTE_LEN
73
        + u32::RAW_BYTE_LEN
74
        + u32::RAW_BYTE_LEN
75
        + u32::RAW_BYTE_LEN);
76
    basic_table_impls!(impl_the_methods);
77
78
    /// 0x00010000 for version 1.0 0x00020000 for version 2.0
79
    /// 0x00025000 for version 2.5 (deprecated) 0x00030000 for version
80
    /// 3.0
81
0
    pub fn version(&self) -> Version16Dot16 {
82
0
        self.data.header().version.get()
83
0
    }
84
85
    /// Italic angle in counter-clockwise degrees from the vertical.
86
    /// Zero for upright text, negative for text that leans to the
87
    /// right (forward).
88
0
    pub fn italic_angle(&self) -> Fixed {
89
0
        self.data.header().italic_angle.get()
90
0
    }
91
92
    /// This is the suggested distance of the top of the underline from
93
    /// the baseline (negative values indicate below baseline). The
94
    /// PostScript definition of this FontInfo dictionary key (the y
95
    /// coordinate of the center of the stroke) is not used for
96
    /// historical reasons. The value of the PostScript key may be
97
    /// calculated by subtracting half the underlineThickness from the
98
    /// value of this field.
99
0
    pub fn underline_position(&self) -> FWord {
100
0
        self.data.header().underline_position.get()
101
0
    }
102
103
    /// Suggested values for the underline thickness. In general, the
104
    /// underline thickness should match the thickness of the
105
    /// underscore character (U+005F LOW LINE), and should also match
106
    /// the strikeout thickness, which is specified in the OS/2 table.
107
0
    pub fn underline_thickness(&self) -> FWord {
108
0
        self.data.header().underline_thickness.get()
109
0
    }
110
111
    /// Set to 0 if the font is proportionally spaced, non-zero if the
112
    /// font is not proportionally spaced (i.e. monospaced).
113
0
    pub fn is_fixed_pitch(&self) -> u32 {
114
0
        self.data.header().is_fixed_pitch.get()
115
0
    }
116
117
    /// Minimum memory usage when an OpenType font is downloaded.
118
0
    pub fn min_mem_type42(&self) -> u32 {
119
0
        self.data.header().min_mem_type42.get()
120
0
    }
121
122
    /// Maximum memory usage when an OpenType font is downloaded.
123
0
    pub fn max_mem_type42(&self) -> u32 {
124
0
        self.data.header().max_mem_type42.get()
125
0
    }
126
127
    /// Minimum memory usage when an OpenType font is downloaded as a
128
    /// Type 1 font.
129
0
    pub fn min_mem_type1(&self) -> u32 {
130
0
        self.data.header().min_mem_type1.get()
131
0
    }
132
133
    /// Maximum memory usage when an OpenType font is downloaded as a
134
    /// Type 1 font.
135
0
    pub fn max_mem_type1(&self) -> u32 {
136
0
        self.data.header().max_mem_type1.get()
137
0
    }
138
139
    /// Number of glyphs (this should be the same as numGlyphs in
140
    /// 'maxp' table).
141
0
    pub fn num_glyphs(&self) -> Option<u16> {
142
0
        let range = self.num_glyphs_byte_range();
143
0
        (!range.is_empty())
144
0
            .then(|| self.offset_data().read_at(range.start).ok())
145
0
            .flatten()
146
0
    }
147
148
    /// Array of indices into the string data. See below for details.
149
0
    pub fn glyph_name_index(&self) -> Option<&'a [BigEndian<u16>]> {
150
0
        let range = self.glyph_name_index_byte_range();
151
0
        (!range.is_empty())
152
0
            .then(|| self.offset_data().read_array(range).ok())
153
0
            .flatten()
154
0
    }
155
156
    /// Storage for the string data.
157
0
    pub fn string_data(&self) -> Option<VarLenArray<'a, PString<'a>>> {
158
0
        let range = self.string_data_byte_range();
159
0
        (!range.is_empty())
160
0
            .then(|| {
161
0
                self.offset_data()
162
0
                    .split_off(range.start)
163
0
                    .and_then(|d| VarLenArray::read(d).ok())
164
0
            })
165
0
            .flatten()
166
0
    }
167
168
0
    pub fn version_byte_range(&self) -> Range<usize> {
169
0
        let start = 0;
170
0
        let end = start + Version16Dot16::RAW_BYTE_LEN;
171
0
        start..end
172
0
    }
173
174
0
    pub fn italic_angle_byte_range(&self) -> Range<usize> {
175
0
        let start = self.version_byte_range().end;
176
0
        let end = start + Fixed::RAW_BYTE_LEN;
177
0
        start..end
178
0
    }
179
180
0
    pub fn underline_position_byte_range(&self) -> Range<usize> {
181
0
        let start = self.italic_angle_byte_range().end;
182
0
        let end = start + FWord::RAW_BYTE_LEN;
183
0
        start..end
184
0
    }
185
186
0
    pub fn underline_thickness_byte_range(&self) -> Range<usize> {
187
0
        let start = self.underline_position_byte_range().end;
188
0
        let end = start + FWord::RAW_BYTE_LEN;
189
0
        start..end
190
0
    }
191
192
0
    pub fn is_fixed_pitch_byte_range(&self) -> Range<usize> {
193
0
        let start = self.underline_thickness_byte_range().end;
194
0
        let end = start + u32::RAW_BYTE_LEN;
195
0
        start..end
196
0
    }
197
198
0
    pub fn min_mem_type42_byte_range(&self) -> Range<usize> {
199
0
        let start = self.is_fixed_pitch_byte_range().end;
200
0
        let end = start + u32::RAW_BYTE_LEN;
201
0
        start..end
202
0
    }
203
204
0
    pub fn max_mem_type42_byte_range(&self) -> Range<usize> {
205
0
        let start = self.min_mem_type42_byte_range().end;
206
0
        let end = start + u32::RAW_BYTE_LEN;
207
0
        start..end
208
0
    }
209
210
0
    pub fn min_mem_type1_byte_range(&self) -> Range<usize> {
211
0
        let start = self.max_mem_type42_byte_range().end;
212
0
        let end = start + u32::RAW_BYTE_LEN;
213
0
        start..end
214
0
    }
215
216
0
    pub fn max_mem_type1_byte_range(&self) -> Range<usize> {
217
0
        let start = self.min_mem_type1_byte_range().end;
218
0
        let end = start + u32::RAW_BYTE_LEN;
219
0
        start..end
220
0
    }
221
222
0
    pub fn num_glyphs_byte_range(&self) -> Range<usize> {
223
0
        let start = self.max_mem_type1_byte_range().end;
224
0
        let end = if self.version().compatible((2u16, 0u16)) {
225
0
            start + u16::RAW_BYTE_LEN
226
        } else {
227
0
            start
228
        };
229
0
        start..end
230
0
    }
231
232
0
    pub fn glyph_name_index_byte_range(&self) -> Range<usize> {
233
0
        let num_glyphs = self.num_glyphs().unwrap_or_default();
234
0
        let start = self.num_glyphs_byte_range().end;
235
0
        let end = if self.version().compatible((2u16, 0u16)) {
236
0
            start + (transforms::to_usize(num_glyphs)).saturating_mul(u16::RAW_BYTE_LEN)
237
        } else {
238
0
            start
239
        };
240
0
        start..end
241
0
    }
242
243
0
    pub fn string_data_byte_range(&self) -> Range<usize> {
244
0
        let start = self.glyph_name_index_byte_range().end;
245
0
        let end = if self.version().compatible((2u16, 0u16)) {
246
0
            start + self.offset_data().len().saturating_sub(start)
247
        } else {
248
0
            start
249
        };
250
0
        start..end
251
0
    }
252
}
253
254
const _: () = assert!(FontData::default_data_long_enough(Post::MIN_SIZE));
255
256
impl Default for Post<'_> {
257
0
    fn default() -> Self {
258
        Self {
259
0
            data: TableDataRef::new(FontData::default_table_data().as_bytes())
260
0
                .unwrap_or_else(|| unreachable!("the default data covers MIN_SIZE")),
261
        }
262
0
    }
263
}