mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-27 20:16:50 -06:00
Fix up merged PRs: EMF+ clipping alongside GDI clip regions
main added its own clip.rs (GDI rectangle regions carried on every drawn item); #582 added a clip.rs that cuts drawing geometrically to the EMF+ clip rectangle. Keep main's module, move #582's to cliprect.rs, keep the EMF+ rectangle on the canvas as plus_clip, and carry the region field through the geometric clipper. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
eab5686393
commit
3450180f19
@@ -536,7 +536,7 @@ impl Canvas {
|
||||
let dev: Vec<Op> = ops.iter().map(|o| self.map_op(*o)).collect();
|
||||
if dev.len() >= 2 {
|
||||
let even_odd = self.even_odd;
|
||||
self.push(Raw::Pattern { ops: dev, even_odd, tile });
|
||||
self.push(Raw::Pattern { ops: dev, even_odd, tile, region: None });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -564,7 +564,7 @@ impl Canvas {
|
||||
}
|
||||
}
|
||||
let even_odd = self.even_odd;
|
||||
self.push(Raw::Pattern { ops: dev, even_odd, tile: Arc::new(RawTile { w, h, px, cell }) });
|
||||
self.push(Raw::Pattern { ops: dev, even_odd, tile: Arc::new(RawTile { w, h, px, cell }), region: None });
|
||||
}
|
||||
|
||||
/// Pushes the drawing state. Past [`MAX_STACK`] levels the parse stops, since later restores
|
||||
|
||||
@@ -48,10 +48,10 @@ fn disjoint(b: [f64; 4], c: [f64; 4]) -> bool {
|
||||
/// Clips one drawn item; a shape that is both filled and stroked comes back as two items.
|
||||
pub(crate) fn clip_raw(raw: Raw, c: [f64; 4]) -> Vec<Raw> {
|
||||
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 inside(b, c) {
|
||||
return vec![Raw::Path { ops, fill, stroke, even_odd }];
|
||||
return vec![Raw::Path { ops, fill, stroke, even_odd, region }];
|
||||
}
|
||||
if disjoint(b, c) {
|
||||
return Vec::new();
|
||||
@@ -61,33 +61,33 @@ pub(crate) fn clip_raw(raw: Raw, c: [f64; 4]) -> Vec<Raw> {
|
||||
if fill.is_some() {
|
||||
let f = clip_fill(&subs, c);
|
||||
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, c);
|
||||
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 inside(b, c) {
|
||||
return vec![Raw::Pattern { ops, even_odd, tile }];
|
||||
return vec![Raw::Pattern { ops, even_odd, tile, region }];
|
||||
}
|
||||
if disjoint(b, c) {
|
||||
return Vec::new();
|
||||
}
|
||||
let f = clip_fill(&flatten(&ops), c);
|
||||
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, c).map(|(rect, img)| vec![Raw::Bitmap { rect, img }]).unwrap_or_default(),
|
||||
Raw::Text(mut t) => {
|
||||
Raw::Bitmap { rect, img, region } => crop(rect, img, c).map(|(rect, img)| vec![Raw::Bitmap { rect, img, region }]).unwrap_or_default(),
|
||||
Raw::Text { text: mut t, region } => {
|
||||
let cur = t.clip.map_or(c, |[a, b, d, e]| intersect(c, [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 }]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1733,7 +1733,7 @@ fn draw_image(id: u16, dst: [f32; 4]) -> Vec<u8> {
|
||||
fn emfplus_draw_image_places_the_bitmap() {
|
||||
let p = plus_pic(vec![prec(0x4008, 0x0500 | 4, &bitmap_2x2()), draw_image(4, [10.0, 10.0, 20.0, 40.0])]);
|
||||
match &p.items[0] {
|
||||
Item::Bitmap { rect, width, height, rgba } => {
|
||||
Item::Bitmap { rect, width, height, rgba, .. } => {
|
||||
assert_eq!((*width, *height), (2, 2));
|
||||
assert_eq!(rect, &[0.0, 0.0, 20.0, 40.0]);
|
||||
assert_eq!(&rgba[..8], &[255, 0, 0, 255, 0, 255, 0, 255]);
|
||||
|
||||
Reference in New Issue
Block a user