From db85d465c8f7671a1e27d269e4ef505ec96860ab Mon Sep 17 00:00:00 2001 From: bflatastic Date: Tue, 13 Oct 2026 09:27:32 +0700 Subject: [PATCH] SVG import: flowed text with a region too large to place is left out with a warning --- crates/svg/src/import/text.rs | 5 +++++ crates/svg/tests/import_text.rs | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/crates/svg/src/import/text.rs b/crates/svg/src/import/text.rs index 32dbde6c..8ddd0f05 100644 --- a/crates/svg/src/import/text.rs +++ b/crates/svg/src/import/text.rs @@ -594,6 +594,11 @@ impl Ctx { obj.xf = parse_transform(r.attribute("transform")) * origin; let servers = vec![(None, None); obj.runs.len()]; let b = obj.xf.transform_rect_bbox(frame); + // A size, place or transform past what numbers hold (`width="1e999"`) has no frame to set type in. + if ![b.x0, b.y0, b.x1, b.y1].iter().all(|v| v.is_finite()) { + warnings.push(format!("{label}: flowed text (flowRoot) with a region too large to place was left out")); + return None; + } let marker = Rect::new(b.x0, b.y0, b.x1.max(b.x0 + 1.0), b.y1.max(b.y0 + 1.0)); let name = t.attribute("id").unwrap_or("").to_string(); Some((PendingText { name, obj, servers, paints: 0, non_scaling: false, under: None, marker }, Vec::new())) diff --git a/crates/svg/tests/import_text.rs b/crates/svg/tests/import_text.rs index 3d587a56..4d862b58 100644 --- a/crates/svg/tests/import_text.rs +++ b/crates/svg/tests/import_text.rs @@ -612,3 +612,20 @@ fn flowed_text_becomes_area_type() { assert!(close(t.runs[0].style.size * t.xf.determinant().abs().sqrt(), 16.0, 1e-6)); assert!(w.iter().any(|w| w.contains("flowRoot")), "{w:?}"); } + +/// Flowed text that can't be read is left out with a warning each, and never stops the import: no +/// region, a region too large for numbers, a flowRoot inside a flowRoot (read once, as the outer one). +#[test] +fn flowed_text_that_cannot_be_read_is_reported() { + let (d, w) = import_with_report(&svg( + r#"No region + Huge + Far + Outerinner"#, + )) + .unwrap(); + assert_eq!(only_text(&d).plain_text(), "Outer\ninner"); + for id in ["none", "huge", "far"] { + assert!(w.iter().any(|w| w.contains(id) && w.contains("flowRoot")), "{id}: {w:?}"); + } +}