use pdfrum_doc::vt::{Config, Metrics};
use pdfrum_form::edit::ops::{self, TextEdit};
fn metrics() -> Metrics<'static> {
Metrics {
width: &|_| 500,
ascent: 905,
descent: -211,
}
}
fn config() -> Config {
Config {
plate: kurbo::Rect::new(1.0, 1.0, 99.0, 29.0),
font_size: 12.0,
..Config::default()
}
}
const HEBREW: &str = "\u{5d1}\u{5d7}\u{5e8}";
const HEBREW_LINE: &str = "\u{5d1}\u{5d7}\u{5e8}... \u{5d0}\u{5d2}\u{5ea}";
fn bands_of(text: &str) -> Vec<kurbo::Rect> {
let (config, metrics) = (config(), metrics());
let mut edit = TextEdit::new(text, &config, &metrics, true);
edit.select_all();
ops::highlight(&edit, &config, &metrics, 0.4).selection
}
fn span(bands: &[kurbo::Rect]) -> (f64, f64) {
bands.iter().fold((f64::MAX, f64::MIN), |acc, r| {
(acc.0.min(r.x0), acc.1.max(r.x1))
})
}
#[test]
fn a_left_to_right_selection_spans_its_whole_run() {
let bands = bands_of("abc... def");
let (left, right) = span(&bands);
assert!((left - 1.0).abs() < 0.01, "starts at the plate's left edge");
assert!(
(right - left - 60.0).abs() < 0.01,
"ten characters at six units, got {}",
right - left
);
}
#[test]
fn a_right_to_left_selection_spans_its_whole_run_too() {
let bands = bands_of(HEBREW_LINE);
let (left, right) = span(&bands);
assert!(
(right - left - 60.0).abs() < 0.01,
"ten characters at six units, got {} — a run that collapses here is \
the direction bug this file exists for",
right - left
);
}
#[test]
fn the_two_directions_cover_equal_widths() {
let (ltr_left, ltr_right) = span(&bands_of("abc"));
let (rtl_left, rtl_right) = span(&bands_of(HEBREW));
assert!((ltr_right - ltr_left - 18.0).abs() < 0.01);
assert!(
((rtl_right - rtl_left) - (ltr_right - ltr_left)).abs() < 0.01,
"three characters cover three characters' width either way"
);
}
#[test]
fn a_contiguous_left_to_right_run_merges_into_one_band() {
assert_eq!(bands_of("abc... def").len(), 1);
}
#[test]
fn an_empty_selection_paints_no_bands() {
let (config, metrics) = (config(), metrics());
let edit = TextEdit::new("abc", &config, &metrics, true);
let highlight = ops::highlight(&edit, &config, &metrics, 0.4);
assert!(highlight.selection.is_empty());
assert!(
highlight.caret.is_some(),
"and a field with no selection shows a caret instead"
);
}
#[test]
fn a_selection_across_a_line_break_is_two_bands() {
let mut config = config();
config.multi_line = true;
config.auto_return = true;
let metrics = metrics();
let mut edit = TextEdit::new("abc\ndef", &config, &metrics, false);
edit.select_all();
let bands = ops::highlight(&edit, &config, &metrics, 0.4).selection;
assert_eq!(bands.len(), 2, "one band per line, got {bands:?}");
let (first, second) = (bands[0], bands[1]);
assert!(
(first.y0 - second.y0).abs() > 0.01,
"the two bands must sit on different lines"
);
}