use super::*; use guiduck_scene::paint::color::palette::css; use guiduck_scene::paint::{Blob, ImageAlphaType, ImageData, ImageFormat}; fn image(w: u32, h: u32) -> Graphic { Graphic::Image(ImageBrush::from(ImageData { data: Blob::new(std::sync::Arc::new(vec![0u8; (w * h * 4) as usize])), format: ImageFormat::Rgba8, alpha_type: ImageAlphaType::Alpha, width: w, height: h, })) } fn unit_square() -> Graphic { Graphic::from_path_cmds(&[ PathCmd::Move(0.0, 0.0), PathCmd::Line(1.0, 0.0), PathCmd::Line(1.0, 1.0), PathCmd::Close, ]) } #[test] fn only_an_image_has_a_natural_size() { assert_eq!(image(40, 20).natural_size(), Some(Size::new(40.0, 20.0))); // Scale-free geometry has no size to report; inventing one would be a // lie, so a path must be given a box. assert_eq!(unit_square().natural_size(), None); } #[test] fn a_path_scales_into_its_target_rect() { let mut fragment = Fragment::default(); unit_square().paint_into( &mut fragment, Rect::new(10.0, 20.0, 30.0, 60.0), &GraphicPaint::Fill(css::BLACK.into()), ); let items = &fragment.items; assert_eq!(items.len(), 1); let guiduck_scene::DisplayItem::Fill { shape, .. } = &items[0] else { panic!("expected a fill, got {:?}", items[0]); }; // The unit square lands exactly on the rect: translated to its origin and // scaled non-uniformly to its extent. let bounds = shape.bounding_box(); assert_eq!((bounds.x0, bounds.y0), (10.0, 20.0)); assert_eq!((bounds.x1, bounds.y1), (30.0, 60.0)); } #[test] fn an_image_fills_its_target_rect() { let mut fragment = Fragment::default(); let rect = Rect::new(0.0, 0.0, 32.0, 32.0); // The paint is a path's business; an image carries its own pixels and // must ignore it rather than tint or refuse. image(16, 16).paint_into( &mut fragment, rect, &GraphicPaint::Stroke(css::RED.into(), 4.0), ); let items = &fragment.items; assert_eq!(items.len(), 1); let guiduck_scene::DisplayItem::Image { dest, .. } = &items[0] else { panic!("expected an image, got {:?}", items[0]); }; assert_eq!(dest, &rect, "a 16x16 image scales into a 32x32 box"); } #[test] fn an_empty_rect_draws_nothing() { let mut fragment = Fragment::default(); let empty = Rect::new(5.0, 5.0, 5.0, 5.0); unit_square().paint_into(&mut fragment, empty, &GraphicPaint::Fill(css::BLACK.into())); image(16, 16).paint_into(&mut fragment, empty, &GraphicPaint::Fill(css::BLACK.into())); assert!(fragment.items.is_empty()); }