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
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright (c) 2016-2017 <daggerbot@gmail.com>
// This software is available under the terms of the zlib license.
// See COPYING.md for more information.

use numeric::{Clamp, ClampError, ClampFrom, Lerp};

/// Luminance color structure.
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))]
pub struct Lum<T> (pub T);

impl<T> Lum<T> {
    #[inline(always)]
    pub fn luminance (self) -> T { self.0 }

    pub fn with_alpha (self, alpha: T) -> LumAlpha<T> {
        LumAlpha(self.0, alpha)
    }
}

impl<F, T: ClampFrom<F>> ClampFrom<Lum<F>> for Lum<T> {
    fn clamp_from (other: Lum<F>) -> Lum<T> {
        Lum(T::clamp_from(other.0))
    }

    fn saturating_clamp_from (other: Lum<F>) -> Lum<T> {
        Lum(T::saturating_clamp_from(other.0))
    }

    fn try_clamp_from (other: Lum<F>) -> Result<Lum<T>, ClampError> {
        Ok(Lum(T::try_clamp_from(other.0)?))
    }
}

impl<S: Lerp<T>, T> Lerp<T> for Lum<S> {
    fn lerp (a: Lum<S>, b: Lum<S>, t: T) -> Lum<S> {
        Lum(S::lerp(a.0, b.0, t))
    }
}

/// Luminance-alpha color structure.
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))]
pub struct LumAlpha<T> (pub T, pub T);

impl<T> LumAlpha<T> {
    #[inline(always)]
    pub fn alpha (self) -> T { self.1 }

    pub fn drop_alpha (self) -> Lum<T> { Lum(self.0) }

    #[inline(always)]
    pub fn luminance (self) -> T { self.0 }

    pub fn split_alpha (self) -> (Lum<T>, T) {
        (Lum(self.0), self.1)
    }
}

impl<F, T: ClampFrom<F>> ClampFrom<LumAlpha<F>> for LumAlpha<T> {
    fn clamp_from (other: LumAlpha<F>) -> LumAlpha<T> {
        LumAlpha(T::clamp_from(other.0), T::clamp_from(other.1))
    }

    fn saturating_clamp_from (other: LumAlpha<F>) -> LumAlpha<T> {
        LumAlpha(T::saturating_clamp_from(other.0), T::saturating_clamp_from(other.1))
    }

    fn try_clamp_from (other: LumAlpha<F>) -> Result<LumAlpha<T>, ClampError> {
        Ok(LumAlpha(T::try_clamp_from(other.0)?, T::try_clamp_from(other.1)?))
    }
}

impl<T: Clamp> From<Lum<T>> for LumAlpha<T> {
    fn from (other: Lum<T>) -> LumAlpha<T> { LumAlpha(other.0, T::clamp_max()) }
}

impl<T: Clamp> From<Option<Lum<T>>> for LumAlpha<T> {
    fn from (other: Option<Lum<T>>) -> LumAlpha<T> {
        match other {
            None => LumAlpha(T::clamp_min(), T::clamp_min()),
            Some(other) => LumAlpha(other.0, T::clamp_max()),
        }
    }
}

impl<S: Lerp<T>, T: Copy> Lerp<T> for LumAlpha<S> {
    fn lerp (a: LumAlpha<S>, b: LumAlpha<S>, t: T) -> LumAlpha<S> {
        LumAlpha(S::lerp(a.0, b.0, t), S::lerp(a.1, b.1, t))
    }
}