diff --git a/crates/render/src/hatch.rs b/crates/render/src/hatch.rs index 880322fb5..6b96d70ca 100644 --- a/crates/render/src/hatch.rs +++ b/crates/render/src/hatch.rs @@ -510,6 +510,12 @@ impl Family<'_> { /// Intersect a pattern family with boundary loops, respecting view, output, cancellation, and shared dash-work limits. fn sweep(&self, loops: &[Vec], px: f64, view: Option<&Bounds2>, cancel: Option<&AtomicBool>, out: &mut Vec>, work: &mut u64) { + // Transforming the boundary is charged before it is done, at the scanline rate (one unit per 8 vertices). + let verts: u64 = loops.iter().map(|l| l.len() as u64).sum(); + if *work == 0 { + return; + } + *work = work.saturating_sub(verts / 8 + 1); let local: Vec> = loops.iter().map(|l| l.iter().map(|p| self.to_local(*p)).collect()).collect(); let bb = Bounds2::from_points(local.iter().flatten().copied()); if bb.is_empty() { diff --git a/crates/render/src/linetype_text.rs b/crates/render/src/linetype_text.rs index 8770eb087..84293ba5f 100644 --- a/crates/render/src/linetype_text.rs +++ b/crates/render/src/linetype_text.rs @@ -102,7 +102,13 @@ fn elements(d: &Drawing, lt: &Linetype, scale: f64) -> Vec { }; let (local, _) = cadcraft_fonts::place(&font, text, ¶ms); let finite = |v: f64| if v.is_finite() { v } else { 0.0 }; - let points = local.strokes.iter().map(Vec::len).sum::() + local.glyphs.iter().flatten().map(Vec::len).sum::(); + // Points plus one per stroke and glyph slot, and one for the label itself, so a label of empty + // glyphs still has a cost proportional to its size. + let points = local.strokes.iter().map(Vec::len).sum::() + + local.glyphs.iter().flatten().map(Vec::len).sum::() + + local.strokes.len() + + local.glyphs.len() + + 1; out.push(Element { at, points,