mod image_raw;
pub use self::image_raw::{ImageRaw, ImageRawBE, ImageRawLE};
use crate::{
draw_target::DrawTarget,
drawable::{Drawable, Pixel},
geometry::{Dimensions, Point, Size},
pixelcolor::PixelColor,
transform::Transform,
};
use core::fmt::Debug;
use core::{fmt, marker::PhantomData};
pub trait IntoPixelIter<C>
where
C: PixelColor + From<<C as PixelColor>::Raw>,
{
type PixelIterator: Iterator<Item = Pixel<C>>;
fn pixel_iter(self) -> Self::PixelIterator;
}
pub trait ImageDimensions {
fn width(&self) -> u32;
fn height(&self) -> u32;
}
#[derive(Debug, Clone, Copy)]
pub struct Image<'a, I, C> {
image_data: &'a I,
offset: Point,
c: PhantomData<C>,
}
impl<'a, I, C> Image<'a, I, C>
where
&'a I: IntoPixelIter<C>,
I: ImageDimensions,
C: PixelColor + From<<C as PixelColor>::Raw>,
{
pub fn new(image_data: &'a I, position: Point) -> Self {
Self {
image_data,
offset: position,
c: PhantomData,
}
}
}
impl<I, C> Transform for Image<'_, I, C> {
fn translate(&self, by: Point) -> Self {
Self {
image_data: self.image_data,
offset: self.offset + by,
c: PhantomData,
}
}
fn translate_mut(&mut self, by: Point) -> &mut Self {
self.offset += by;
self
}
}
impl<'a, 'b, I, C> Drawable<C> for &'a Image<'b, I, C>
where
&'b I: IntoPixelIter<C>,
I: ImageDimensions,
C: PixelColor + From<<C as PixelColor>::Raw>,
{
fn draw<D: DrawTarget<C>>(self, display: &mut D) -> Result<(), D::Error> {
display.draw_image(self)
}
}
impl<'a, I, C> Dimensions for Image<'a, I, C>
where
I: ImageDimensions,
C: PixelColor + From<<C as PixelColor>::Raw>,
{
fn top_left(&self) -> Point {
self.offset
}
fn bottom_right(&self) -> Point {
self.top_left() + self.size()
}
fn size(&self) -> Size {
Size::new(self.image_data.width(), self.image_data.height())
}
}
impl<'a, 'b, I, C> IntoIterator for &'a Image<'b, I, C>
where
&'b I: IntoPixelIter<C>,
C: PixelColor + From<<C as PixelColor>::Raw>,
{
type Item = Pixel<C>;
type IntoIter = ImageIterator<'a, 'b, I, C>;
fn into_iter(self) -> Self::IntoIter {
ImageIterator {
it: self.image_data.pixel_iter(),
image: self,
}
}
}
pub struct ImageIterator<'a, 'b, I, C>
where
&'b I: IntoPixelIter<C>,
C: PixelColor + From<<C as PixelColor>::Raw>,
{
image: &'a Image<'b, I, C>,
it: <&'b I as IntoPixelIter<C>>::PixelIterator,
}
impl<'a, 'b, I, C> Debug for ImageIterator<'a, 'b, I, C>
where
&'b I: IntoPixelIter<C> + Debug,
<&'b I as IntoPixelIter<C>>::PixelIterator: Debug,
I: Debug,
C: PixelColor + From<<C as PixelColor>::Raw> + Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ImageIterator")
.field("image", &self.image)
.field("it", &self.it)
.finish()
}
}
impl<'a, 'b, I, C> Iterator for ImageIterator<'a, 'b, I, C>
where
&'b I: IntoPixelIter<C>,
C: PixelColor + From<<C as PixelColor>::Raw>,
{
type Item = Pixel<C>;
fn next(&mut self) -> Option<Self::Item> {
self.it.next().map(|p| Pixel(p.0 + self.image.offset, p.1))
}
}