mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-13 21:17:48 +00:00
Type: measuring a threaded frame copies its own text once
Each measurement of a frame's share started from a copy of the whole frame, its own runs included, and then replaced the runs. The frame is now copied once without its own text, and each measurement copies that. A test counts the frame text copied to measure frames that already hold text.
This commit is contained in:
@@ -96,6 +96,25 @@ fn fit_bytes() -> usize {
|
||||
FIT_BYTES.get()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
thread_local! {
|
||||
/// The bytes of frames' own text copied on this thread to measure them ([`probe_copied`]).
|
||||
static PROBE_COPIED: std::cell::Cell<usize> = const { std::cell::Cell::new(0) };
|
||||
}
|
||||
|
||||
/// The bytes of frames' own text copied on this thread to measure them.
|
||||
#[cfg(test)]
|
||||
fn probe_copied() -> usize {
|
||||
PROBE_COPIED.get()
|
||||
}
|
||||
|
||||
/// A copy of `frame` to measure text in, its own text counted as copied ([`probe_copied`]).
|
||||
fn copy_to_measure(frame: &TextObject) -> TextObject {
|
||||
#[cfg(test)]
|
||||
PROBE_COPIED.set(PROBE_COPIED.get() + runs_len(&frame.runs));
|
||||
frame.clone()
|
||||
}
|
||||
|
||||
/// The fewest bytes of story a frame is measured with before the measured text grows.
|
||||
const MIN_MEASURE: usize = 512;
|
||||
|
||||
@@ -372,8 +391,12 @@ pub fn distribute_continuing_levels(
|
||||
let n = if i + 1 == frames.len() {
|
||||
len
|
||||
} else {
|
||||
// The frame without its own text, copied once and then for each measurement.
|
||||
let mut base = copy_to_measure(f);
|
||||
base.runs = Vec::new();
|
||||
base.paras = Vec::new();
|
||||
let probe = |runs: Vec<TextRun>| {
|
||||
let mut probe = (*f).clone();
|
||||
let mut probe = copy_to_measure(&base);
|
||||
let styles = slice_paras(paras, first_para, &runs);
|
||||
probe.runs = runs;
|
||||
probe.set_paragraph_styles(styles);
|
||||
|
||||
@@ -682,6 +682,29 @@ fn many_frames_measure_about_the_text_they_take() {
|
||||
assert!(measured <= bound, "measured {measured} bytes for {placed} placed in {} frames (at most {bound})", frames.len());
|
||||
}
|
||||
|
||||
/// Frames that already hold text and take a story over several measurements each: each frame's own
|
||||
/// text is copied once to measure it, not once for each measurement.
|
||||
#[test]
|
||||
fn frames_with_text_copy_it_once_to_measure_it() {
|
||||
let db = FontDb::global();
|
||||
let text = paragraphs(600);
|
||||
let story = vec![TextRun::new(text.clone(), CharStyle::default())];
|
||||
let mut frames: Vec<TextObject> = (0..4).map(|k| sized(400.0 * k as f64, 300.0, 600.0)).collect();
|
||||
for f in &mut frames {
|
||||
f.runs = vec![TextRun::new("Old text. ".repeat(500), CharStyle::default())];
|
||||
}
|
||||
let refs: Vec<&TextObject> = frames.iter().collect();
|
||||
let (fit_before, copied_before) = (fit_bytes(), probe_copied());
|
||||
let parts = distribute(db, &refs, &story, &[]);
|
||||
let (measured, copied) = (fit_bytes() - fit_before, probe_copied() - copied_before);
|
||||
let joined: String = parts.iter().flat_map(|p| &p.runs).map(|r| r.text.as_str()).collect();
|
||||
assert_eq!(joined, text, "no character lost or duplicated");
|
||||
let first = runs_len(&parts[0].runs);
|
||||
assert!(measured > 2 * first, "the first frame is measured more than once: {measured} bytes for {first}");
|
||||
let own: usize = frames[..frames.len() - 1].iter().map(|f| runs_len(&f.runs)).sum();
|
||||
assert_eq!(copied, own, "each frame before the last copies its own text once to measure it");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_story_leaves_later_frames_empty_with_a_style() {
|
||||
let db = FontDb::global();
|
||||
|
||||
Reference in New Issue
Block a user