|
@@ -16,8 +16,45 @@ pub trait Writable<PF: PixelFormat>: Readable<PF> {
|
|
fn set_pixel(&mut self, x: usize, y: usize, to: Self::ReadResult);
|
|
fn set_pixel(&mut self, x: usize, y: usize, to: Self::ReadResult);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+pub trait AlphaPaintable: BitmapMutAccess<A8> + Writable<A8, ReadResult = u8> {
|
|
|
|
+ fn fill(&mut self, with: u8) {
|
|
|
|
+ self.data_mut().fill(with);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fn copy_from(
|
|
|
|
+ &mut self,
|
|
|
|
+ amap: &impl BitmapAccess<A8>,
|
|
|
|
+ amap_region: &math::PixelBox,
|
|
|
|
+ dst: &math::PixelPoint,
|
|
|
|
+ ) {
|
|
|
|
+ let Some((write_region, read_region)) = helpers::clip_to(
|
|
|
|
+ self.size(),
|
|
|
|
+ *dst,
|
|
|
|
+ amap.size(),
|
|
|
|
+ amap_region.min,
|
|
|
|
+ amap_region.size(),
|
|
|
|
+ ) else {
|
|
|
|
+ return;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ let row_width = write_region.width() as usize * A8::PIXEL_WIDTH;
|
|
|
|
+ for y in 0..write_region.height() {
|
|
|
|
+ let write_offset = ((y + write_region.min.y) * self.row_stride() as i32) as usize;
|
|
|
|
+ let read_offset = ((y + read_region.min.y) * amap.row_stride() as i32) as usize;
|
|
|
|
+
|
|
|
|
+ let write_offset = write_offset + write_region.min.x as usize;
|
|
|
|
+ let read_offset = read_offset + read_region.min.x as usize;
|
|
|
|
+
|
|
|
|
+ self.data_mut()[write_offset..(write_offset + row_width)]
|
|
|
|
+ .copy_from_slice(&amap.data()[read_offset..(read_offset + row_width)]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+impl<T: BitmapMutAccess<A8>> AlphaPaintable for T {}
|
|
|
|
+
|
|
/// RGBA32-specific painting struct.
|
|
/// RGBA32-specific painting struct.
|
|
-pub trait Paintable:
|
|
|
|
|
|
+pub trait RgbaPaintable:
|
|
BitmapAccess<Rgba32> + BitmapMutAccess<Rgba32> + Writable<Rgba32, ReadResult = Colour>
|
|
BitmapAccess<Rgba32> + BitmapMutAccess<Rgba32> + Writable<Rgba32, ReadResult = Colour>
|
|
{
|
|
{
|
|
/// Fill the entire image with a given colour.
|
|
/// Fill the entire image with a given colour.
|
|
@@ -54,9 +91,13 @@ pub trait Paintable:
|
|
col: Colour,
|
|
col: Colour,
|
|
mode: BlendMode,
|
|
mode: BlendMode,
|
|
) {
|
|
) {
|
|
- let Some((write_box, read_box)) =
|
|
|
|
- helpers::clip_to(self.size(), *dst, amap.size(), amap_region.min, amap_region.size())
|
|
|
|
- else {
|
|
|
|
|
|
+ let Some((write_box, read_box)) = helpers::clip_to(
|
|
|
|
+ self.size(),
|
|
|
|
+ *dst,
|
|
|
|
+ amap.size(),
|
|
|
|
+ amap_region.min,
|
|
|
|
+ amap_region.size(),
|
|
|
|
+ ) else {
|
|
return;
|
|
return;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -67,7 +108,8 @@ pub trait Paintable:
|
|
let wx = (write_box.min.x + x) as usize;
|
|
let wx = (write_box.min.x + x) as usize;
|
|
let wy = (write_box.min.y + y) as usize;
|
|
let wy = (write_box.min.y + y) as usize;
|
|
let source = col.with_a(amap.get_pixel(rx, ry));
|
|
let source = col.with_a(amap.get_pixel(rx, ry));
|
|
- self.set_pixel(wx, wy, mode.blend(&self.get_pixel(wx, wy), &source));
|
|
|
|
|
|
+ let blended = mode.blend(&source, &self.get_pixel(wx, wy));
|
|
|
|
+ self.set_pixel(wx, wy, blended);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -118,4 +160,4 @@ pub trait Paintable:
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-impl<T: BitmapMutAccess<Rgba32>> Paintable for T {}
|
|
|
|
|
|
+impl<T: BitmapMutAccess<Rgba32>> RgbaPaintable for T {}
|