Initial implementation of invert()
(no support for weight
argument)
This commit is contained in:
parent
8638e2f251
commit
1269c9f662
@ -150,4 +150,10 @@ pub(crate) fn register(f: &mut BTreeMap<String, Builtin>) {
|
|||||||
_ => todo!("non-color given to builtin function `alpha()`")
|
_ => todo!("non-color given to builtin function `alpha()`")
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
decl!(f "invert", |args, _| {
|
||||||
|
match arg!(args, 0, "color") {
|
||||||
|
Value::Color(c) => Some(Value::Color(c.invert())),
|
||||||
|
_ => todo!("non-color given to builtin function `alpha()`")
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -10,15 +10,15 @@ mod name;
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub(crate) struct Color {
|
pub(crate) struct Color {
|
||||||
red: u16,
|
red: u8,
|
||||||
green: u16,
|
green: u8,
|
||||||
blue: u16,
|
blue: u8,
|
||||||
alpha: Number,
|
alpha: Number,
|
||||||
repr: String,
|
repr: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Color {
|
impl Color {
|
||||||
pub fn new(red: u16, green: u16, blue: u16, alpha: u16, repr: String) -> Self {
|
pub fn new(red: u8, green: u8, blue: u8, alpha: u8, repr: String) -> Self {
|
||||||
Color {
|
Color {
|
||||||
red,
|
red,
|
||||||
green,
|
green,
|
||||||
@ -28,15 +28,15 @@ impl Color {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn red(&self) -> u16 {
|
pub const fn red(&self) -> u8 {
|
||||||
self.red
|
self.red
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn blue(&self) -> u16 {
|
pub const fn blue(&self) -> u8 {
|
||||||
self.blue
|
self.blue
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn green(&self) -> u16 {
|
pub const fn green(&self) -> u8 {
|
||||||
self.green
|
self.green
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ impl Color {
|
|||||||
};
|
};
|
||||||
let val = (luminance.clone() * Number::from(255))
|
let val = (luminance.clone() * Number::from(255))
|
||||||
.to_integer()
|
.to_integer()
|
||||||
.to_u16()
|
.to_u8()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let repr = repr(val, val, val, &alpha);
|
let repr = repr(val, val, val, &alpha);
|
||||||
return Color {
|
return Color {
|
||||||
@ -175,8 +175,8 @@ impl Color {
|
|||||||
} * Number::from(255))
|
} * Number::from(255))
|
||||||
.round()
|
.round()
|
||||||
.to_integer()
|
.to_integer()
|
||||||
.to_u16()
|
.to_u8()
|
||||||
.expect("expected channel to fit inside u16");
|
.expect("expected channel to fit inside u8");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,11 +198,11 @@ impl Color {
|
|||||||
macro_rules! clamp {
|
macro_rules! clamp {
|
||||||
($channel:ident) => {
|
($channel:ident) => {
|
||||||
let $channel = if $channel > Number::from(255) {
|
let $channel = if $channel > Number::from(255) {
|
||||||
255_u16
|
255_u8
|
||||||
} else if $channel < Number::from(0) {
|
} else if $channel < Number::from(0) {
|
||||||
0_u16
|
0_u8
|
||||||
} else {
|
} else {
|
||||||
$channel.round().to_integer().to_u16().unwrap()
|
$channel.round().to_integer().to_u8().unwrap()
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -211,6 +211,14 @@ impl Color {
|
|||||||
clamp!(green);
|
clamp!(green);
|
||||||
clamp!(blue);
|
clamp!(blue);
|
||||||
|
|
||||||
|
let alpha = if alpha > Number::from(1) {
|
||||||
|
Number::from(1)
|
||||||
|
} else if alpha < Number::from(0) {
|
||||||
|
Number::from(0)
|
||||||
|
} else {
|
||||||
|
alpha
|
||||||
|
};
|
||||||
|
|
||||||
let repr = repr(red, green, blue, &alpha);
|
let repr = repr(red, green, blue, &alpha);
|
||||||
Color {
|
Color {
|
||||||
red,
|
red,
|
||||||
@ -220,10 +228,24 @@ impl Color {
|
|||||||
repr,
|
repr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn invert(&self) -> Self {
|
||||||
|
let red = std::u8::MAX - self.red;
|
||||||
|
let green = std::u8::MAX - self.green;
|
||||||
|
let blue = std::u8::MAX - self.blue;
|
||||||
|
let repr = repr(red, green, blue, &self.alpha);
|
||||||
|
Color {
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
alpha: self.alpha.clone(),
|
||||||
|
repr,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the proper representation from RGBA values
|
/// Get the proper representation from RGBA values
|
||||||
fn repr(red: u16, green: u16, blue: u16, alpha: &Number) -> String {
|
fn repr(red: u8, green: u8, blue: u8, alpha: &Number) -> String {
|
||||||
if alpha < &Number::from(1) {
|
if alpha < &Number::from(1) {
|
||||||
format!("rgba({}, {}, {}, {})", red, green, blue, alpha)
|
format!("rgba({}, {}, {}, {})", red, green, blue, alpha)
|
||||||
} else if let Ok(c) = ColorName::try_from([red, green, blue]) {
|
} else if let Ok(c) = ColorName::try_from([red, green, blue]) {
|
||||||
|
@ -469,10 +469,11 @@ impl TryFrom<&str> for ColorName {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl TryFrom<[u16; 3]> for ColorName {
|
|
||||||
|
impl TryFrom<[u8; 3]> for ColorName {
|
||||||
type Error = &'static str;
|
type Error = &'static str;
|
||||||
|
|
||||||
fn try_from(c: [u16; 3]) -> Result<Self, Self::Error> {
|
fn try_from(c: [u8; 3]) -> Result<Self, Self::Error> {
|
||||||
match c {
|
match c {
|
||||||
[0xF0, 0xF8, 0xFF] => Ok(Self::AliceBlue),
|
[0xF0, 0xF8, 0xFF] => Ok(Self::AliceBlue),
|
||||||
[0xFA, 0xEB, 0xD7] => Ok(Self::AntiqueWhite),
|
[0xFA, 0xEB, 0xD7] => Ok(Self::AntiqueWhite),
|
||||||
|
@ -61,6 +61,7 @@ macro_rules! from_integer {
|
|||||||
from_integer!(u16);
|
from_integer!(u16);
|
||||||
from_integer!(usize);
|
from_integer!(usize);
|
||||||
from_integer!(i32);
|
from_integer!(i32);
|
||||||
|
from_integer!(u8);
|
||||||
|
|
||||||
impl Display for Number {
|
impl Display for Number {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
@ -20,32 +20,32 @@ fn parse_hex(s: String) -> Value {
|
|||||||
match s.len() {
|
match s.len() {
|
||||||
3 => {
|
3 => {
|
||||||
let v = u16::from_str_radix(&s, 16).unwrap();
|
let v = u16::from_str_radix(&s, 16).unwrap();
|
||||||
let red = ((v & 0xf00) >> 8) * 0x11;
|
let red = (((v & 0xf00) >> 8) * 0x11) as u8;
|
||||||
let green = ((v & 0x0f0) >> 4) * 0x11;
|
let green = (((v & 0x0f0) >> 4) * 0x11) as u8;
|
||||||
let blue = (v & 0x00f) * 0x11;
|
let blue = ((v & 0x00f) * 0x11) as u8;
|
||||||
Value::Color(Color::new(red, green, blue, 1, format!("#{}", s)))
|
Value::Color(Color::new(red, green, blue, 1, format!("#{}", s)))
|
||||||
}
|
}
|
||||||
4 => {
|
4 => {
|
||||||
let v = u16::from_str_radix(&s, 16).unwrap();
|
let v = u16::from_str_radix(&s, 16).unwrap();
|
||||||
let red = ((v & 0xf000) >> 12) * 0x11;
|
let red = (((v & 0xf000) >> 12) * 0x11) as u8;
|
||||||
let green = ((v & 0x0f00) >> 8) * 0x11;
|
let green = (((v & 0x0f00) >> 8) * 0x11) as u8;
|
||||||
let blue = ((v & 0x00f0) >> 4) * 0x11;
|
let blue = (((v & 0x00f0) >> 4) * 0x11) as u8;
|
||||||
let alpha = (v & 0x000f) * 0x11;
|
let alpha = ((v & 0x000f) * 0x11) as u8;
|
||||||
Value::Color(Color::new(red, green, blue, alpha, format!("#{}", s)))
|
Value::Color(Color::new(red, green, blue, alpha, format!("#{}", s)))
|
||||||
}
|
}
|
||||||
6 => {
|
6 => {
|
||||||
let v = u32::from_str_radix(&s, 16).unwrap();
|
let v = u32::from_str_radix(&s, 16).unwrap();
|
||||||
let red: u16 = ((v & 0x00ff_0000) >> 16) as u16;
|
let red = ((v & 0x00ff_0000) >> 16) as u8;
|
||||||
let green: u16 = ((v & 0x0000_ff00) >> 8) as u16;
|
let green = ((v & 0x0000_ff00) >> 8) as u8;
|
||||||
let blue: u16 = (v & 0x0000_00ff) as u16;
|
let blue = (v & 0x0000_00ff) as u8;
|
||||||
Value::Color(Color::new(red, green, blue, 1, format!("#{}", s)))
|
Value::Color(Color::new(red, green, blue, 1, format!("#{}", s)))
|
||||||
}
|
}
|
||||||
8 => {
|
8 => {
|
||||||
let v = u32::from_str_radix(&s, 16).unwrap();
|
let v = u32::from_str_radix(&s, 16).unwrap();
|
||||||
let red = ((v & 0xff00_0000) >> 24) as u16;
|
let red = ((v & 0xff00_0000) >> 24) as u8;
|
||||||
let green = ((v & 0x00ff_0000) >> 16) as u16;
|
let green = ((v & 0x00ff_0000) >> 16) as u8;
|
||||||
let blue = ((v & 0x0000_ff00) >> 8) as u16;
|
let blue = ((v & 0x0000_ff00) >> 8) as u8;
|
||||||
let alpha = (v & 0x0000_00ff) as u16;
|
let alpha = (v & 0x0000_00ff) as u8;
|
||||||
Value::Color(Color::new(red, green, blue, alpha, format!("#{}", s)))
|
Value::Color(Color::new(red, green, blue, alpha, format!("#{}", s)))
|
||||||
}
|
}
|
||||||
_ => Value::Ident(s, QuoteKind::None),
|
_ => Value::Ident(s, QuoteKind::None),
|
||||||
|
@ -171,3 +171,8 @@ test!(
|
|||||||
"$a: hsl(193, 67%, 28%);\n\na {\n color: lightness($a);\n}\n",
|
"$a: hsl(193, 67%, 28%);\n\na {\n color: lightness($a);\n}\n",
|
||||||
"a {\n color: 28%;\n}\n"
|
"a {\n color: 28%;\n}\n"
|
||||||
);
|
);
|
||||||
|
test!(
|
||||||
|
invert_no_weight,
|
||||||
|
"a {\n color: invert(white);\n}\n",
|
||||||
|
"a {\n color: black;\n}\n"
|
||||||
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user