use core::ops;
use crate::c;
use crate::color::Color;
use crate::color::Color8;
use crate::color::ColorF;
use crate::color::Color16;
use crate::color::BlendMode;
impl Color<f32> for ColorF {
#[inline(always)]
fn r(&self) -> f32 {
return self.r;
}
#[inline(always)]
fn g(&self) -> f32 {
return self.g;
}
#[inline(always)]
fn b(&self) -> f32 {
return self.b;
}
#[inline(always)]
fn a(&self) -> f32 {
return self.a;
}
#[inline(always)]
fn gray(&self) -> f32 {
unsafe{c::lexlibColorFGray(*self)}
}
#[inline(always)]
fn gray_alpha(&self) -> Self {
unsafe{c::lexlibColorFGrayAlpha(*self)}
}
#[inline(always)]
fn premultiply(&self) -> Self {
unsafe{c::lexlibColorFPremultiply(*self)}
}
#[inline(always)]
fn blend(&self, src: Self, mode: BlendMode) -> Self {
unsafe{c::lexlibColorFBlend(*self, src, mode as u8)}
}
const MIN: f32 = 0.0;
const MAX: f32 = 1.0;
const BLACK: Self = Self{r: Self::MIN, g: Self::MIN, b: Self::MIN, a: Self::MAX};
const WHITE: Self = Self{r: Self::MAX, g: Self::MAX, b: Self::MAX, a: Self::MAX};
const RED: Self = Self{r: Self::MAX, g: Self::MIN, b: Self::MIN, a: Self::MAX};
const GREEN: Self = Self{r: Self::MIN, g: Self::MAX, b: Self::MIN, a: Self::MAX};
const BLUE: Self = Self{r: Self::MIN, g: Self::MIN, b: Self::MAX, a: Self::MAX};
const YELLOW: Self = Self{r: Self::MAX, g: Self::MAX, b: Self::MIN, a: Self::MAX};
const MAGENTA: Self = Self{r: Self::MAX, g: Self::MIN, b: Self::MAX, a: Self::MAX};
const CYAN: Self = Self{r: Self::MIN, g: Self::MAX, b: Self::MAX, a: Self::MAX};
}
impl ops::Add for ColorF {
#[inline(always)]
fn add(self, src: Self) -> Self {
unsafe{ c::lexlibColorFBlend(self, src, c::LEXLIB_ADD) }
}
type Output = ColorF;
}
impl ops::Sub for ColorF {
#[inline(always)]
fn sub(self, src: Self) -> Self {
unsafe{ c::lexlibColorFBlend(self, src, c::LEXLIB_SUB) }
}
type Output = ColorF;
}
impl ops::Mul for ColorF {
#[inline(always)]
fn mul(self, src: Self) -> Self {
unsafe{ c::lexlibColorFBlend(self, src, c::LEXLIB_MUL) }
}
type Output = ColorF;
}
impl ColorF {
#[inline(always)]
pub const fn new(r: f32, g: f32, b: f32, a: f32) -> Self {
Self{r,g,b,a}
}
#[inline(always)]
pub const fn new_rgb(r: f32, g: f32, b: f32) -> Self {
Self{r,g,b, a: Self::MAX}
}
#[inline(always)]
pub const fn new_gray(g: f32) -> Self {
Self{r: g, g: g, b: g, a: Self::MAX}
}
#[inline(always)]
pub fn blend(self, src: Self) -> Self {
unsafe{ c::lexlibColorFBlend(self, src, c::LEXLIB_BLEND) }
}
#[inline(always)]
pub fn modulate(self, src: Self) -> Self {
unsafe{ c::lexlibColorFBlend(self, src, c::LEXLIB_MOD) }
}
}
impl From<Color8> for ColorF {
fn from(color: Color8) -> Self{
Self{
r: color.r as f32 / Color8::MAX as f32,
g: color.g as f32 / Color8::MAX as f32,
b: color.b as f32 / Color8::MAX as f32,
a: color.a as f32 / Color8::MAX as f32,
}
}
}
impl From<Color16> for ColorF {
fn from(color: Color16) -> Self{
Self{
r: color.r as f32 / Color16::MAX as f32,
g: color.g as f32 / Color16::MAX as f32,
b: color.b as f32 / Color16::MAX as f32,
a: color.a as f32 / Color16::MAX as f32,
}
}
}
impl From<[f32; 4]> for ColorF {
#[inline(always)]
fn from(val: [f32; 4]) -> Self {
Self{
r: val[0],
g: val[1],
b: val[2],
a: val[3],
}
}
}
impl From<(f32, f32, f32, f32)> for ColorF {
#[inline(always)]
fn from(val: (f32, f32, f32, f32)) -> Self {
Self{
r: val.0,
g: val.1,
b: val.2,
a: val.3,
}
}
}
#[test]
fn gray(){
assert_eq!(ColorF::new(1.0, 0.0, 0.0, 1.0).gray(), 0.299);
assert_eq!(ColorF::new(0.0, 1.0, 0.0, 1.0).gray(), 0.587);
assert_eq!(ColorF::new(0.0, 0.0, 1.0, 1.0).gray(), 0.114);
assert_eq!(ColorF::new(0.18, 0.142, 0.97, 1.0).gray(), 0.2477540075778961181640625);
}