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:
dotCooCoo
2026-11-13 07:12:59 -08:00
parent 6d0556e60f
commit 7f18643ada
2 changed files with 47 additions and 1 deletions
+24 -1
View File
@@ -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);
+23
View File
@@ -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();