1use crate::palette::Palette;
5use crate::Color;
6
7#[derive(Clone, Debug)]
9pub struct ColorScale {
10 palette: Palette,
11}
12
13impl ColorScale {
14 pub fn new(palette: Palette) -> Self {
16 Self { palette }
17 }
18
19 pub fn viridis() -> Self {
21 Self::new(Palette::viridis())
22 }
23
24 pub fn rdbu() -> Self {
26 Self::new(Palette::rdbu())
27 }
28
29 pub fn map(&self, t: f32) -> Color {
31 self.palette.sample(t)
32 }
33
34 pub fn to_texture_data(&self, width: u32) -> Vec<u8> {
38 let mut data = Vec::with_capacity(width as usize * 4);
39 for i in 0..width {
40 let t = if width <= 1 {
41 0.5
42 } else {
43 i as f32 / (width - 1) as f32
44 };
45 let c = self.map(t);
46 let [r, g, b, a] = c.to_srgb8();
47 data.extend_from_slice(&[r, g, b, a]);
48 }
49 data
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn texture_data_length() {
59 let scale = ColorScale::viridis();
60 let data = scale.to_texture_data(256);
61 assert_eq!(data.len(), 256 * 4);
62 }
63
64 #[test]
65 fn endpoints() {
66 let scale = ColorScale::viridis();
67 let start = scale.map(0.0);
68 let end = scale.map(1.0);
69 assert!(start.r < 0.1); assert!(end.r > 0.5); }
73}