write_fonts/generated/
generated_os2.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
8pub use read_fonts::tables::os2::SelectionFlags;
9
10impl FontWrite for SelectionFlags {
11    fn write_into(&self, writer: &mut TableWriter) {
12        writer.write_slice(&self.bits().to_be_bytes())
13    }
14}
15
16/// [`OS/2`](https://docs.microsoft.com/en-us/typography/opentype/spec/os2)
17#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19pub struct Os2 {
20    /// [Average weighted escapement](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#xavgcharwidth).
21    ///
22    /// The Average Character Width parameter specifies the arithmetic average
23    /// of the escapement (width) of all non-zero width glyphs in the font.
24    pub x_avg_char_width: i16,
25    /// [Weight class](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#usweightclass).
26    ///
27    /// Indicates the visual weight (degree of blackness or thickness of
28    /// strokes) of the characters in the font. Values from 1 to 1000 are valid.
29    pub us_weight_class: u16,
30    /// [Width class](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#uswidthclass).
31    ///
32    /// Indicates a relative change from the normal aspect ratio (width to height
33    /// ratio) as specified by a font designer for the glyphs in a font.
34    pub us_width_class: u16,
35    /// [Type flags](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#fstype).
36    ///
37    /// Indicates font embedding licensing rights for the font.
38    pub fs_type: u16,
39    /// The recommended horizontal size in font design units for subscripts for
40    /// this font.
41    pub y_subscript_x_size: i16,
42    /// The recommended vertical size in font design units for subscripts for
43    /// this font.
44    pub y_subscript_y_size: i16,
45    /// The recommended horizontal offset in font design units for subscripts
46    /// for this font.
47    pub y_subscript_x_offset: i16,
48    /// The recommended vertical offset in font design units for subscripts
49    /// for this font.
50    pub y_subscript_y_offset: i16,
51    /// The recommended horizontal size in font design units for superscripts
52    /// for this font.
53    pub y_superscript_x_size: i16,
54    /// The recommended vertical size in font design units for superscripts
55    /// for this font.
56    pub y_superscript_y_size: i16,
57    /// The recommended horizontal offset in font design units for superscripts
58    /// for this font.
59    pub y_superscript_x_offset: i16,
60    /// The recommended vertical offset in font design units for superscripts
61    /// for this font.
62    pub y_superscript_y_offset: i16,
63    /// Thickness of the strikeout stroke in font design units.
64    pub y_strikeout_size: i16,
65    /// The position of the top of the strikeout stroke relative to the
66    /// baseline in font design units.
67    pub y_strikeout_position: i16,
68    /// [Font-family class and subclass](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#sfamilyclass).
69    /// This parameter is a classification of font-family design.
70    pub s_family_class: i16,
71    /// [PANOSE classification number](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#panose).
72    ///
73    /// Additional specifications are required for PANOSE to classify non-Latin
74    /// character sets.
75    pub panose_10: [u8; 10],
76    /// [Unicode Character Range](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#ulunicoderange1-bits-031ulunicoderange2-bits-3263ulunicoderange3-bits-6495ulunicoderange4-bits-96127).
77    ///
78    /// Unicode Character Range (bits 0-31).
79    pub ul_unicode_range_1: u32,
80    /// Unicode Character Range (bits 32-63).
81    pub ul_unicode_range_2: u32,
82    /// Unicode Character Range (bits 64-95).
83    pub ul_unicode_range_3: u32,
84    /// Unicode Character Range (bits 96-127).
85    pub ul_unicode_range_4: u32,
86    /// [Font Vendor Identification](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#achvendid).
87    ///
88    /// The four-character identifier for the vendor of the given type face.
89    pub ach_vend_id: Tag,
90    /// [Font selection flags](https://learn.microsoft.com/en-us/typography/opentype/spec/os2#fsselection).
91    ///
92    /// Contains information concerning the nature of the font patterns.
93    pub fs_selection: SelectionFlags,
94    /// The minimum Unicode index (character code) in this font.
95    pub us_first_char_index: u16,
96    /// The maximum Unicode index (character code) in this font.
97    pub us_last_char_index: u16,
98    /// The typographic ascender for this font.
99    pub s_typo_ascender: i16,
100    /// The typographic descender for this font.
101    pub s_typo_descender: i16,
102    /// The typographic line gap for this font.
103    pub s_typo_line_gap: i16,
104    /// The “Windows ascender” metric.
105    ///
106    /// This should be used to specify the height above the baseline for a
107    /// clipping region.
108    pub us_win_ascent: u16,
109    /// The “Windows descender” metric.
110    ///
111    /// This should be used to specify the vertical extent below the baseline
112    /// for a clipping region.
113    pub us_win_descent: u16,
114    /// Code page character range bits 0-31.
115    pub ul_code_page_range_1: Option<u32>,
116    /// Code page character range bits 32-63.
117    pub ul_code_page_range_2: Option<u32>,
118    /// This metric specifies the distance between the baseline and the
119    /// approximate height of non-ascending lowercase letters measured in
120    /// FUnits.
121    pub sx_height: Option<i16>,
122    /// This metric specifies the distance between the baseline and the
123    /// approximate height of uppercase letters measured in FUnits.
124    pub s_cap_height: Option<i16>,
125    /// This is the Unicode codepoint, in UTF-16 encoding, of a character that
126    /// can be used for a default glyph.
127    pub us_default_char: Option<u16>,
128    /// This is the Unicode codepoint, in UTF-16 encoding, of a character that
129    /// can be used as a default break character.
130    pub us_break_char: Option<u16>,
131    /// This field is used for fonts with multiple optical styles.
132    pub us_max_context: Option<u16>,
133    /// This field is used for fonts with multiple optical styles.
134    pub us_lower_optical_point_size: Option<u16>,
135    /// This field is used for fonts with multiple optical styles.
136    pub us_upper_optical_point_size: Option<u16>,
137}
138
139impl Default for Os2 {
140    fn default() -> Self {
141        Self {
142            x_avg_char_width: Default::default(),
143            us_weight_class: 400,
144            us_width_class: 5,
145            fs_type: Default::default(),
146            y_subscript_x_size: Default::default(),
147            y_subscript_y_size: Default::default(),
148            y_subscript_x_offset: Default::default(),
149            y_subscript_y_offset: Default::default(),
150            y_superscript_x_size: Default::default(),
151            y_superscript_y_size: Default::default(),
152            y_superscript_x_offset: Default::default(),
153            y_superscript_y_offset: Default::default(),
154            y_strikeout_size: Default::default(),
155            y_strikeout_position: Default::default(),
156            s_family_class: Default::default(),
157            panose_10: Default::default(),
158            ul_unicode_range_1: Default::default(),
159            ul_unicode_range_2: Default::default(),
160            ul_unicode_range_3: Default::default(),
161            ul_unicode_range_4: Default::default(),
162            ach_vend_id: Default::default(),
163            fs_selection: Default::default(),
164            us_first_char_index: Default::default(),
165            us_last_char_index: Default::default(),
166            s_typo_ascender: Default::default(),
167            s_typo_descender: Default::default(),
168            s_typo_line_gap: Default::default(),
169            us_win_ascent: Default::default(),
170            us_win_descent: Default::default(),
171            ul_code_page_range_1: Default::default(),
172            ul_code_page_range_2: Default::default(),
173            sx_height: Default::default(),
174            s_cap_height: Default::default(),
175            us_default_char: Default::default(),
176            us_break_char: Default::default(),
177            us_max_context: Default::default(),
178            us_lower_optical_point_size: Default::default(),
179            us_upper_optical_point_size: Default::default(),
180        }
181    }
182}
183
184impl FontWrite for Os2 {
185    #[allow(clippy::unnecessary_cast)]
186    fn write_into(&self, writer: &mut TableWriter) {
187        let version = self.compute_version() as u16;
188        version.write_into(writer);
189        self.x_avg_char_width.write_into(writer);
190        self.us_weight_class.write_into(writer);
191        self.us_width_class.write_into(writer);
192        self.fs_type.write_into(writer);
193        self.y_subscript_x_size.write_into(writer);
194        self.y_subscript_y_size.write_into(writer);
195        self.y_subscript_x_offset.write_into(writer);
196        self.y_subscript_y_offset.write_into(writer);
197        self.y_superscript_x_size.write_into(writer);
198        self.y_superscript_y_size.write_into(writer);
199        self.y_superscript_x_offset.write_into(writer);
200        self.y_superscript_y_offset.write_into(writer);
201        self.y_strikeout_size.write_into(writer);
202        self.y_strikeout_position.write_into(writer);
203        self.s_family_class.write_into(writer);
204        self.panose_10.write_into(writer);
205        self.ul_unicode_range_1.write_into(writer);
206        self.ul_unicode_range_2.write_into(writer);
207        self.ul_unicode_range_3.write_into(writer);
208        self.ul_unicode_range_4.write_into(writer);
209        self.ach_vend_id.write_into(writer);
210        self.fs_selection.write_into(writer);
211        self.us_first_char_index.write_into(writer);
212        self.us_last_char_index.write_into(writer);
213        self.s_typo_ascender.write_into(writer);
214        self.s_typo_descender.write_into(writer);
215        self.s_typo_line_gap.write_into(writer);
216        self.us_win_ascent.write_into(writer);
217        self.us_win_descent.write_into(writer);
218        version.compatible(1u16).then(|| {
219            self.ul_code_page_range_1
220                .as_ref()
221                .expect("missing conditional field should have failed validation")
222                .write_into(writer)
223        });
224        version.compatible(1u16).then(|| {
225            self.ul_code_page_range_2
226                .as_ref()
227                .expect("missing conditional field should have failed validation")
228                .write_into(writer)
229        });
230        version.compatible(2u16).then(|| {
231            self.sx_height
232                .as_ref()
233                .expect("missing conditional field should have failed validation")
234                .write_into(writer)
235        });
236        version.compatible(2u16).then(|| {
237            self.s_cap_height
238                .as_ref()
239                .expect("missing conditional field should have failed validation")
240                .write_into(writer)
241        });
242        version.compatible(2u16).then(|| {
243            self.us_default_char
244                .as_ref()
245                .expect("missing conditional field should have failed validation")
246                .write_into(writer)
247        });
248        version.compatible(2u16).then(|| {
249            self.us_break_char
250                .as_ref()
251                .expect("missing conditional field should have failed validation")
252                .write_into(writer)
253        });
254        version.compatible(2u16).then(|| {
255            self.us_max_context
256                .as_ref()
257                .expect("missing conditional field should have failed validation")
258                .write_into(writer)
259        });
260        version.compatible(5u16).then(|| {
261            self.us_lower_optical_point_size
262                .as_ref()
263                .expect("missing conditional field should have failed validation")
264                .write_into(writer)
265        });
266        version.compatible(5u16).then(|| {
267            self.us_upper_optical_point_size
268                .as_ref()
269                .expect("missing conditional field should have failed validation")
270                .write_into(writer)
271        });
272    }
273    fn table_type(&self) -> TableType {
274        TableType::TopLevel(Os2::TAG)
275    }
276}
277
278impl Validate for Os2 {
279    fn validate_impl(&self, ctx: &mut ValidationCtx) {
280        ctx.in_table("Os2", |ctx| {
281            let version: u16 = self.compute_version();
282            ctx.in_field("ul_code_page_range_1", |ctx| {
283                if version.compatible(1u16) && self.ul_code_page_range_1.is_none() {
284                    ctx.report(format!("field must be present for version {version}"));
285                }
286            });
287            ctx.in_field("ul_code_page_range_2", |ctx| {
288                if version.compatible(1u16) && self.ul_code_page_range_2.is_none() {
289                    ctx.report(format!("field must be present for version {version}"));
290                }
291            });
292            ctx.in_field("sx_height", |ctx| {
293                if version.compatible(2u16) && self.sx_height.is_none() {
294                    ctx.report(format!("field must be present for version {version}"));
295                }
296            });
297            ctx.in_field("s_cap_height", |ctx| {
298                if version.compatible(2u16) && self.s_cap_height.is_none() {
299                    ctx.report(format!("field must be present for version {version}"));
300                }
301            });
302            ctx.in_field("us_default_char", |ctx| {
303                if version.compatible(2u16) && self.us_default_char.is_none() {
304                    ctx.report(format!("field must be present for version {version}"));
305                }
306            });
307            ctx.in_field("us_break_char", |ctx| {
308                if version.compatible(2u16) && self.us_break_char.is_none() {
309                    ctx.report(format!("field must be present for version {version}"));
310                }
311            });
312            ctx.in_field("us_max_context", |ctx| {
313                if version.compatible(2u16) && self.us_max_context.is_none() {
314                    ctx.report(format!("field must be present for version {version}"));
315                }
316            });
317            ctx.in_field("us_lower_optical_point_size", |ctx| {
318                if version.compatible(5u16) && self.us_lower_optical_point_size.is_none() {
319                    ctx.report(format!("field must be present for version {version}"));
320                }
321            });
322            ctx.in_field("us_upper_optical_point_size", |ctx| {
323                if version.compatible(5u16) && self.us_upper_optical_point_size.is_none() {
324                    ctx.report(format!("field must be present for version {version}"));
325                }
326            });
327        })
328    }
329}
330
331impl TopLevelTable for Os2 {
332    const TAG: Tag = Tag::new(b"OS/2");
333}
334
335impl<'a> FromObjRef<read_fonts::tables::os2::Os2<'a>> for Os2 {
336    fn from_obj_ref(obj: &read_fonts::tables::os2::Os2<'a>, _: FontData) -> Self {
337        Os2 {
338            x_avg_char_width: obj.x_avg_char_width(),
339            us_weight_class: obj.us_weight_class(),
340            us_width_class: obj.us_width_class(),
341            fs_type: obj.fs_type(),
342            y_subscript_x_size: obj.y_subscript_x_size(),
343            y_subscript_y_size: obj.y_subscript_y_size(),
344            y_subscript_x_offset: obj.y_subscript_x_offset(),
345            y_subscript_y_offset: obj.y_subscript_y_offset(),
346            y_superscript_x_size: obj.y_superscript_x_size(),
347            y_superscript_y_size: obj.y_superscript_y_size(),
348            y_superscript_x_offset: obj.y_superscript_x_offset(),
349            y_superscript_y_offset: obj.y_superscript_y_offset(),
350            y_strikeout_size: obj.y_strikeout_size(),
351            y_strikeout_position: obj.y_strikeout_position(),
352            s_family_class: obj.s_family_class(),
353            panose_10: convert_panose(obj.panose_10()),
354            ul_unicode_range_1: obj.ul_unicode_range_1(),
355            ul_unicode_range_2: obj.ul_unicode_range_2(),
356            ul_unicode_range_3: obj.ul_unicode_range_3(),
357            ul_unicode_range_4: obj.ul_unicode_range_4(),
358            ach_vend_id: obj.ach_vend_id(),
359            fs_selection: obj.fs_selection(),
360            us_first_char_index: obj.us_first_char_index(),
361            us_last_char_index: obj.us_last_char_index(),
362            s_typo_ascender: obj.s_typo_ascender(),
363            s_typo_descender: obj.s_typo_descender(),
364            s_typo_line_gap: obj.s_typo_line_gap(),
365            us_win_ascent: obj.us_win_ascent(),
366            us_win_descent: obj.us_win_descent(),
367            ul_code_page_range_1: obj.ul_code_page_range_1(),
368            ul_code_page_range_2: obj.ul_code_page_range_2(),
369            sx_height: obj.sx_height(),
370            s_cap_height: obj.s_cap_height(),
371            us_default_char: obj.us_default_char(),
372            us_break_char: obj.us_break_char(),
373            us_max_context: obj.us_max_context(),
374            us_lower_optical_point_size: obj.us_lower_optical_point_size(),
375            us_upper_optical_point_size: obj.us_upper_optical_point_size(),
376        }
377    }
378}
379
380#[allow(clippy::needless_lifetimes)]
381impl<'a> FromTableRef<read_fonts::tables::os2::Os2<'a>> for Os2 {}
382
383impl<'a> FontRead<'a> for Os2 {
384    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
385        <read_fonts::tables::os2::Os2 as FontRead>::read(data).map(|x| x.to_owned_table())
386    }
387}