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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
use super::*;
use crate::{ColorMap, Interpolator};
use std::ops::Range;

pub struct RgbGradient {
    red: Interpolator,
    green: Interpolator,
    blue: Interpolator,
    alpha: Interpolator,
    range: Range<f32>,
}

impl RgbGradient {
    /// # Arguments
    ///
    /// * `min`:
    /// * `max`:
    ///
    /// returns: RgbGradient
    ///
    /// # Examples
    ///
    /// ```
    /// # use colormap::HsvGradient;
    /// ```
    pub fn new(min: f32, max: f32) -> Self {
        debug_assert!(max > min, "max must be greater than min");
        Self {
            red: Interpolator::new(0.0, 1.0),
            green: Interpolator::new(0.0, 1.0),
            blue: Interpolator::new(0.0, 1.0),
            alpha: Interpolator::new(0.0, 1.0),
            range: Range { start: min, end: max },
        }
    }
    pub fn rescale(&mut self, min: f32, max: f32) {
        debug_assert!(max > min, "max must be greater than min");
        self.range = Range { start: min, end: max };
    }
    pub fn insert_color<RGB>(&mut self, key: f32, color: RGB)
    where
        RGB: Into<RGBA32>,
    {
        let rgba = color.into();
        let ratio = self.get_ratio(key);
        self.red.insert(ratio, rgba.r);
        self.green.insert(ratio, rgba.g);
        self.blue.insert(ratio, rgba.b);
        self.alpha.insert(ratio, rgba.a);
    }
    pub fn remove_color(&mut self, key: f32) {
        let ratio = self.get_ratio(key);
        self.red.remove(ratio);
        self.green.remove(ratio);
        self.blue.remove(ratio);
        self.alpha.remove(ratio);
    }
    pub fn insert_red(&mut self, key: f32, value: f32) {
        let ratio = self.get_ratio(key);
        self.red.insert(ratio, value);
    }
    pub fn remove_red(&mut self, key: f32) {
        let ratio = self.get_ratio(key);
        self.red.remove(ratio);
    }
    pub fn insert_green(&mut self, key: f32, value: f32) {
        let ratio = self.get_ratio(key);
        self.green.insert(ratio, value);
    }
    pub fn remove_green(&mut self, key: f32) {
        let ratio = self.get_ratio(key);
        self.green.remove(ratio);
    }
    pub fn insert_blue(&mut self, key: f32, value: f32) {
        let ratio = self.get_ratio(key);
        self.blue.insert(ratio, value);
    }
    pub fn remove_blue(&mut self, key: f32) {
        let ratio = self.get_ratio(key);
        self.blue.remove(ratio);
    }
    pub fn insert_alpha(&mut self, key: f32, value: f32) {
        let ratio = self.get_ratio(key);
        self.alpha.insert(ratio, value);
    }
    pub fn remove_alpha(&mut self, key: f32) {
        let ratio = self.get_ratio(key);
        self.alpha.remove(ratio);
    }
    pub fn clear_alpha(&mut self) {
        self.alpha.clear();
    }
}

impl RgbGradient {
    fn get_ratio(&self, value: f32) -> u16 {
        if value <= self.range.start {
            0
        }
        else if value >= self.range.end {
            65535
        }
        else {
            let ratio = (value - self.range.start) / (self.range.end - self.range.start);
            (ratio * 65535.0) as u16
        }
    }
    /// Creates a new HSVGradient with the given min and max values.
    ///
    /// # Arguments
    ///
    /// * `min`:
    /// * `max`:
    ///
    /// returns: HSVGradient
    ///
    /// # Examples
    ///
    /// ```
    /// # use color_gradient;
    /// ```
    pub fn get_step(&self, value: f32) -> RGBA32 {
        let ratio = self.get_ratio(value);
        RGBA32 {
            r: self.red.get_step(ratio),
            g: self.green.get_step(ratio),
            b: self.blue.get_step(ratio),
            a: self.alpha.get_step(ratio),
        }
    }
    /// Creates a new HSVGradient with the given min and max values.
    ///
    /// # Arguments
    ///
    /// * `min`:
    /// * `max`:
    ///
    /// returns: HSVGradient
    ///
    /// # Examples
    ///
    /// ```
    /// # use color_gradient;
    /// ```
    pub fn get_linear(&self, value: f32) -> RGBA32 {
        let ratio = self.get_ratio(value);
        RGBA32 {
            r: self.red.get_linear(ratio),
            g: self.green.get_linear(ratio),
            b: self.blue.get_linear(ratio),
            a: self.alpha.get_linear(ratio),
        }
    }
}