vectorcraft/crates/text/src/tests_scripts.rs

51 lines
2.4 KiB
Rust

//! Superscript, subscript and synthesized small caps (Character panel, Document Setup → Type).
use kurbo::Shape;
use vectorcraft_doc::{CharPosition, CharStyle, ScriptMetrics, TextObject};
use super::*;
fn layout_of(text: &str, st: CharStyle) -> TextLayout {
layout(FontDb::global(), &TextObject::point(kurbo::Point::ZERO, text, st))
}
fn glyph_box(l: &TextLayout, i: usize) -> kurbo::Rect {
l.glyphs[i].outline.bounding_box()
}
#[test]
fn superscript_and_subscript_scale_and_shift_glyphs() {
let base = CharStyle { size: 20.0, ..CharStyle::default() };
let normal = layout_of("H", base.clone());
let m = ScriptMetrics { size: 50.0, position: 40.0 };
let sup = layout_of("H", CharStyle { position: CharPosition::Superscript(m), ..base.clone() });
let sub = layout_of("H", CharStyle { position: CharPosition::Subscript(m), ..base.clone() });
let (n, p, b) = (glyph_box(&normal, 0), glyph_box(&sup, 0), glyph_box(&sub, 0));
// Half the height and advance.
assert!((p.height() - n.height() * 0.5).abs() < 0.05, "{p:?} vs {n:?}");
assert!((sup.glyphs[0].advance - normal.glyphs[0].advance * 0.5).abs() < 1e-6);
// Raised / lowered by 40% of 20 pt (y points down).
assert!((p.y1 - (n.y1 - 8.0)).abs() < 0.05, "{p:?}");
assert!((b.y1 - (n.y1 + 8.0)).abs() < 0.05, "{b:?}");
// Line metrics keep the full size.
assert_eq!(sup.lines[0].ascent, normal.lines[0].ascent);
}
#[test]
fn small_caps_draw_lowercase_as_smaller_capitals() {
let base = CharStyle { size: 20.0, ..CharStyle::default() };
let cap = layout_of("A", base.clone());
let cap14 = layout_of("A", CharStyle { size: 14.0, ..base.clone() });
let small = layout_of("Aa", CharStyle { small_caps: Some(70.0), ..base.clone() });
// The capital is unchanged; the lowercase letter is a capital A at 70% (14 pt).
assert_eq!(small.glyphs[0].advance, cap.glyphs[0].advance);
assert!((small.glyphs[1].advance - cap14.glyphs[0].advance).abs() < 1e-6);
let (a, s) = (glyph_box(&cap14, 0), glyph_box(&small, 1));
assert!((s.height() - a.height()).abs() < 0.05, "{s:?} vs {a:?}");
// Byte offsets still map back to the source characters.
assert_eq!((small.glyphs[1].byte, small.glyphs[1].len), (1, 1));
// All Caps wins over Small Caps.
let all = layout_of("a", CharStyle { all_caps: true, small_caps: Some(70.0), ..base });
assert_eq!(all.glyphs[0].advance, cap.glyphs[0].advance);
}