|
@@ -0,0 +1,67 @@
|
|
|
+use crate::{
|
|
|
+ bitmap::{BitmapDataMut, MakeMutView},
|
|
|
+ colour::Colour,
|
|
|
+ math::{PixelBox, PixelPoint, PixelSideOffsets},
|
|
|
+};
|
|
|
+
|
|
|
+use super::{GenericUnary, UnaryDispatch, UnaryOpSpec, KahloOps};
|
|
|
+
|
|
|
+pub struct RectangleOp;
|
|
|
+
|
|
|
+type Params<'l> = (PixelBox, usize, Colour);
|
|
|
+
|
|
|
+#[cfg(test)]
|
|
|
+const _ : () = {
|
|
|
+ use super::generate;
|
|
|
+ impl generate::UnaryInputSpec for RectangleOp {
|
|
|
+ fn gen<'l>() -> impl generate::ValueGeneratorList<'l, OutputTuple = Self::Params<'l>> {
|
|
|
+ (generate::dst_area, generate::uniform(1,5), generate::random_colour,)
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+impl UnaryOpSpec for RectangleOp {
|
|
|
+ type Params<'l> = Params<'l>;
|
|
|
+ fn build<'l>() -> UnaryDispatch<Self::Params<'l>> {
|
|
|
+ UnaryDispatch::from_generic::<Self>()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl<'l> GenericUnary<Params<'l>> for RectangleOp {
|
|
|
+ fn perform<Format: crate::formats::PixelFormatSpec>(
|
|
|
+ mut write_data: &mut dyn BitmapDataMut,
|
|
|
+ params: &Params<'l>,
|
|
|
+ ) {
|
|
|
+ // get a KahloOps for the image
|
|
|
+ let mut subregion = write_data.make_view_mut::<Format>(PixelBox::from_size(write_data.size()));
|
|
|
+ let (area, width, colour) = params;
|
|
|
+
|
|
|
+ let maxmin = PixelPoint::new(area.max.x, area.min.y);
|
|
|
+ let minmax = PixelPoint::new(area.min.x, area.max.y);
|
|
|
+
|
|
|
+ let width = (*width as i32) - 1;
|
|
|
+
|
|
|
+ // top side
|
|
|
+ subregion.fill_region(PixelBox::from_points([area.min, maxmin]).outer_box(PixelSideOffsets {
|
|
|
+ bottom: width,
|
|
|
+ ..Default::default()
|
|
|
+ }), *colour);
|
|
|
+ // bottom side
|
|
|
+ subregion.fill_region(PixelBox::from_points([minmax, area.max]).outer_box(PixelSideOffsets {
|
|
|
+ top: width,
|
|
|
+ ..Default::default()
|
|
|
+ }), *colour);
|
|
|
+
|
|
|
+ // left side
|
|
|
+ subregion.fill_region(PixelBox::from_points([area.min, minmax]).outer_box(PixelSideOffsets {
|
|
|
+ right: width,
|
|
|
+ ..Default::default()
|
|
|
+ }), *colour);
|
|
|
+ // right side
|
|
|
+ subregion.fill_region(PixelBox::from_points([maxmin, area.max]).outer_box(PixelSideOffsets {
|
|
|
+ left: width,
|
|
|
+ ..Default::default()
|
|
|
+ }), *colour);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|