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
use crate::conv::{LineMetrics, DPU};
use crate::GlyphId;
use ttf_parser::Face;
#[derive(Copy, Clone, Debug)]
pub struct FaceRef(pub(crate) &'static Face<'static>);
impl FaceRef {
#[inline]
pub fn glyph_index(&self, c: char) -> GlyphId {
GlyphId(self.0.glyph_index(c).map(|id| id.0).unwrap_or(0))
}
#[inline]
pub fn dpu(self, dpem: f32) -> DPU {
DPU(dpem / f32::from(self.0.units_per_em()))
}
#[inline]
pub fn scale_by_dpem(self, dpem: f32) -> ScaledFaceRef {
ScaledFaceRef(self.0, self.dpu(dpem))
}
#[inline]
pub fn scale_by_dpu(self, dpu: DPU) -> ScaledFaceRef {
ScaledFaceRef(self.0, dpu)
}
#[inline]
pub fn height(&self, dpem: f32) -> f32 {
self.scale_by_dpem(dpem).height()
}
}
#[derive(Copy, Clone, Debug)]
pub struct ScaledFaceRef(&'static Face<'static>, DPU);
impl ScaledFaceRef {
#[inline]
pub fn face(&self) -> FaceRef {
FaceRef(self.0)
}
#[inline]
pub fn dpu(&self) -> DPU {
self.1
}
#[inline]
pub fn h_advance(&self, id: GlyphId) -> f32 {
let x = self.0.glyph_hor_advance(id.into()).unwrap();
self.1.u16_to_px(x)
}
#[inline]
pub fn h_side_bearing(&self, id: GlyphId) -> f32 {
let x = self.0.glyph_hor_side_bearing(id.into()).unwrap_or(0);
self.1.i16_to_px(x)
}
#[inline]
pub fn ascent(&self) -> f32 {
self.1.i16_to_px(self.0.ascender())
}
#[inline]
pub fn descent(&self) -> f32 {
self.1.i16_to_px(self.0.descender())
}
#[inline]
pub fn line_gap(&self) -> f32 {
self.1.i16_to_px(self.0.line_gap())
}
#[inline]
pub fn height(&self) -> f32 {
self.1.i16_to_px(self.0.height())
}
#[inline]
pub fn underline_metrics(&self) -> Option<LineMetrics> {
self.0
.underline_metrics()
.map(|m| self.1.to_line_metrics(m))
}
#[inline]
pub fn strikethrough_metrics(&self) -> Option<LineMetrics> {
self.0
.strikeout_metrics()
.map(|m| self.1.to_line_metrics(m))
}
}