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
//! Mathematical typesetting table.
use super::otl::Coverage;
use super::parse_prelude::*;
/// Tag for the `math` table.
pub const MATH: Tag = Tag::new(b"MATH");
/// Mathematical typesetting table.
///
/// <https://docs.microsoft.com/en-us/typography/opentype/spec/math>
///
/// The math constants and math glyph information subtables are not (yet)
/// implemented.
#[derive(Copy, Clone)]
pub struct Math<'a>(Buffer<'a>);
impl<'a> Math<'a> {
/// Creates a new math table from a byte slice containing the table data.
pub fn new(data: &'a [u8]) -> Self {
Self(Buffer::new(data))
}
/// Returns the major version.
pub fn major_version(&self) -> u16 {
self.0.read(0).unwrap_or(0)
}
/// Returns the minor version.
pub fn minor_version(&self) -> u16 {
self.0.read(2).unwrap_or(0)
}
/// Returns the MathVariants subtable.
pub fn variants(&self) -> Option<MathVariants> {
let offset = self.0.read_offset16(8, 0)?;
Some(MathVariants { math: self, offset })
}
}
/// Mathematical variants subtable.
///
/// <https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathvariants-table>
#[derive(Copy, Clone)]
pub struct MathVariants<'a> {
math: &'a Math<'a>,
offset: u32,
}
impl<'a> MathVariants<'a> {
/// Returns the minimum overlap of connecting glyphs during glyph
/// construction.
pub fn min_connector_overlap(&self) -> UfWord {
self.math.0.read(self.offset as usize).unwrap_or(0)
}
/// Returns the number of glyphs for which information is provided for
/// vertically growing variants.
pub fn vert_glyph_count(&self) -> u16 {
self.math.0.read(self.offset as usize + 6).unwrap_or(0)
}
/// Returns the number of glyphs for which information is provided for
/// horizontally growing variants.
pub fn horiz_glyph_count(&self) -> u16 {
self.math.0.read(self.offset as usize + 8).unwrap_or(0)
}
/// Returns the coverage table associated with vertically growing glyphs.
pub fn vert_glyph_coverage(&self) -> Option<Coverage> {
let offset = self
.math
.0
.read_offset16(self.offset as usize + 2, self.offset)?;
Some(Coverage::new(self.math.0, offset))
}
/// Returns the coverage table associated with horizontally growing glyphs.
pub fn horiz_glyph_coverage(&self) -> Option<Coverage> {
let offset = self
.math
.0
.read_offset16(self.offset as usize + 4, self.offset)?;
Some(Coverage::new(self.math.0, offset))
}
/// Returns information about how to a construct vertically growing glyph,
/// based on its coverage index.
pub fn vert_glyph_construction(&self, coverage_index: u16) -> Option<MathGlyphConstruction> {
let offset = self.offset as usize + 10 + 2 * coverage_index as usize;
let offset = self.math.0.read_offset16(offset, self.offset)?;
Some(MathGlyphConstruction {
math: self.math,
offset: offset,
})
}
/// Returns information about how to a construct horizontally growing glyph,
/// based on its coverage index.
pub fn horiz_glyph_construction(&self, coverage_index: u16) -> Option<MathGlyphConstruction> {
let offset = self.offset as usize
+ 10
+ 2 * self.vert_glyph_count() as usize
+ 2 * coverage_index as usize;
let offset = self.math.0.read_offset16(offset, self.offset)?;
Some(MathGlyphConstruction {
math: self.math,
offset: offset,
})
}
}
/// Mathematical glyph construction subtable.
///
/// <https://docs.microsoft.com/en-us/typography/opentype/spec/math#mathvariants-table>
///
/// The "glyph assembly" subtable is not (yet) implemented.
#[derive(Copy, Clone)]
pub struct MathGlyphConstruction<'a> {
math: &'a Math<'a>,
offset: u32,
}
impl<'a> MathGlyphConstruction<'a> {
/// Returns the number of growing variants for this glyph.
pub fn variant_count(&self) -> u16 {
self.math.0.read(self.offset as usize + 2).unwrap_or(0)
}
/// Return the growing variants associated with this glyph.
pub fn variants(&self) -> Option<Slice<'a, MathGlyphVariantRecord>> {
self.math
.0
.read_slice(self.offset as usize + 4, self.variant_count() as usize)
}
}
/// Information about a math glyph variant.
#[derive(Copy, Clone, Debug)]
pub struct MathGlyphVariantRecord {
/// The variant glyph
pub variant_glyph: GlyphId,
/// The advance width/height of the variant, in the direction of this
/// record's associated table.
pub advance_measurement: UfWord,
}
impl ReadData for MathGlyphVariantRecord {
unsafe fn read_data_unchecked(buf: &[u8], offset: usize) -> Self {
Self {
variant_glyph: GlyphId::read_data_unchecked(buf, offset),
advance_measurement: UfWord::read_data_unchecked(buf, offset + 2),
}
}
}