#[cfg(test)]
mod tests {
use ttf_parser::Face;
fn embedded_fonts() -> [(&'static str, &'static [u8]); 8] {
[
("DejaVuSans", uzor_fonts::DEJAVU_SANS),
("Roboto-Regular", uzor_fonts::ROBOTO_REGULAR),
("Roboto-Bold", uzor_fonts::ROBOTO_BOLD),
("Roboto-Italic", uzor_fonts::ROBOTO_ITALIC),
("Roboto-BoldItalic", uzor_fonts::ROBOTO_BOLD_ITALIC),
("JetBrainsMono-Regular", uzor_fonts::JETBRAINS_MONO_REGULAR),
("JetBrainsMono-Bold", uzor_fonts::JETBRAINS_MONO_BOLD),
("PTRootUI-VF", uzor_fonts::PT_ROOT_UI_VF),
]
}
fn digit_advances(bytes: &[u8]) -> (Vec<u16>, u16) {
let face = Face::parse(bytes, 0).expect("embedded font must parse");
let upm = face.units_per_em();
let advances: Vec<u16> = ('0'..='9')
.map(|c| {
let gid = face.glyph_index(c).unwrap_or_else(|| panic!("font must contain digit '{c}'"));
face.glyph_hor_advance(gid).unwrap_or_else(|| panic!("digit '{c}' must have a horizontal advance"))
})
.collect();
(advances, upm)
}
fn all_equal(advances: &[u16]) -> bool {
advances.windows(2).all(|w| w[0] == w[1])
}
fn to_px(units: u16, upm: u16, size_px: f64) -> f64 {
units as f64 * size_px / upm as f64
}
#[test]
fn digit_width_audit_table() {
for (label, bytes) in embedded_fonts() {
let (advances, upm) = digit_advances(bytes);
let tabular = all_equal(&advances);
let px16: Vec<f64> = advances.iter().map(|&u| (to_px(u, upm, 16.0) * 100.0).round() / 100.0).collect();
let px32: Vec<f64> = advances.iter().map(|&u| (to_px(u, upm, 32.0) * 100.0).round() / 100.0).collect();
println!("{label:22} upm={upm:5} tabular={tabular:5} units(0-9)={advances:?} px16={px16:?} px32={px32:?}");
}
}
#[test]
fn jetbrains_mono_digits_are_tabular_by_definition_both_weights() {
let (regular, _) = digit_advances(uzor_fonts::JETBRAINS_MONO_REGULAR);
let (bold, _) = digit_advances(uzor_fonts::JETBRAINS_MONO_BOLD);
assert!(all_equal(®ular), "JetBrains Mono Regular digits must be tabular (monospace)");
assert!(all_equal(&bold), "JetBrains Mono Bold digits must be tabular (monospace)");
}
#[test]
fn roboto_and_dejavu_sans_already_have_tabular_default_digits() {
let already_tabular = [
("DejaVuSans", uzor_fonts::DEJAVU_SANS),
("Roboto-Regular", uzor_fonts::ROBOTO_REGULAR),
("Roboto-Bold", uzor_fonts::ROBOTO_BOLD),
("Roboto-Italic", uzor_fonts::ROBOTO_ITALIC),
("Roboto-BoldItalic", uzor_fonts::ROBOTO_BOLD_ITALIC),
];
for (label, bytes) in already_tabular {
let (advances, _) = digit_advances(bytes);
assert!(all_equal(&advances), "{label}: expected already-tabular default digits (T1 measurement), got {advances:?}");
}
}
#[test]
fn pt_root_ui_vf_default_digits_are_not_tabular_a_real_measured_gap() {
let (advances, upm) = digit_advances(uzor_fonts::PT_ROOT_UI_VF);
assert!(!all_equal(&advances), "PT Root UI VF: expected a NON-tabular default (T1 measurement), got uniformly {advances:?}");
let widest = *advances.iter().max().expect("10 digits");
let narrowest = *advances.iter().min().expect("10 digits");
assert_eq!(advances[1], narrowest, "digit '1' must be the narrowest — the classic proportional-figures tell, got advances={advances:?}");
let spread_fraction = (widest - narrowest) as f64 / widest as f64;
assert!(
spread_fraction > 0.25,
"the widest/narrowest digit spread must be a REAL gap (>25% of the widest digit's own advance), got {:.1}% (upm={upm})",
spread_fraction * 100.0
);
}
#[test]
fn tabular_verdict_is_identical_across_render_sizes() {
for (label, bytes) in embedded_fonts() {
let (advances, upm) = digit_advances(bytes);
let units_verdict = all_equal(&advances);
let px16: Vec<f64> = advances.iter().map(|&u| to_px(u, upm, 16.0)).collect();
let px32: Vec<f64> = advances.iter().map(|&u| to_px(u, upm, 32.0)).collect();
let px16_verdict = px16.windows(2).all(|w| (w[0] - w[1]).abs() < 1e-9);
let px32_verdict = px32.windows(2).all(|w| (w[0] - w[1]).abs() < 1e-9);
assert_eq!(units_verdict, px16_verdict, "{label}: 16px verdict must match the font-unit verdict");
assert_eq!(units_verdict, px32_verdict, "{label}: 32px verdict must match the font-unit verdict");
}
}
}