mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-11 15:22:05 +00:00
Pass the runs' ordered flag with them to stay under the argument limit
This commit is contained in:
+19
-21
@@ -634,6 +634,13 @@ fn runs_ordered(runs: &[(Range<usize>, TextStyle)]) -> bool {
|
||||
runs.windows(2).all(|w| w[0].0.end <= w[1].0.start)
|
||||
}
|
||||
|
||||
/// Style runs with whether they are [`runs_ordered`].
|
||||
#[derive(Clone, Copy)]
|
||||
struct Runs<'a> {
|
||||
list: &'a [(Range<usize>, TextStyle)],
|
||||
ordered: bool,
|
||||
}
|
||||
|
||||
/// The style run index covering global byte `b` (the run before it at a boundary, for empty
|
||||
/// paragraphs at the end). `ordered` is [`runs_ordered`] of `runs`.
|
||||
fn run_at(runs: &[(Range<usize>, TextStyle)], ordered: bool, b: usize) -> usize {
|
||||
@@ -721,8 +728,7 @@ impl<'a> Para<'a> {
|
||||
fn new(
|
||||
text: &'a str,
|
||||
base: usize,
|
||||
runs: &'a [(Range<usize>, TextStyle)],
|
||||
ordered: bool,
|
||||
runs: Runs<'a>,
|
||||
primaries: &'a [Resolved],
|
||||
variation_ids: &'a [u32],
|
||||
para: &'a ParagraphStyle,
|
||||
@@ -731,8 +737,8 @@ impl<'a> Para<'a> {
|
||||
let default_level = para.rtl.map(|r| if r { Level::rtl() } else { Level::ltr() });
|
||||
let bidi = BidiInfo::new(text, default_level);
|
||||
let base_rtl = bidi.paragraphs[0].level.is_rtl();
|
||||
let chars = char_forms(text, base, runs, ordered, primaries, &bidi);
|
||||
let items = build_items(text, &chars, runs);
|
||||
let chars = char_forms(text, base, runs, primaries, &bidi);
|
||||
let items = build_items(text, &chars, runs.list);
|
||||
// Prefix widths and the preceding non-whitespace boundary make candidate line widths O(1).
|
||||
// Every-line composition evaluates O(n²) candidate breaks; summing each candidate's bytes
|
||||
// or rescanning its trailing whitespace would otherwise add another factor of text length.
|
||||
@@ -755,7 +761,7 @@ impl<'a> Para<'a> {
|
||||
}
|
||||
previous_non_ws[b + c.len_utf8()] = non_ws_end;
|
||||
}
|
||||
Para { text, base, runs, primaries, variation_ids, para, width, bidi, base_rtl, chars, items, char_adv, prefix_adv, previous_non_ws }
|
||||
Para { text, base, runs: runs.list, primaries, variation_ids, para, width, bidi, base_rtl, chars, items, char_adv, prefix_adv, previous_non_ws }
|
||||
}
|
||||
|
||||
fn range_w(&self, r: Range<usize>) -> f32 {
|
||||
@@ -1037,11 +1043,11 @@ impl<'a> Para<'a> {
|
||||
}
|
||||
|
||||
/// Each char with its shaped form, face, direction and run.
|
||||
fn char_forms(text: &str, base: usize, runs: &[(Range<usize>, TextStyle)], ordered: bool, primaries: &[Resolved], bidi: &BidiInfo) -> Vec<CharInfo> {
|
||||
fn char_forms(text: &str, base: usize, runs: Runs, primaries: &[Resolved], bidi: &BidiInfo) -> Vec<CharInfo> {
|
||||
text.char_indices()
|
||||
.map(|(b, c)| {
|
||||
let si = run_at(runs, ordered, base + b);
|
||||
let style = &runs[si].1;
|
||||
let si = run_at(runs.list, runs.ordered, base + b);
|
||||
let style = &runs.list[si].1;
|
||||
let primary = primaries[si].face;
|
||||
let face_of = |ch: char| if ch.is_whitespace() { primary } else { fonts::fallback_for(ch, primary) };
|
||||
let all_small = style.opentype.all_small_caps && style.caps != Caps::All;
|
||||
@@ -1095,18 +1101,9 @@ fn build_items(text: &str, chars: &[CharInfo], runs: &[(Range<usize>, TextStyle)
|
||||
items
|
||||
}
|
||||
|
||||
fn paragraph(
|
||||
text: &str,
|
||||
base: usize,
|
||||
runs: &[(Range<usize>, TextStyle)],
|
||||
ordered: bool,
|
||||
primaries: &[Resolved],
|
||||
variation_ids: &[u32],
|
||||
para: &ParagraphStyle,
|
||||
width: Option<f32>,
|
||||
) -> Vec<ParaLine> {
|
||||
fn paragraph(text: &str, base: usize, runs: Runs, primaries: &[Resolved], variation_ids: &[u32], para: &ParagraphStyle, width: Option<f32>) -> Vec<ParaLine> {
|
||||
if text.is_empty() {
|
||||
let si = run_at(runs, ordered, base);
|
||||
let (runs, si) = (runs.list, run_at(runs.list, runs.ordered, base));
|
||||
let pm = style_metrics(primaries, runs, si);
|
||||
// No text to resolve a direction from: the explicit one.
|
||||
let rtl = para.rtl == Some(true);
|
||||
@@ -1127,7 +1124,7 @@ fn paragraph(
|
||||
underline: None,
|
||||
}];
|
||||
}
|
||||
let p = Para::new(text, base, runs, ordered, primaries, variation_ids, para, width);
|
||||
let p = Para::new(text, base, runs, primaries, variation_ids, para, width);
|
||||
let ranges = p.break_ranges();
|
||||
let nlines = ranges.len();
|
||||
ranges.into_iter().enumerate().map(|(li, r)| p.place_line(li, r, li + 1 == nlines)).collect()
|
||||
@@ -1189,7 +1186,8 @@ pub fn layout_rich_uncached(text: &str, runs: &[(Range<usize>, TextStyle)], para
|
||||
let mut plines: Vec<(usize, ParaLine)> = Vec::new();
|
||||
for (pi, span) in paragraph_ranges(text).enumerate() {
|
||||
let p = text.get(span.bytes.clone()).unwrap_or_default();
|
||||
plines.extend(paragraph(p, span.bytes.start, runs, ordered, &primaries, &variation_ids, para_at(pi), width).into_iter().map(|l| (pi, l)));
|
||||
plines
|
||||
.extend(paragraph(p, span.bytes.start, Runs { list: runs, ordered }, &primaries, &variation_ids, para_at(pi), width).into_iter().map(|l| (pi, l)));
|
||||
}
|
||||
let mut baseline = 0.0f32;
|
||||
for (i, (pi, pl)) in plines.into_iter().enumerate() {
|
||||
|
||||
Reference in New Issue
Block a user