diff --git a/crates/metafile/src/cliprect.rs b/crates/metafile/src/cliprect.rs index 8290dd379..396f44025 100644 --- a/crates/metafile/src/cliprect.rs +++ b/crates/metafile/src/cliprect.rs @@ -143,10 +143,10 @@ fn bbox_inside(b: [f64; 4], clip: &[P]) -> bool { pub(crate) fn clip_raw(raw: Raw, clip: &[P]) -> Vec { let Some(cb) = pts_bbox(clip).filter(|_| clip.len() >= 3) else { return Vec::new() }; match raw { - Raw::Path { ops, fill, stroke, even_odd } => { + Raw::Path { ops, fill, stroke, even_odd, region } => { let Some(b) = ops_bbox(&ops) else { return Vec::new() }; if bbox_inside(b, clip) { - return vec![Raw::Path { ops, fill, stroke, even_odd }]; + return vec![Raw::Path { ops, fill, stroke, even_odd, region }]; } if disjoint(b, cb) { return Vec::new(); @@ -156,34 +156,34 @@ pub(crate) fn clip_raw(raw: Raw, clip: &[P]) -> Vec { if fill.is_some() { let f = clip_fill(&subs, clip); if !f.is_empty() { - out.push(Raw::Path { ops: f, fill, stroke: None, even_odd }); + out.push(Raw::Path { ops: f, fill, stroke: None, even_odd, region: region.clone() }); } } if stroke.is_some() { let s = clip_stroke(&subs, clip); if !s.is_empty() { - out.push(Raw::Path { ops: s, fill: None, stroke, even_odd }); + out.push(Raw::Path { ops: s, fill: None, stroke, even_odd, region }); } } out } - Raw::Pattern { ops, even_odd, tile } => { + Raw::Pattern { ops, even_odd, tile, region } => { let Some(b) = ops_bbox(&ops) else { return Vec::new() }; if bbox_inside(b, clip) { - return vec![Raw::Pattern { ops, even_odd, tile }]; + return vec![Raw::Pattern { ops, even_odd, tile, region }]; } if disjoint(b, cb) { return Vec::new(); } let f = clip_fill(&flatten(&ops), clip); - if f.is_empty() { Vec::new() } else { vec![Raw::Pattern { ops: f, even_odd, tile }] } + if f.is_empty() { Vec::new() } else { vec![Raw::Pattern { ops: f, even_odd, tile, region }] } } - Raw::Bitmap { rect, img } => crop(rect, img, clip).map(|(rect, img)| vec![Raw::Bitmap { rect, img }]).unwrap_or_default(), - Raw::Text(mut t) => { + Raw::Bitmap { rect, img, region } => crop(rect, img, clip).map(|(rect, img)| vec![Raw::Bitmap { rect, img, region }]).unwrap_or_default(), + Raw::Text { text: mut t, region } => { // Text clips to a rectangle: the one around the polygon. let cur = t.clip.map_or(cb, |[a, b, d, e]| intersect(cb, [f64::from(a), f64::from(b), f64::from(d), f64::from(e)])); t.clip = Some(cur.map(|v| v as f32)); - vec![Raw::Text(t)] + vec![Raw::Text { text: t, region }] } } } diff --git a/crates/metafile/src/emfplus.rs b/crates/metafile/src/emfplus.rs index a8c937759..fb757b638 100644 --- a/crates/metafile/src/emfplus.rs +++ b/crates/metafile/src/emfplus.rs @@ -737,15 +737,21 @@ impl Painter { }) .collect() }; + // The nested picture's own clip regions are not carried over: each item takes the + // canvas's current clip. for item in &pic.items { if cv.full() { break; } let raw = match item { - Item::Path { segs, fill, stroke, even_odd } => { - Raw::Path { ops: ops(segs), fill: *fill, stroke: stroke.map(|(c, w)| (c, f64::from(w) * scale)), even_odd: *even_odd } - } - Item::Pattern { segs, even_odd, tile } => Raw::Pattern { + Item::Path { segs, fill, stroke, even_odd, .. } => Raw::Path { + ops: ops(segs), + fill: *fill, + stroke: stroke.map(|(c, w)| (c, f64::from(w) * scale)), + even_odd: *even_odd, + region: None, + }, + Item::Pattern { segs, even_odd, tile, .. } => Raw::Pattern { ops: ops(segs), even_odd: *even_odd, tile: Arc::new(RawTile { @@ -754,12 +760,13 @@ impl Painter { px: tile.rgba.clone(), cell: f64::from(tile.cell[0]) * scale, }), + region: None, }, - Item::Bitmap { rect, width, height, rgba } => { + Item::Bitmap { rect, width, height, rgba, .. } => { let (a, b) = (pt(rect[0], rect[1]), pt(rect[0] + rect[2], rect[1] + rect[3])); let mut img = Rgba { w: *width as usize, h: *height as usize, bottom_up: false, px: rgba.clone() }; crate::dib::flip(&mut img, a.0 > b.0, a.1 > b.1); - Raw::Bitmap { rect: [a.0.min(b.0), a.1.min(b.1), (b.0 - a.0).abs(), (b.1 - a.1).abs()], img } + Raw::Bitmap { rect: [a.0.min(b.0), a.1.min(b.1), (b.0 - a.0).abs(), (b.1 - a.1).abs()], img, region: None } } Item::Text(t) => { let mut t = t.clone(); @@ -768,7 +775,7 @@ impl Painter { let (p, q) = (pt(x0, y0), pt(x1, y1)); t.clip = Some([p.0.min(q.0) as f32, p.1.min(q.1) as f32, p.0.max(q.0) as f32, p.1.max(q.1) as f32]); } - Raw::Text(t) + Raw::Text { text: t, region: None } } }; cv.push_device(raw);