mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
style: Use abstract color parser
In stead of having the css parser construct a color in it's own format and then converting it to what Gecko needs to perform operations, we now construct a Gecko friendly color type directly. Differential Revision: https://phabricator.services.mozilla.com/D170187
This commit is contained in:
parent
6e128b6512
commit
1c3aafd9d2
2 changed files with 81 additions and 63 deletions
|
@ -274,52 +274,6 @@ impl From<cssparser::PredefinedColorSpace> for ColorSpace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<cssparser::AbsoluteColor> for AbsoluteColor {
|
|
||||||
fn from(f: cssparser::AbsoluteColor) -> Self {
|
|
||||||
match f {
|
|
||||||
cssparser::AbsoluteColor::Rgba(rgba) => Self::from_rgba(rgba),
|
|
||||||
|
|
||||||
cssparser::AbsoluteColor::Lab(lab) => Self::new(
|
|
||||||
ColorSpace::Lab,
|
|
||||||
ColorComponents(lab.lightness, lab.a, lab.b),
|
|
||||||
lab.alpha,
|
|
||||||
),
|
|
||||||
|
|
||||||
cssparser::AbsoluteColor::Lch(lch) => Self::new(
|
|
||||||
ColorSpace::Lch,
|
|
||||||
ColorComponents(lch.lightness, lch.chroma, lch.hue),
|
|
||||||
lch.alpha,
|
|
||||||
),
|
|
||||||
|
|
||||||
cssparser::AbsoluteColor::Oklab(oklab) => Self::new(
|
|
||||||
ColorSpace::Oklab,
|
|
||||||
ColorComponents(oklab.lightness, oklab.a, oklab.b),
|
|
||||||
oklab.alpha,
|
|
||||||
),
|
|
||||||
|
|
||||||
cssparser::AbsoluteColor::Oklch(oklch) => Self::new(
|
|
||||||
ColorSpace::Oklch,
|
|
||||||
ColorComponents(oklch.lightness, oklch.chroma, oklch.hue),
|
|
||||||
oklch.alpha,
|
|
||||||
),
|
|
||||||
|
|
||||||
cssparser::AbsoluteColor::ColorFunction(c) => {
|
|
||||||
let mut result = AbsoluteColor::new(
|
|
||||||
c.color_space.into(),
|
|
||||||
ColorComponents(c.c1, c.c2, c.c3),
|
|
||||||
c.alpha,
|
|
||||||
);
|
|
||||||
|
|
||||||
if matches!(c.color_space, cssparser::PredefinedColorSpace::Srgb) {
|
|
||||||
result.flags |= SerializationFlags::AS_COLOR_FUNCTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToCss for AbsoluteColor {
|
impl ToCss for AbsoluteColor {
|
||||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
where
|
where
|
||||||
|
@ -394,7 +348,7 @@ impl ToCss for AbsoluteColor {
|
||||||
c3: self.components.2,
|
c3: self.components.2,
|
||||||
alpha: self.alpha,
|
alpha: self.alpha,
|
||||||
};
|
};
|
||||||
let color = cssparser::AbsoluteColor::ColorFunction(color_function);
|
let color = cssparser::Color::ColorFunction(color_function);
|
||||||
cssparser::ToCss::to_css(&color, dest)
|
cssparser::ToCss::to_css(&color, dest)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use super::AllowQuirks;
|
use super::AllowQuirks;
|
||||||
use crate::color::mix::ColorInterpolationMethod;
|
use crate::color::mix::ColorInterpolationMethod;
|
||||||
use crate::color::{AbsoluteColor, ColorComponents, ColorSpace};
|
use crate::color::{AbsoluteColor, ColorComponents, ColorSpace, SerializationFlags};
|
||||||
use crate::media_queries::Device;
|
use crate::media_queries::Device;
|
||||||
use crate::parser::{Parse, ParserContext};
|
use crate::parser::{Parse, ParserContext};
|
||||||
use crate::values::computed::{Color as ComputedColor, Context, ToComputedValue};
|
use crate::values::computed::{Color as ComputedColor, Context, ToComputedValue};
|
||||||
|
@ -433,8 +433,65 @@ impl From<RGBA> for Color {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ColorComponentParser<'a, 'b: 'a>(&'a ParserContext<'b>);
|
#[inline]
|
||||||
impl<'a, 'b: 'a, 'i: 'a> ::cssparser::ColorComponentParser<'i> for ColorComponentParser<'a, 'b> {
|
fn new_absolute(color_space: ColorSpace, c1: f32, c2: f32, c3: f32, alpha: f32) -> Color {
|
||||||
|
Color::Absolute(Box::new(Absolute {
|
||||||
|
color: AbsoluteColor::new(color_space, ColorComponents(c1, c2, c3), alpha),
|
||||||
|
authored: None,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl cssparser::FromParsedColor for Color {
|
||||||
|
fn from_current_color() -> Self {
|
||||||
|
Color::CurrentColor
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
|
||||||
|
new_absolute(
|
||||||
|
ColorSpace::Srgb,
|
||||||
|
red as f32 / 255.0,
|
||||||
|
green as f32 / 255.0,
|
||||||
|
blue as f32 / 255.0,
|
||||||
|
alpha,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_lab(lightness: f32, a: f32, b: f32, alpha: f32) -> Self {
|
||||||
|
new_absolute(ColorSpace::Lab, lightness, a, b, alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_lch(lightness: f32, chroma: f32, hue: f32, alpha: f32) -> Self {
|
||||||
|
new_absolute(ColorSpace::Lch, lightness, chroma, hue, alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_oklab(lightness: f32, a: f32, b: f32, alpha: f32) -> Self {
|
||||||
|
new_absolute(ColorSpace::Oklab, lightness, a, b, alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_oklch(lightness: f32, chroma: f32, hue: f32, alpha: f32) -> Self {
|
||||||
|
new_absolute(ColorSpace::Oklch, lightness, chroma, hue, alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_color_function(
|
||||||
|
color_space: cssparser::PredefinedColorSpace,
|
||||||
|
c1: f32,
|
||||||
|
c2: f32,
|
||||||
|
c3: f32,
|
||||||
|
alpha: f32,
|
||||||
|
) -> Self {
|
||||||
|
let mut result = new_absolute(color_space.into(), c1, c2, c3, alpha);
|
||||||
|
if let Color::Absolute(ref mut absolute) = result {
|
||||||
|
if matches!(absolute.color.color_space, ColorSpace::Srgb) {
|
||||||
|
absolute.color.flags |= SerializationFlags::AS_COLOR_FUNCTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ColorParser<'a, 'b: 'a>(&'a ParserContext<'b>);
|
||||||
|
impl<'a, 'b: 'a, 'i: 'a> ::cssparser::ColorParser<'i> for ColorParser<'a, 'b> {
|
||||||
|
type Output = Color;
|
||||||
type Error = StyleParseErrorKind<'i>;
|
type Error = StyleParseErrorKind<'i>;
|
||||||
|
|
||||||
fn parse_angle_or_number<'t>(
|
fn parse_angle_or_number<'t>(
|
||||||
|
@ -532,23 +589,30 @@ impl Color {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let compontent_parser = ColorComponentParser(&*context);
|
let color_parser = ColorParser(&*context);
|
||||||
match input.try_parse(|i| CSSParserColor::parse_with(&compontent_parser, i)) {
|
match input.try_parse(|i| cssparser::parse_color_with(&color_parser, i)) {
|
||||||
Ok(value) => Ok(match value {
|
Ok(mut color) => {
|
||||||
CSSParserColor::CurrentColor => Color::CurrentColor,
|
if let Color::Absolute(ref mut absolute) = color {
|
||||||
CSSParserColor::Absolute(absolute) => {
|
let enabled = {
|
||||||
let enabled = matches!(absolute, cssparser::AbsoluteColor::Rgba(_)) ||
|
let is_srgb = matches!(absolute.color.color_space, ColorSpace::Srgb);
|
||||||
allow_more_color_4();
|
let is_color_function = absolute
|
||||||
|
.color
|
||||||
|
.flags
|
||||||
|
.contains(SerializationFlags::AS_COLOR_FUNCTION);
|
||||||
|
let pref_enabled = allow_more_color_4();
|
||||||
|
|
||||||
|
(is_srgb && !is_color_function) || pref_enabled
|
||||||
|
};
|
||||||
if !enabled {
|
if !enabled {
|
||||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
Color::Absolute(Box::new(Absolute {
|
// Because we can't set the `authored` value at construction time, we have to set it
|
||||||
color: absolute.into(),
|
// here.
|
||||||
authored: authored.map(|s| s.to_ascii_lowercase().into_boxed_str()),
|
absolute.authored = authored.map(|s| s.to_ascii_lowercase().into_boxed_str());
|
||||||
}))
|
}
|
||||||
|
Ok(color)
|
||||||
},
|
},
|
||||||
}),
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue