use formulary::{layout, parse, GlyphId, Item, LayoutOptions, MathFont};
fn stix() -> Vec<u8> {
std::fs::read(concat!(
env!("CARGO_MANIFEST_DIR"),
"/fonts/STIXTwoMath-Regular.otf"
))
.expect("vendored test font")
}
#[test]
fn probe_accepts_math_font_and_agrees_with_new() {
let data = stix();
assert!(MathFont::probe(&data, 0));
assert!(MathFont::new(&data, 0).is_ok());
}
#[test]
fn probe_rejects_non_fonts() {
assert!(!MathFont::probe(&[], 0));
assert!(!MathFont::probe(b"definitely not a font", 0));
assert!(!MathFont::probe(&stix()[..64], 0));
}
#[test]
fn probe_rejects_font_without_math_table() {
let mut data = stix();
let num_tables = u16::from_be_bytes([data[4], data[5]]) as usize;
let mut renamed = false;
for i in 0..num_tables {
let at = 12 + 16 * i;
if &data[at..at + 4] == b"MATH" {
data[at..at + 4].copy_from_slice(b"XATH");
renamed = true;
}
}
assert!(renamed, "test font should have a MATH table to rename");
assert!(!MathFont::probe(&data, 0));
assert!(MathFont::new(&data, 0).is_err());
}
#[test]
fn glyph_items_carry_the_nominal_advance() {
let data = stix();
let font = MathFont::new(&data, 0).unwrap();
let tree = parse("<math><mi>x</mi></math>").unwrap();
let laid = layout(&tree, &font, &LayoutOptions { font_size: 16.0 });
let glyphs: Vec<_> = laid
.items
.iter()
.filter_map(|item| match *item {
Item::Glyph { id, advance, .. } => Some((id, advance)),
_ => None,
})
.collect();
assert_eq!(glyphs.len(), 1);
let (id, advance) = glyphs[0];
assert!(id != GlyphId(0), "x should map to a real glyph");
assert!(advance > 0.0);
assert!((advance - laid.width).abs() < 1e-4);
}
#[test]
fn advance_scales_with_font_size() {
let data = stix();
let font = MathFont::new(&data, 0).unwrap();
let tree = parse("<math><mn>7</mn></math>").unwrap();
let advance_at = |size: f32| {
let laid = layout(&tree, &font, &LayoutOptions { font_size: size });
laid.items
.iter()
.find_map(|item| match *item {
Item::Glyph { advance, .. } => Some(advance),
_ => None,
})
.unwrap()
};
let a16 = advance_at(16.0);
let a32 = advance_at(32.0);
assert!((a32 - 2.0 * a16).abs() < 1e-3);
}
#[test]
fn arabic_text_detection() {
let has = |markup: &str| parse(markup).unwrap().has_arabic_text();
assert!(!has("<math><mi>x</mi><mo>+</mo><mn>2</mn></math>"));
assert!(has("<math><mi>\u{0633}</mi></math>"));
assert!(has(
"<math><mfrac><mn>1</mn><mrow><mi>\u{0645}</mi></mrow></mfrac></math>"
));
assert!(has(
"<math><mtable><mtr><mtd><mtext>\u{FEB3}</mtext></mtd></mtr></mtable></math>"
));
assert!(has("<math><mi>\u{1EE00}</mi></math>"));
assert!(!has("<math dir=\"rtl\"><msqrt><mi>x</mi></msqrt></math>"));
}