Merge branch 'master' into feature/canvas-interaction

This commit is contained in:
Héctor Ramón Jiménez 2020-05-04 23:35:09 +02:00
commit 67b2ccb4d5
8 changed files with 621 additions and 5 deletions

View file

@ -8,3 +8,7 @@ license = "MIT"
repository = "https://github.com/hecrj/iced"
[dependencies]
[dependencies.palette]
version = "0.5.0"
optional = true

View file

@ -1,10 +1,16 @@
#[cfg(feature = "palette")]
use palette::rgb::{Srgb, Srgba};
/// A color in the sRGB color space.
#[derive(Debug, Clone, Copy, PartialEq)]
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct Color {
/// Red component, 0.0 - 1.0
pub r: f32,
/// Green component, 0.0 - 1.0
pub g: f32,
/// Blue component, 0.0 - 1.0
pub b: f32,
/// Transparency, 0.0 - 1.0
pub a: f32,
}
@ -33,11 +39,45 @@ impl Color {
a: 0.0,
};
/// Creates a new [`Color`].
///
/// In debug mode, it will panic if the values are not in the correct
/// range: 0.0 - 1.0
///
/// [`Color`]: struct.Color.html
pub fn new(r: f32, g: f32, b: f32, a: f32) -> Color {
debug_assert!(
(0.0..=1.0).contains(&r),
"Red component must be on [0, 1]"
);
debug_assert!(
(0.0..=1.0).contains(&g),
"Green component must be on [0, 1]"
);
debug_assert!(
(0.0..=1.0).contains(&b),
"Blue component must be on [0, 1]"
);
debug_assert!(
(0.0..=1.0).contains(&a),
"Alpha component must be on [0, 1]"
);
Color { r, g, b, a }
}
/// Creates a [`Color`] from its RGB components.
///
/// [`Color`]: struct.Color.html
pub const fn from_rgb(r: f32, g: f32, b: f32) -> Color {
Color { r, g, b, a: 1.0 }
Color::from_rgba(r, g, b, 1.0f32)
}
/// Creates a [`Color`] from its RGBA components.
///
/// [`Color`]: struct.Color.html
pub const fn from_rgba(r: f32, g: f32, b: f32, a: f32) -> Color {
Color { r, g, b, a }
}
/// Creates a [`Color`] from its RGB8 components.
@ -80,16 +120,114 @@ impl Color {
self.a,
]
}
/// Inverts the [`Color`] in-place.
///
/// [`Color`]: struct.Color.html
pub fn invert(&mut self) {
self.r = 1.0f32 - self.r;
self.b = 1.0f32 - self.g;
self.g = 1.0f32 - self.b;
}
/// Returns the inverted [`Color`].
///
/// [`Color`]: struct.Color.html
pub fn inverse(self) -> Color {
Color::new(1.0f32 - self.r, 1.0f32 - self.g, 1.0f32 - self.b, self.a)
}
}
impl From<[f32; 3]> for Color {
fn from([r, g, b]: [f32; 3]) -> Self {
Color { r, g, b, a: 1.0 }
Color::new(r, g, b, 1.0)
}
}
impl From<[f32; 4]> for Color {
fn from([r, g, b, a]: [f32; 4]) -> Self {
Color { r, g, b, a }
Color::new(r, g, b, a)
}
}
#[cfg(feature = "palette")]
/// Converts from palette's `Srgba` type to a [`Color`].
///
/// [`Color`]: struct.Color.html
impl From<Srgba> for Color {
fn from(srgba: Srgba) -> Self {
Color::new(srgba.red, srgba.green, srgba.blue, srgba.alpha)
}
}
#[cfg(feature = "palette")]
/// Converts from [`Color`] to palette's `Srgba` type.
///
/// [`Color`]: struct.Color.html
impl From<Color> for Srgba {
fn from(c: Color) -> Self {
Srgba::new(c.r, c.g, c.b, c.a)
}
}
#[cfg(feature = "palette")]
/// Converts from palette's `Srgb` type to a [`Color`].
///
/// [`Color`]: struct.Color.html
impl From<Srgb> for Color {
fn from(srgb: Srgb) -> Self {
Color::new(srgb.red, srgb.green, srgb.blue, 1.0)
}
}
#[cfg(feature = "palette")]
/// Converts from [`Color`] to palette's `Srgb` type.
///
/// [`Color`]: struct.Color.html
/// [`Srgb`]: ../palette/rgb/type.Srgb.html
impl From<Color> for Srgb {
fn from(c: Color) -> Self {
Srgb::new(c.r, c.g, c.b)
}
}
#[cfg(feature = "palette")]
#[cfg(test)]
mod tests {
use super::*;
use palette::Blend;
#[test]
fn srgba_traits() {
let c = Color::from_rgb(0.5, 0.4, 0.3);
// Round-trip conversion to the palette:Srgba type
let s: Srgba = c.into();
let r: Color = s.into();
assert_eq!(c, r);
}
#[test]
fn color_manipulation() {
let c1 = Color::from_rgb(0.5, 0.4, 0.3);
let c2 = Color::from_rgb(0.2, 0.5, 0.3);
// Convert to linear color for manipulation
let l1 = Srgba::from(c1).into_linear();
let l2 = Srgba::from(c2).into_linear();
// Take the lighter of each of the RGB components
let lighter = l1.lighten(l2);
// Convert back to our Color
let r: Color = Srgba::from_linear(lighter).into();
assert_eq!(
r,
Color {
r: 0.5,
g: 0.5,
b: 0.3,
a: 1.0
}
);
}
}