diff --git a/servo/components/style/color/to_css.rs b/servo/components/style/color/to_css.rs index 6ae7ab23d0df..350d8386f185 100644 --- a/servo/components/style/color/to_css.rs +++ b/servo/components/style/color/to_css.rs @@ -38,26 +38,6 @@ impl<'a> ToCss for ModernComponent<'a> { } } -impl ToCss for ColorFunction { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: Write, - { - dest.write_str("color(")?; - self.color_space.to_css(dest)?; - dest.write_char(' ')?; - ModernComponent(&self.c1).to_css(dest)?; - dest.write_char(' ')?; - ModernComponent(&self.c2).to_css(dest)?; - dest.write_char(' ')?; - ModernComponent(&self.c3).to_css(dest)?; - - serialize_color_alpha(dest, self.alpha, false)?; - - dest.write_char(')') - } -} - impl ToCss for AbsoluteColor { fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where @@ -66,22 +46,37 @@ impl ToCss for AbsoluteColor { match self.color_space { ColorSpace::Srgb if self.flags.contains(ColorFlags::IS_LEGACY_SRGB) => { // The "none" keyword is not supported in the rgb/rgba legacy syntax. - RgbaLegacy::from_floats( - self.components.0, - self.components.1, - self.components.2, - self.alpha, - ) - .to_css(dest) + let has_alpha = self.alpha != OPAQUE; + + dest.write_str(if has_alpha { "rgba(" } else { "rgb(" })?; + clamp_unit_f32(self.components.0).to_css(dest)?; + dest.write_str(", ")?; + clamp_unit_f32(self.components.1).to_css(dest)?; + dest.write_str(", ")?; + clamp_unit_f32(self.components.2).to_css(dest)?; + + // Legacy syntax does not allow none components. + serialize_color_alpha(dest, Some(self.alpha), true)?; + + dest.write_char(')') }, ColorSpace::Hsl | ColorSpace::Hwb => self.into_srgb_legacy().to_css(dest), - ColorSpace::Lab => Lab::new(self.c0(), self.c1(), self.c2(), self.alpha()).to_css(dest), - ColorSpace::Lch => Lch::new(self.c0(), self.c1(), self.c2(), self.alpha()).to_css(dest), - ColorSpace::Oklab => { - Oklab::new(self.c0(), self.c1(), self.c2(), self.alpha()).to_css(dest) - }, - ColorSpace::Oklch => { - Oklch::new(self.c0(), self.c1(), self.c2(), self.alpha()).to_css(dest) + ColorSpace::Oklab | ColorSpace::Lab | ColorSpace::Oklch | ColorSpace::Lch => { + if let ColorSpace::Oklab | ColorSpace::Oklch = self.color_space { + dest.write_str("ok")?; + } + if let ColorSpace::Oklab | ColorSpace::Lab = self.color_space { + dest.write_str("lab(")?; + } else { + dest.write_str("lch(")?; + } + ModernComponent(&self.c0()).to_css(dest)?; + dest.write_char(' ')?; + ModernComponent(&self.c1()).to_css(dest)?; + dest.write_char(' ')?; + ModernComponent(&self.c2()).to_css(dest)?; + serialize_color_alpha(dest, self.alpha(), false)?; + dest.write_char(')') }, _ => { #[cfg(debug_assertions)] @@ -91,7 +86,6 @@ impl ToCss for AbsoluteColor { !self.flags.contains(ColorFlags::IS_LEGACY_SRGB), "legacy srgb is not a color function" ); - PredefinedColorSpace::Srgb }, ColorSpace::SrgbLinear | ColorSpace::DisplayP3 | @@ -107,14 +101,18 @@ impl ToCss for AbsoluteColor { }, }; - let color_function = ColorFunction::new( - self.color_space, - self.c0(), - self.c1(), - self.c2(), - self.alpha(), - ); - color_function.to_css(dest) + dest.write_str("color(")?; + self.color_space.to_css(dest)?; + dest.write_char(' ')?; + ModernComponent(&self.c0()).to_css(dest)?; + dest.write_char(' ')?; + ModernComponent(&self.c1()).to_css(dest)?; + dest.write_char(' ')?; + ModernComponent(&self.c2()).to_css(dest)?; + + serialize_color_alpha(dest, self.alpha(), false)?; + + dest.write_char(')') }, } } @@ -251,239 +249,3 @@ impl AbsoluteColor { } } } - -/// A color with red, green, blue, and alpha components, in a byte each. -#[derive(Clone, Copy, PartialEq, Debug)] -pub struct RgbaLegacy { - /// The red component. - pub red: u8, - /// The green component. - pub green: u8, - /// The blue component. - pub blue: u8, - /// The alpha component. - pub alpha: f32, -} - -impl RgbaLegacy { - /// Constructs a new RGBA value from float components. It expects the red, - /// green, blue and alpha channels in that order, and all values will be - /// clamped to the 0.0 ... 1.0 range. - #[inline] - pub fn from_floats(red: f32, green: f32, blue: f32, alpha: f32) -> Self { - Self::new( - clamp_unit_f32(red), - clamp_unit_f32(green), - clamp_unit_f32(blue), - alpha.clamp(0.0, OPAQUE), - ) - } - - /// Same thing, but with `u8` values instead of floats in the 0 to 1 range. - #[inline] - pub const fn new(red: u8, green: u8, blue: u8, alpha: f32) -> Self { - Self { - red, - green, - blue, - alpha, - } - } -} - -impl ToCss for RgbaLegacy { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: fmt::Write, - { - let has_alpha = self.alpha != OPAQUE; - - dest.write_str(if has_alpha { "rgba(" } else { "rgb(" })?; - self.red.to_css(dest)?; - dest.write_str(", ")?; - self.green.to_css(dest)?; - dest.write_str(", ")?; - self.blue.to_css(dest)?; - - // Legacy syntax does not allow none components. - serialize_color_alpha(dest, Some(self.alpha), true)?; - - dest.write_char(')') - } -} - -// NOTE: LAB and OKLAB is not declared inside the [impl_lab_like] macro, -// because it causes cbindgen to ignore them. - -/// Color specified by lightness, a- and b-axis components. -#[derive(Clone, Copy, PartialEq, Debug)] -pub struct Lab { - /// The lightness component. - pub lightness: Option, - /// The a-axis component. - pub a: Option, - /// The b-axis component. - pub b: Option, - /// The alpha component. - pub alpha: Option, -} - -/// Color specified by lightness, a- and b-axis components. -#[derive(Clone, Copy, PartialEq, Debug)] -pub struct Oklab { - /// The lightness component. - pub lightness: Option, - /// The a-axis component. - pub a: Option, - /// The b-axis component. - pub b: Option, - /// The alpha component. - pub alpha: Option, -} - -macro_rules! impl_lab_like { - ($cls:ident, $fname:literal) => { - impl $cls { - /// Construct a new Lab color format with lightness, a, b and alpha components. - pub fn new( - lightness: Option, - a: Option, - b: Option, - alpha: Option, - ) -> Self { - Self { - lightness, - a, - b, - alpha, - } - } - } - - impl ToCss for $cls { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: fmt::Write, - { - dest.write_str($fname)?; - dest.write_str("(")?; - ModernComponent(&self.lightness).to_css(dest)?; - dest.write_char(' ')?; - ModernComponent(&self.a).to_css(dest)?; - dest.write_char(' ')?; - ModernComponent(&self.b).to_css(dest)?; - serialize_color_alpha(dest, self.alpha, false)?; - dest.write_char(')') - } - } - }; -} - -impl_lab_like!(Lab, "lab"); -impl_lab_like!(Oklab, "oklab"); - -// NOTE: LCH and OKLCH is not declared inside the [impl_lch_like] macro, -// because it causes cbindgen to ignore them. - -/// Color specified by lightness, chroma and hue components. -#[derive(Clone, Copy, PartialEq, Debug)] -pub struct Lch { - /// The lightness component. - pub lightness: Option, - /// The chroma component. - pub chroma: Option, - /// The hue component. - pub hue: Option, - /// The alpha component. - pub alpha: Option, -} - -/// Color specified by lightness, chroma and hue components. -#[derive(Clone, Copy, PartialEq, Debug)] -pub struct Oklch { - /// The lightness component. - pub lightness: Option, - /// The chroma component. - pub chroma: Option, - /// The hue component. - pub hue: Option, - /// The alpha component. - pub alpha: Option, -} - -macro_rules! impl_lch_like { - ($cls:ident, $fname:literal) => { - impl $cls { - /// Construct a new color with lightness, chroma and hue components. - pub fn new( - lightness: Option, - chroma: Option, - hue: Option, - alpha: Option, - ) -> Self { - Self { - lightness, - chroma, - hue, - alpha, - } - } - } - - impl ToCss for $cls { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: fmt::Write, - { - dest.write_str($fname)?; - dest.write_str("(")?; - ModernComponent(&self.lightness).to_css(dest)?; - dest.write_char(' ')?; - ModernComponent(&self.chroma).to_css(dest)?; - dest.write_char(' ')?; - ModernComponent(&self.hue).to_css(dest)?; - serialize_color_alpha(dest, self.alpha, false)?; - dest.write_char(')') - } - } - }; -} - -impl_lch_like!(Lch, "lch"); -impl_lch_like!(Oklch, "oklch"); - -/// A color specified by the color() function. -/// -#[derive(Clone, Copy, PartialEq, Debug)] -pub struct ColorFunction { - /// The color space for this color. - pub color_space: ColorSpace, - /// The first component of the color. Either red or x. - pub c1: Option, - /// The second component of the color. Either green or y. - pub c2: Option, - /// The third component of the color. Either blue or z. - pub c3: Option, - /// The alpha component of the color. - pub alpha: Option, -} - -impl ColorFunction { - /// Construct a new color function definition with the given color space and - /// color components. - pub fn new( - color_space: ColorSpace, - c1: Option, - c2: Option, - c3: Option, - alpha: Option, - ) -> Self { - Self { - color_space, - c1, - c2, - c3, - alpha, - } - } -}