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
use lina::font::{self, Font};
const DEFAULT_FONT: &str = "font/latinmodern-math.otf";
const WANTED: &str = "CHONSPFlBrIKNaMgZ0123456789+\u{2212}";
fn main() {
let path = std::env::args().nth(1).unwrap_or_else(|| DEFAULT_FONT.to_string());
let data = match std::fs::read(&path) {
Ok(data) => data,
Err(reason) => {
eprintln!("cannot read the font: {path}: {reason}");
std::process::exit(1);
}
};
let font = match font::load(data) {
Ok(font) => font,
Err(reason) => {
eprintln!("cannot load the font: {path}: {reason}");
std::process::exit(1);
}
};
println!("typeface {}", font::family(&font));
println!("units per em {}", font::units_per_em(&font));
println!("cap height {:.4} em", font::cap_height(&font));
println!("x-height {:.4} em", font::x_height(&font));
println!();
println!(" advance height depth left right");
let mut missing = Vec::new();
for character in WANTED.chars() {
match font::glyph_of(&font, character) {
None => missing.push(character),
Some(glyph) => report(&font, character, glyph),
}
}
if missing.is_empty() {
println!();
println!("every character needed is there");
} else {
let list: String = missing.iter().collect();
println!();
println!("missing characters: {list}");
}
}
fn report(font: &Font, character: char, glyph: u16) {
let advance = font::advance(font, glyph);
let (height, depth) = font::extent(font, glyph);
let (left, right) = font::bearing(font, glyph);
println!(
"{character} {advance:.4} {height:.4} {depth:.4} {left:.4} {right:.4}"
);
}