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
//! 書体が化学式に要る字を持っているか、どんな寸法かを見る
//!
//! 使い方:
//! cargo run --example probe
//! cargo run --example probe -- /path/to/other.otf
use lina::font::{self, Font};
const DEFAULT_FONT: &str = "font/latinmodern-math.otf";
/// 化学式によく出る字。負電荷は U+2212 で組むので、そちらを見る
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!("フォントを読めません: {path}: {reason}");
std::process::exit(1);
}
};
let font = match font::load(data) {
Ok(font) => font,
Err(reason) => {
eprintln!("フォントを読み込めません: {path}: {reason}");
std::process::exit(1);
}
};
println!("書体 {}", font::family(&font));
println!("1em の単位 {}", font::units_per_em(&font));
println!("大文字の高さ {:.4} em", font::cap_height(&font));
println!("x の高さ {:.4} em", font::x_height(&font));
println!();
println!("字 送り幅 高さ 深さ 左の余白 右の余白");
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!("要る字はすべて持っています");
} else {
let list: String = missing.iter().collect();
println!();
println!("持っていない字: {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}"
);
}