From d5e58b0e4bb6962218f3933ed168b95f5f605efa Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Sat, 14 Nov 2026 07:46:17 -0800 Subject: [PATCH] Metafile import: a clip of several figures along a box's sides still clips A clip path is left out only when it is one rectangle around the whole picture. Two open figures along the top and bottom of a box enclose nothing, and the objects under such a clip are no longer imported unclipped. --- crates/metafile/src/import.rs | 9 ++++----- crates/metafile/src/tests/import.rs | 7 +++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/crates/metafile/src/import.rs b/crates/metafile/src/import.rs index 43023e0183..dce77b2d7a 100644 --- a/crates/metafile/src/import.rs +++ b/crates/metafile/src/import.rs @@ -44,8 +44,9 @@ fn sane(r: Rect) -> bool { [r.x0, r.y0, r.x1, r.y1].iter().all(|v| v.is_finite() && v.abs() <= LIMIT) } -/// Is `path` an upright rectangle around the whole of `frame`? Writers clip to one first; it clips -/// nothing in the picture. +/// Is `path` one upright rectangle around the whole of `frame`? Writers clip to one first; it clips +/// nothing in the picture. A path of more than one figure is not one rectangle, even when its +/// figures run along the sides of a box. fn around(path: &BezPath, frame: Rect) -> bool { if path.elements().len() > 6 { return false; @@ -67,9 +68,7 @@ fn around(path: &BezPath, frame: Rect) -> bool { }; let Some(i) = corners.iter().position(|c| near(*c, p)) else { return false }; if start { - if let (Some(f), Some(l)) = (first, last) - && !along(f, l) - { + if first.is_some() { return false; } first = Some(i); diff --git a/crates/metafile/src/tests/import.rs b/crates/metafile/src/tests/import.rs index 69abf02e86..4dcb3020c4 100644 --- a/crates/metafile/src/tests/import.rs +++ b/crates/metafile/src/tests/import.rs @@ -524,8 +524,11 @@ fn a_clip_whose_box_holds_the_picture_still_clips() { // A bow tie through the four corners of a box around the picture. let mut bow_tie = le(&[0, 0, 0, 0, 4]); bow_tie.extend(le(&[-500, -500, 5500, 3500, 5500, -500, -500, 3500])); - for clip in [diamond, bow_tie] { - let records = vec![(59, vec![]), (3, clip), (60, vec![]), (67, le(&[5])), (43, le(&[0, 0, 5000, 3000]))]; + // Two open figures through the four corners, the top edge and the bottom edge, which enclose + // nothing: MOVETOEX, LINETO, MOVETOEX, LINETO. + let edges = vec![(27, le(&[-500, -500])), (54, le(&[5500, -500])), (27, le(&[5500, 3500])), (54, le(&[-500, 3500]))]; + for clip in [vec![(3, diamond)], vec![(3, bow_tie)], edges] { + let records = [vec![(59, vec![])], clip, vec![(60, vec![]), (67, le(&[5])), (43, le(&[0, 0, 5000, 3000]))]].concat(); let back = import(&hand_emf(5000, 3000, &records)).unwrap(); let layer = back.document.layers[0].children().unwrap(); assert_eq!(layer.len(), 1);