1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Copyright (c) 2017, Marty Mills <daggerbot@gmail.com>
// This software is available under the terms of the zlib license.
// See COPYING.md for more information.

use bounds::{Boundless, Bounds, Size2};
use vec_image::VecImage2;

/// Raster image trait.
pub trait Image<'a> {
    type Bounds : Bounds<Index = Self::Index>;
    type Index;
    type Pixel : 'a;

    fn bounds (&'a self) -> &'a Self::Bounds;
    fn pixel (&'a self, index: Self::Index) -> Self::Pixel;

    fn render<O> (&'a self) -> O
        where O: Render<'a, Self>
    {
        O::render_from(self)
    }

    fn render_vec2<T> (&'a self) -> VecImage2<T>
        where VecImage2<T>: Render<'a, Self>
    {
        VecImage2::render_from(self)
    }

    fn with_size2<S, I> (self, size: S) -> Bounded<Self, Size2<I>>
        where Self: Sized,
              S: Into<Size2<I>>
    {
        Bounded { parent: self, bounds: size.into() }
    }
}

/// Imposes boundaries on a boundless image.
pub struct Bounded<P, B> {
    parent: P,
    bounds: B,
}

impl<'a, P, B, T, I> Image<'a> for Bounded<P, B>
    where P: Image<'a, Bounds = Boundless<I>, Index = I, Pixel = T>,
          B: Bounds<Index = I>,
          T: 'a,
{
    type Bounds = B;
    type Index = I;
    type Pixel = T;

    fn bounds (&'a self) -> &'a B { &self.bounds }
    fn pixel (&'a self, index: I) -> T { self.parent.pixel(index) }
}

/// Unbounded image which returns the same value at any index.
pub struct Fill<T, I> {
    bounds: Boundless<I>,
    pixel: T,
}

impl<'a, T, I> Image<'a> for Fill<T, I>
    where T: 'a + Copy
{
    type Bounds = Boundless<I>;
    type Index = I;
    type Pixel = T;

    fn bounds (&'a self) -> &Boundless<I> { &self.bounds }
    fn pixel (&'a self, _: I) -> T { self.pixel }
}

/// Renders a value from an image.
pub trait Render<'a, I: ?Sized> {
    fn render_from (image: &'a I) -> Self;
}

/// Constructs a `Fill`.
pub fn fill<T, I> (pixel: T) -> Fill<T, I> {
    Fill { bounds: Boundless::new(), pixel }
}