use crate::layout::TextLayout;
use crate::style::TextStyle;
use crate::system::TextSystem;
use proptest::prelude::*;
use smudge_core::geometry::Point;
fn setup() {
TextSystem::bundled_only().install();
}
fn glyph_positions(layout: &TextLayout) -> Vec<(u32, f32, f32)> {
let origin = Point { x: 10.0, y: 20.0 };
let mut positions = Vec::new();
for run in layout.glyph_runs_at(origin, smudge_core::geometry::Color::BLACK) {
for glyph in &run.glyphs {
positions.push((glyph.id, glyph.x, glyph.y));
}
}
positions
}
#[test]
fn rebreaking_at_another_width_matches_a_fresh_layout() {
setup();
let style = TextStyle::default();
let text = "The quick brown fox jumps over the lazy dog and keeps \
running until the sentence wraps onto several lines.";
let mut rebroken = TextLayout::new(text, &style, Some(220.0));
rebroken.rebreak(Some(90.0));
let fresh = TextLayout::new(text, &style, Some(90.0));
assert_eq!(rebroken.size(), fresh.size());
assert_eq!(rebroken.line_count(), fresh.line_count());
assert_eq!(glyph_positions(&rebroken), glyph_positions(&fresh));
}
#[test]
fn rebreaking_at_max_content_matches_a_fresh_layout() {
setup();
let style = TextStyle::default();
let text = "words at several widths";
let mut rebroken = TextLayout::new(text, &style, Some(40.0));
rebroken.rebreak(None);
let fresh = TextLayout::new(text, &style, None);
assert_eq!(rebroken.size(), fresh.size());
assert_eq!(rebroken.line_count(), fresh.line_count(), "one line");
assert_eq!(glyph_positions(&rebroken), glyph_positions(&fresh));
}
#[test]
fn any_rebreak_sequence_matches_a_fresh_layout() {
setup();
let style = TextStyle::default();
let text = "several words of text that wrap at every width the engine \
could offer, some of them narrow and some of them wide";
proptest!(|(widths in proptest::collection::vec(1.0..300.0f32, 1..6))| {
let mut rebroken = TextLayout::new(text, &style, None);
for width in &widths {
rebroken.rebreak(Some(*width));
}
let last = widths[widths.len() - 1];
let fresh = TextLayout::new(text, &style, Some(last));
prop_assert_eq!(rebroken.size(), fresh.size());
prop_assert_eq!(rebroken.line_count(), fresh.line_count());
prop_assert_eq!(glyph_positions(&rebroken), glyph_positions(&fresh));
});
}
#[cfg(feature = "complex-scripts")]
#[test]
fn thai_without_spaces_wraps_between_words() {
setup();
let style = TextStyle::default();
let text = "ภาษาไทยเป็นภาษาที่ไม่มีการเว้นวรรคระหว่างคำ";
let width = TextLayout::new(text, &style, None).size().width;
let wrapped = TextLayout::new(text, &style, Some(width / 3.0));
assert!(wrapped.line_count() > 1);
assert!(wrapped.size().width <= width / 3.0);
}