Tests: a fitted text test changes its fit scale

The regression test for rebuilding fitted area type after a scale change
used text that overflowed at the minimum size both before and after the
change, so both layouts used the same fit scale and the pixel comparison
did not depend on the fit.

The fixture is now 2 pt type in a small frame, drawn 20 times zoomed in.
It fits at 0.7 of its size, and at 0.733 after a 1.5 times scale. The
test asserts that the two fit scales differ and that the words set at the
earlier fit draw different pixels, and keeps the comparison with a fresh
renderer and the check that the geometry is not reused.
This commit is contained in:
dotCooCoo
2026-11-06 12:42:26 +07:00
committed by bflatastic
parent 70f798b71d
commit b75b1548d4
+28 -6
View File
@@ -189,22 +189,44 @@ fn moving_type_reuses_character_strokes_without_changing_pixels() {
#[test]
fn scaling_fitted_area_type_rebuilds_its_glyph_geometry() {
let _fonts = fonts_steady();
let (mut d, id) = stroked_text_doc("A long story that must shrink to fit in a small area of type");
// 2 pt type, drawn 20× zoomed in. Shrink Text to Fit steps the size in tenths of a document
// point, so at 2 pt and at 3 pt it fits the same words at different fractions of full size.
let (mut d, id) = stroked_text_doc("Type");
if let Some(Node { kind: NodeKind::Text(t), .. }) = d.node_mut(id) {
t.kind = TextKind::Area { frame: PathData::from_bezpath(&Rect::new(0.0, 0.0, 100.0, 45.0).to_path(0.1)) };
t.xf = Affine::IDENTITY;
t.runs[0].style.size = 2.0;
t.runs[0].style.stroke_width = 0.05;
t.kind = TextKind::Area { frame: PathData::from_bezpath(&Rect::new(0.0, 0.0, 3.0, 3.0).to_path(0.1)) };
t.area.fit = AreaFit::ShrinkText { min_percent: 30.0 };
}
let text = |d: &Document| match d.node(id).map(|n| &n.kind) {
Some(NodeKind::Text(t)) => (**t).clone(),
_ => panic!("the text object"),
};
let fit = |d: &Document| vectorcraft_text::layout(vectorcraft_text::FontDb::global(), &text(d)).fit_scale;
let view = Affine::scale(20.0);
let opts = RenderOptions::default();
let mut r = Renderer::new();
r.render(&d, SIZE, SIZE, Affine::IDENTITY, &opts);
r.render(&d, SIZE, SIZE, view, &opts);
let first = r.texts.used_in(r.stamp).next().unwrap().1.clone();
let before = fit(&d);
if let Some(Node { kind: NodeKind::Text(t), .. }) = d.node_mut(id) {
t.xf = Affine::scale(1.2) * t.xf;
t.xf = Affine::scale(1.5) * t.xf;
}
let scaled = r.render(&d, SIZE, SIZE, Affine::IDENTITY, &opts);
let after = fit(&d);
assert!(before > 0.3 && before < 1.0 && after > 0.3 && after < 1.0, "it fits above the minimum both times: {before}, {after}");
assert!((before - after).abs() > 0.01, "the scale changes the fitted size: {before}, {after}");
let scaled = r.render(&d, SIZE, SIZE, view, &opts);
let again = r.texts.used_in(r.stamp).next().unwrap().1.clone();
assert!(!Arc::ptr_eq(&first, &again), "changing area type's scale lays it out again");
assert_eq!(scaled.pixels, Renderer::new().render(&d, SIZE, SIZE, Affine::IDENTITY, &opts).pixels);
assert_eq!(scaled.pixels, Renderer::new().render(&d, SIZE, SIZE, view, &opts).pixels);
// The words set at the earlier fit, which reusing the earlier layout would draw, draw other pixels.
let mut stale = d.clone();
if let Some(Node { kind: NodeKind::Text(t), .. }) = stale.node_mut(id) {
**t = vectorcraft_text::scaled(t, before);
}
assert_eq!(fit(&stale), 1.0, "the earlier fit's words fit as they are");
assert_ne!(scaled.pixels, Renderer::new().render(&stale, SIZE, SIZE, view, &opts).pixels, "the new fit changes the pixels");
}
/// Frames that draw character strokes from the cache draw the same pixels, and what a renderer