1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// THIS FILE IS AUTOGENERATED.
// Any changes to this file will be overwritten.
// For more information about how codegen works, see font-codegen/README.md

#[allow(unused_imports)]
use crate::codegen_prelude::*;

/// The [VORG (Vertical Origin)](https://docs.microsoft.com/en-us/typography/opentype/spec/vorg) table.
#[derive(Debug, Clone, Copy)]
#[doc(hidden)]
pub struct VorgMarker {
    vert_origin_y_metrics_byte_len: usize,
}

impl VorgMarker {
    fn version_byte_range(&self) -> Range<usize> {
        let start = 0;
        start..start + MajorMinor::RAW_BYTE_LEN
    }
    fn default_vert_origin_y_byte_range(&self) -> Range<usize> {
        let start = self.version_byte_range().end;
        start..start + i16::RAW_BYTE_LEN
    }
    fn num_vert_origin_y_metrics_byte_range(&self) -> Range<usize> {
        let start = self.default_vert_origin_y_byte_range().end;
        start..start + u16::RAW_BYTE_LEN
    }
    fn vert_origin_y_metrics_byte_range(&self) -> Range<usize> {
        let start = self.num_vert_origin_y_metrics_byte_range().end;
        start..start + self.vert_origin_y_metrics_byte_len
    }
}

impl TopLevelTable for Vorg<'_> {
    /// `VORG`
    const TAG: Tag = Tag::new(b"VORG");
}

impl<'a> FontRead<'a> for Vorg<'a> {
    fn read(data: FontData<'a>) -> Result<Self, ReadError> {
        let mut cursor = data.cursor();
        cursor.advance::<MajorMinor>();
        cursor.advance::<i16>();
        let num_vert_origin_y_metrics: u16 = cursor.read()?;
        let vert_origin_y_metrics_byte_len = (num_vert_origin_y_metrics as usize)
            .checked_mul(VertOriginYMetrics::RAW_BYTE_LEN)
            .ok_or(ReadError::OutOfBounds)?;
        cursor.advance_by(vert_origin_y_metrics_byte_len);
        cursor.finish(VorgMarker {
            vert_origin_y_metrics_byte_len,
        })
    }
}

/// The [VORG (Vertical Origin)](https://docs.microsoft.com/en-us/typography/opentype/spec/vorg) table.
pub type Vorg<'a> = TableRef<'a, VorgMarker>;

impl<'a> Vorg<'a> {
    /// Major/minor version number. Set to 1.0.
    pub fn version(&self) -> MajorMinor {
        let range = self.shape.version_byte_range();
        self.data.read_at(range.start).unwrap()
    }

    /// The y coordinate of a glyph’s vertical origin, in the font’s design
    /// coordinate system, to be used if no entry is present for the glyph
    /// in the vertOriginYMetrics array.
    pub fn default_vert_origin_y(&self) -> i16 {
        let range = self.shape.default_vert_origin_y_byte_range();
        self.data.read_at(range.start).unwrap()
    }

    /// Number of elements in the vertOriginYMetrics array.
    pub fn num_vert_origin_y_metrics(&self) -> u16 {
        let range = self.shape.num_vert_origin_y_metrics_byte_range();
        self.data.read_at(range.start).unwrap()
    }

    /// Array of VertOriginYMetrics records, sorted by glyph ID.
    pub fn vert_origin_y_metrics(&self) -> &'a [VertOriginYMetrics] {
        let range = self.shape.vert_origin_y_metrics_byte_range();
        self.data.read_array(range).unwrap()
    }
}

#[cfg(feature = "experimental_traverse")]
impl<'a> SomeTable<'a> for Vorg<'a> {
    fn type_name(&self) -> &str {
        "Vorg"
    }
    fn get_field(&self, idx: usize) -> Option<Field<'a>> {
        match idx {
            0usize => Some(Field::new("version", self.version())),
            1usize => Some(Field::new(
                "default_vert_origin_y",
                self.default_vert_origin_y(),
            )),
            2usize => Some(Field::new(
                "num_vert_origin_y_metrics",
                self.num_vert_origin_y_metrics(),
            )),
            3usize => Some(Field::new(
                "vert_origin_y_metrics",
                traversal::FieldType::array_of_records(
                    stringify!(VertOriginYMetrics),
                    self.vert_origin_y_metrics(),
                    self.offset_data(),
                ),
            )),
            _ => None,
        }
    }
}

#[cfg(feature = "experimental_traverse")]
impl<'a> std::fmt::Debug for Vorg<'a> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        (self as &dyn SomeTable<'a>).fmt(f)
    }
}

/// Vertical origin Y metrics record.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, bytemuck :: AnyBitPattern)]
#[repr(C)]
#[repr(packed)]
pub struct VertOriginYMetrics {
    /// Glyph index.
    pub glyph_index: BigEndian<GlyphId16>,
    /// Y coordinate, in the font’s design coordinate system, of the glyph’s vertical origin.
    pub vert_origin_y: BigEndian<i16>,
}

impl VertOriginYMetrics {
    /// Glyph index.
    pub fn glyph_index(&self) -> GlyphId16 {
        self.glyph_index.get()
    }

    /// Y coordinate, in the font’s design coordinate system, of the glyph’s vertical origin.
    pub fn vert_origin_y(&self) -> i16 {
        self.vert_origin_y.get()
    }
}

impl FixedSize for VertOriginYMetrics {
    const RAW_BYTE_LEN: usize = GlyphId16::RAW_BYTE_LEN + i16::RAW_BYTE_LEN;
}

#[cfg(feature = "experimental_traverse")]
impl<'a> SomeRecord<'a> for VertOriginYMetrics {
    fn traverse(self, data: FontData<'a>) -> RecordResolver<'a> {
        RecordResolver {
            name: "VertOriginYMetrics",
            get_field: Box::new(move |idx, _data| match idx {
                0usize => Some(Field::new("glyph_index", self.glyph_index())),
                1usize => Some(Field::new("vert_origin_y", self.vert_origin_y())),
                _ => None,
            }),
            data,
        }
    }
}