This commit is contained in:
ConnorSkees 2020-02-09 19:07:44 -05:00
parent f6b27177ba
commit 7fcfeee97e
7 changed files with 47 additions and 51 deletions

View File

@ -41,20 +41,20 @@ impl Color {
} }
/// Calculate hue from RGBA values /// Calculate hue from RGBA values
/// Algorithm adapted from http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/ /// Algorithm adapted from <http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/>
pub fn hue(&self) -> Number { pub fn hue(&self) -> Number {
let red = self.red.clone() / Number::from(255); let red = self.red.clone() / Number::from(255);
let green = self.green.clone() / Number::from(255); let green = self.green.clone() / Number::from(255);
let blue = self.blue.clone() / Number::from(255); let blue = self.blue.clone() / Number::from(255);
let min = red.clone().min(green.clone().min(blue.clone())); let min = red.clone().min(green.clone().min(blue.clone()));
let max = red.clone().max(green.clone().max(blue.clone())); let max = red.clone().max(green.clone().max(blue.clone()));
if &min == &max { if min == max {
return Number::from(0); return Number::from(0);
} }
let mut hue = if &red == &max { let mut hue = if red == max {
(green - blue) / (max - min) (green - blue) / (max - min)
} else if &green == &max { } else if green == max {
Number::from(2) + (blue - red) / (max - min) Number::from(2) + (blue - red) / (max - min)
} else { } else {
Number::from(4) + (red - green) / (max - min) Number::from(4) + (red - green) / (max - min)
@ -68,7 +68,7 @@ impl Color {
} }
/// Calculate saturation from RGBA values /// Calculate saturation from RGBA values
/// Algorithm adapted from http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/ /// Algorithm adapted from <http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/>
pub fn saturation(&self) -> Number { pub fn saturation(&self) -> Number {
let red = self.red.clone() / Number::from(255); let red = self.red.clone() / Number::from(255);
let green = self.green.clone() / Number::from(255); let green = self.green.clone() / Number::from(255);
@ -77,18 +77,22 @@ impl Color {
let min = red.clone().min(green.clone().min(blue.clone())); let min = red.clone().min(green.clone().min(blue.clone()));
let max = red.max(green.max(blue)); let max = red.max(green.max(blue));
if &min == &max { if min == max {
return Number::from(0); return Number::from(0);
} }
let d = max.clone() - min.clone(); let d = max.clone() - min.clone();
let mm = max + min; let mm = max + min;
let s = d / if mm > Number::from(1) { Number::from(2) - mm } else { mm }; let s = d / if mm > Number::from(1) {
Number::from(2) - mm
} else {
mm
};
(s * Number::from(100)).round() (s * Number::from(100)).round()
} }
/// Calculate luminance from RGBA values /// Calculate luminance from RGBA values
/// Algorithm adapted from http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/ /// Algorithm adapted from <http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/>
pub fn lightness(&self) -> Number { pub fn lightness(&self) -> Number {
let red = self.red.clone() / Number::from(255); let red = self.red.clone() / Number::from(255);
let green = self.green.clone() / Number::from(255); let green = self.green.clone() / Number::from(255);
@ -103,7 +107,7 @@ impl Color {
} }
/// Create RGBA representation from HSLA values /// Create RGBA representation from HSLA values
/// Algorithm adapted from http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/ /// Algorithm adapted from <http://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/>
pub fn from_hsla( pub fn from_hsla(
mut hue: Number, mut hue: Number,
mut saturation: Number, mut saturation: Number,
@ -131,26 +135,26 @@ impl Color {
} else { } else {
luminance luminance
}; };
let val = luminance.clone() * Number::from(255); let val = luminance * Number::from(255);
let repr = repr(&val, &val, &val, &alpha); let repr = repr(&val, &val, &val, &alpha);
return Color { return Color {
red: val.clone(), red: val.clone(),
green: val.clone(), green: val.clone(),
blue: val, blue: val,
alpha: Number::from(alpha), alpha,
repr, repr,
}; };
} }
let temporary_1 = if luminance.clone() < Number::ratio(1, 2) { let temporary_1 = if luminance.clone() < Number::ratio(1, 2) {
luminance.clone() * (Number::from(1) + saturation) luminance.clone() * (Number::from(1) + saturation)
} else { } else {
luminance.clone() + saturation.clone() - luminance.clone() * saturation.clone() luminance.clone() + saturation.clone() - luminance.clone() * saturation
}; };
let temporary_2 = Number::from(2) * luminance.clone() - temporary_1.clone(); let temporary_2 = Number::from(2) * luminance - temporary_1.clone();
hue /= Number::from(360); hue /= Number::from(360);
let mut temporary_r = hue.clone() + Number::ratio(1, 3); let mut temporary_r = hue.clone() + Number::ratio(1, 3);
let mut temporary_g = hue.clone(); let mut temporary_g = hue.clone();
let mut temporary_b = hue.clone() - Number::ratio(1, 3); let mut temporary_b = hue - Number::ratio(1, 3);
macro_rules! clamp_temp { macro_rules! clamp_temp {
($temp:ident) => { ($temp:ident) => {
@ -241,9 +245,9 @@ impl Color {
} else { } else {
weight weight
}; };
let red = Number::from(std::u8::MAX) - (Number::from(self.red.clone()) * weight.clone()); let red = Number::from(u8::max_value()) - self.red.clone() * weight.clone();
let green = Number::from(std::u8::MAX) - (Number::from(self.green.clone()) * weight.clone()); let green = Number::from(u8::max_value()) - self.green.clone() * weight.clone();
let blue = Number::from(std::u8::MAX) - (Number::from(self.blue.clone()) * weight); let blue = Number::from(u8::max_value()) - self.blue.clone() * weight;
let repr = repr(&red, &green, &blue, &self.alpha); let repr = repr(&red, &green, &blue, &self.alpha);
Color { Color {
red, red,

View File

@ -646,8 +646,7 @@ impl ColorName {
Self::DarkBlue => Color::new(0x00, 0x00, 0x8B, 0xFF, repr), Self::DarkBlue => Color::new(0x00, 0x00, 0x8B, 0xFF, repr),
Self::DarkCyan => Color::new(0x00, 0x8B, 0x8B, 0xFF, repr), Self::DarkCyan => Color::new(0x00, 0x8B, 0x8B, 0xFF, repr),
Self::DarkGoldenRod => Color::new(0xB8, 0x86, 0x0B, 0xFF, repr), Self::DarkGoldenRod => Color::new(0xB8, 0x86, 0x0B, 0xFF, repr),
Self::DarkGray => Color::new(0xA9, 0xA9, 0xA9, 0xFF, repr), Self::DarkGray | Self::DarkGrey => Color::new(0xA9, 0xA9, 0xA9, 0xFF, repr),
Self::DarkGrey => Color::new(0xA9, 0xA9, 0xA9, 0xFF, repr),
Self::DarkGreen => Color::new(0x00, 0x64, 0x00, 0xFF, repr), Self::DarkGreen => Color::new(0x00, 0x64, 0x00, 0xFF, repr),
Self::DarkKhaki => Color::new(0xBD, 0xB7, 0x6B, 0xFF, repr), Self::DarkKhaki => Color::new(0xBD, 0xB7, 0x6B, 0xFF, repr),
Self::DarkMagenta => Color::new(0x8B, 0x00, 0x8B, 0xFF, repr), Self::DarkMagenta => Color::new(0x8B, 0x00, 0x8B, 0xFF, repr),
@ -658,14 +657,12 @@ impl ColorName {
Self::DarkSalmon => Color::new(0xE9, 0x96, 0x7A, 0xFF, repr), Self::DarkSalmon => Color::new(0xE9, 0x96, 0x7A, 0xFF, repr),
Self::DarkSeaGreen => Color::new(0x8F, 0xBC, 0x8F, 0xFF, repr), Self::DarkSeaGreen => Color::new(0x8F, 0xBC, 0x8F, 0xFF, repr),
Self::DarkSlateBlue => Color::new(0x48, 0x3D, 0x8B, 0xFF, repr), Self::DarkSlateBlue => Color::new(0x48, 0x3D, 0x8B, 0xFF, repr),
Self::DarkSlateGray => Color::new(0x2F, 0x4F, 0x4F, 0xFF, repr), Self::DarkSlateGray | Self::DarkSlateGrey => Color::new(0x2F, 0x4F, 0x4F, 0xFF, repr),
Self::DarkSlateGrey => Color::new(0x2F, 0x4F, 0x4F, 0xFF, repr),
Self::DarkTurquoise => Color::new(0x00, 0xCE, 0xD1, 0xFF, repr), Self::DarkTurquoise => Color::new(0x00, 0xCE, 0xD1, 0xFF, repr),
Self::DarkViolet => Color::new(0x94, 0x00, 0xD3, 0xFF, repr), Self::DarkViolet => Color::new(0x94, 0x00, 0xD3, 0xFF, repr),
Self::DeepPink => Color::new(0xFF, 0x14, 0x93, 0xFF, repr), Self::DeepPink => Color::new(0xFF, 0x14, 0x93, 0xFF, repr),
Self::DeepSkyBlue => Color::new(0x00, 0xBF, 0xFF, 0xFF, repr), Self::DeepSkyBlue => Color::new(0x00, 0xBF, 0xFF, 0xFF, repr),
Self::DimGray => Color::new(0x69, 0x69, 0x69, 0xFF, repr), Self::DimGray | Self::DimGrey => Color::new(0x69, 0x69, 0x69, 0xFF, repr),
Self::DimGrey => Color::new(0x69, 0x69, 0x69, 0xFF, repr),
Self::DodgerBlue => Color::new(0x1E, 0x90, 0xFF, 0xFF, repr), Self::DodgerBlue => Color::new(0x1E, 0x90, 0xFF, 0xFF, repr),
Self::FireBrick => Color::new(0xB2, 0x22, 0x22, 0xFF, repr), Self::FireBrick => Color::new(0xB2, 0x22, 0x22, 0xFF, repr),
Self::FloralWhite => Color::new(0xFF, 0xFA, 0xF0, 0xFF, repr), Self::FloralWhite => Color::new(0xFF, 0xFA, 0xF0, 0xFF, repr),
@ -675,8 +672,7 @@ impl ColorName {
Self::GhostWhite => Color::new(0xF8, 0xF8, 0xFF, 0xFF, repr), Self::GhostWhite => Color::new(0xF8, 0xF8, 0xFF, 0xFF, repr),
Self::Gold => Color::new(0xFF, 0xD7, 0x00, 0xFF, repr), Self::Gold => Color::new(0xFF, 0xD7, 0x00, 0xFF, repr),
Self::GoldenRod => Color::new(0xDA, 0xA5, 0x20, 0xFF, repr), Self::GoldenRod => Color::new(0xDA, 0xA5, 0x20, 0xFF, repr),
Self::Gray => Color::new(0x80, 0x80, 0x80, 0xFF, repr), Self::Gray | Self::Grey => Color::new(0x80, 0x80, 0x80, 0xFF, repr),
Self::Grey => Color::new(0x80, 0x80, 0x80, 0xFF, repr),
Self::Green => Color::new(0x00, 0x80, 0x00, 0xFF, repr), Self::Green => Color::new(0x00, 0x80, 0x00, 0xFF, repr),
Self::GreenYellow => Color::new(0xAD, 0xFF, 0x2F, 0xFF, repr), Self::GreenYellow => Color::new(0xAD, 0xFF, 0x2F, 0xFF, repr),
Self::HoneyDew => Color::new(0xF0, 0xFF, 0xF0, 0xFF, repr), Self::HoneyDew => Color::new(0xF0, 0xFF, 0xF0, 0xFF, repr),
@ -700,8 +696,7 @@ impl ColorName {
Self::LightSalmon => Color::new(0xFF, 0xA0, 0x7A, 0xFF, repr), Self::LightSalmon => Color::new(0xFF, 0xA0, 0x7A, 0xFF, repr),
Self::LightSeaGreen => Color::new(0x20, 0xB2, 0xAA, 0xFF, repr), Self::LightSeaGreen => Color::new(0x20, 0xB2, 0xAA, 0xFF, repr),
Self::LightSkyBlue => Color::new(0x87, 0xCE, 0xFA, 0xFF, repr), Self::LightSkyBlue => Color::new(0x87, 0xCE, 0xFA, 0xFF, repr),
Self::LightSlateGray => Color::new(0x77, 0x88, 0x99, 0xFF, repr), Self::LightSlateGray | Self::LightSlateGrey => Color::new(0x77, 0x88, 0x99, 0xFF, repr),
Self::LightSlateGrey => Color::new(0x77, 0x88, 0x99, 0xFF, repr),
Self::LightSteelBlue => Color::new(0xB0, 0xC4, 0xDE, 0xFF, repr), Self::LightSteelBlue => Color::new(0xB0, 0xC4, 0xDE, 0xFF, repr),
Self::LightYellow => Color::new(0xFF, 0xFF, 0xE0, 0xFF, repr), Self::LightYellow => Color::new(0xFF, 0xFF, 0xE0, 0xFF, repr),
Self::Lime => Color::new(0x00, 0xFF, 0x00, 0xFF, repr), Self::Lime => Color::new(0x00, 0xFF, 0x00, 0xFF, repr),
@ -754,8 +749,7 @@ impl ColorName {
Self::Silver => Color::new(0xC0, 0xC0, 0xC0, 0xFF, repr), Self::Silver => Color::new(0xC0, 0xC0, 0xC0, 0xFF, repr),
Self::SkyBlue => Color::new(0x87, 0xCE, 0xEB, 0xFF, repr), Self::SkyBlue => Color::new(0x87, 0xCE, 0xEB, 0xFF, repr),
Self::SlateBlue => Color::new(0x6A, 0x5A, 0xCD, 0xFF, repr), Self::SlateBlue => Color::new(0x6A, 0x5A, 0xCD, 0xFF, repr),
Self::SlateGray => Color::new(0x70, 0x80, 0x90, 0xFF, repr), Self::SlateGray | Self::SlateGrey => Color::new(0x70, 0x80, 0x90, 0xFF, repr),
Self::SlateGrey => Color::new(0x70, 0x80, 0x90, 0xFF, repr),
Self::Snow => Color::new(0xFF, 0xFA, 0xFA, 0xFF, repr), Self::Snow => Color::new(0xFF, 0xFA, 0xFA, 0xFF, repr),
Self::SpringGreen => Color::new(0x00, 0xFF, 0x7F, 0xFF, repr), Self::SpringGreen => Color::new(0x00, 0xFF, 0x7F, 0xFF, repr),
Self::SteelBlue => Color::new(0x46, 0x82, 0xB4, 0xFF, repr), Self::SteelBlue => Color::new(0x46, 0x82, 0xB4, 0xFF, repr),

View File

@ -96,7 +96,7 @@ impl Mixin {
while let Some(expr) = eat_expr(&mut self.body, &self.scope, super_selector)? { while let Some(expr) = eat_expr(&mut self.body, &self.scope, super_selector)? {
match expr { match expr {
Expr::Style(s) => stmts.push(Stmt::Style(s)), Expr::Style(s) => stmts.push(Stmt::Style(s)),
Expr::Styles(s) => stmts.extend(s.into_iter().map(|s| Stmt::Style(s))), Expr::Styles(s) => stmts.extend(s.into_iter().map(Stmt::Style)),
Expr::Include(s) => stmts.extend(s), Expr::Include(s) => stmts.extend(s),
Expr::MixinDecl(..) | Expr::FunctionDecl(..) | Expr::Debug(..) | Expr::Warn(..) => { Expr::MixinDecl(..) | Expr::FunctionDecl(..) | Expr::Debug(..) | Expr::Warn(..) => {
todo!() todo!()

View File

@ -295,13 +295,12 @@ impl<'a> SelectorParser<'a> {
}), }),
TokenKind::Interpolation => { TokenKind::Interpolation => {
self.is_interpolated = true; self.is_interpolated = true;
let v = self.tokens_to_selectors( self.tokens_to_selectors(
&mut parse_interpolation(tokens, self.scope) &mut parse_interpolation(tokens, self.scope)
.into_iter() .into_iter()
.peekable(), .peekable(),
); );
self.is_interpolated = false; self.is_interpolated = false;
v
} }
TokenKind::Attribute(attr) => self.selectors.push(SelectorKind::Attribute(attr)), TokenKind::Attribute(attr) => self.selectors.push(SelectorKind::Attribute(attr)),
_ => todo!("unimplemented selector"), _ => todo!("unimplemented selector"),

View File

@ -53,7 +53,7 @@ struct StyleParser<'a> {
} }
impl<'a> StyleParser<'a> { impl<'a> StyleParser<'a> {
fn new(scope: &'a Scope, super_selector: &'a Selector) -> Self { const fn new(scope: &'a Scope, super_selector: &'a Selector) -> Self {
StyleParser { StyleParser {
scope, scope,
super_selector, super_selector,

View File

@ -161,7 +161,7 @@ impl Mul for Value {
match self { match self {
Self::Null => todo!(), Self::Null => todo!(),
Self::Dimension(num, unit) => match other { Self::Dimension(num, unit) => match other {
Self::Dimension(num2, unit2) => Value::Dimension(num - num2, unit), Self::Dimension(num2, unit2) => Value::Dimension(num * num2, unit),
_ => todo!(), _ => todo!(),
}, },
Self::BinaryOp(..) | Self::Paren(..) => self.eval(), Self::BinaryOp(..) | Self::Paren(..) => self.eval(),

View File

@ -167,13 +167,13 @@ impl Value {
} else { } else {
Unit::None Unit::None
}; };
let n = match val.parse::<BigRational>() { let n = if let Ok(v) = val.parse::<BigRational>() {
// the number is an integer! // the number is an integer!
Ok(v) => v, v
// the number is floating point // the number is floating point
Err(_) => { } else {
let mut num = String::new(); let mut num = String::new();
let mut chars = val.chars().into_iter(); let mut chars = val.chars();
let mut num_dec = 0; let mut num_dec = 0;
while let Some(c) = chars.next() { while let Some(c) = chars.next() {
if c == '.' { if c == '.' {
@ -186,7 +186,6 @@ impl Value {
num.push(c); num.push(c);
} }
BigRational::new(num.parse().unwrap(), pow(BigInt::from(10), num_dec)) BigRational::new(num.parse().unwrap(), pow(BigInt::from(10), num_dec))
}
}; };
Some(Value::Dimension(Number::new(n), unit)) Some(Value::Dimension(Number::new(n), unit))
} }