2019-09-07 00:24:58 +02:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Default)]
|
2019-07-30 16:31:42 +02:00
|
|
|
pub struct Color {
|
|
|
|
|
red: f32,
|
|
|
|
|
green: f32,
|
|
|
|
|
blue: f32,
|
|
|
|
|
opacity: f32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Color {
|
|
|
|
|
pub fn new(red: f32, green: f32, blue: f32, opacity: f32) -> Color {
|
2019-10-02 16:24:28 +02:00
|
|
|
let (red, green, blue, opacity) = clamp(red, green, blue, opacity);
|
2019-07-30 16:31:42 +02:00
|
|
|
Color {
|
2019-10-02 16:24:28 +02:00
|
|
|
red,
|
|
|
|
|
green,
|
|
|
|
|
blue,
|
|
|
|
|
opacity,
|
2019-07-30 16:31:42 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn blend(&self, other: &Color, ratio: f32) -> Color {
|
2019-10-02 16:24:28 +02:00
|
|
|
let ratio = clamp_f32(ratio, 0.0, 1.0);
|
2019-07-30 16:31:42 +02:00
|
|
|
|
|
|
|
|
Color {
|
2019-10-02 16:24:28 +02:00
|
|
|
red: blend_f32(self.red, other.red, ratio),
|
|
|
|
|
green: blend_f32(self.green, other.green, ratio),
|
|
|
|
|
blue: blend_f32(self.blue, other.blue, ratio),
|
|
|
|
|
opacity: blend_f32(self.opacity, other.opacity, ratio),
|
2019-07-30 16:31:42 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-02 16:24:28 +02:00
|
|
|
#[inline]
|
2019-07-30 16:31:42 +02:00
|
|
|
pub fn as_argb8888(&self) -> u32 {
|
2019-08-01 19:51:06 +02:00
|
|
|
((255.0 * self.opacity) as u32 & 0xFF) << 24
|
|
|
|
|
| ((255.0 * self.red) as u32 & 0xFF) << 16
|
|
|
|
|
| ((255.0 * self.green) as u32 & 0xFF) << 8
|
|
|
|
|
| ((255.0 * self.blue) as u32 & 0xFF)
|
2019-07-30 16:31:42 +02:00
|
|
|
}
|
2019-07-31 00:42:03 +02:00
|
|
|
}
|
2019-10-02 16:24:28 +02:00
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn clamp(r: f32, g: f32, b: f32, o: f32) -> (f32, f32, f32, f32) {
|
|
|
|
|
clamp_naive(r, g, b, o)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn clamp_naive(r: f32, g: f32, b: f32, o: f32) -> (f32, f32, f32, f32) {
|
|
|
|
|
(
|
|
|
|
|
clamp_f32(r, 0.0, 1.0),
|
|
|
|
|
clamp_f32(g, 0.0, 1.0),
|
|
|
|
|
clamp_f32(b, 0.0, 1.0),
|
|
|
|
|
clamp_f32(o, 0.0, 1.0),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn clamp_f32(v: f32, a: f32, b: f32) -> f32 {
|
|
|
|
|
if v > b {
|
|
|
|
|
b
|
|
|
|
|
} else if v < a {
|
|
|
|
|
a
|
|
|
|
|
} else {
|
|
|
|
|
v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn blend_f32(a: f32, b: f32, r: f32) -> f32 {
|
|
|
|
|
a + ((b - a) * r)
|
|
|
|
|
}
|