зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1882754 - Clean up and simplify the color ToCss implementations. r=layout-reviewers,emilio
Differential Revision: https://phabricator.services.mozilla.com/D203118
This commit is contained in:
Родитель
599f3538c7
Коммит
2b84327e28
|
@ -38,26 +38,6 @@ impl<'a> ToCss for ModernComponent<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToCss for ColorFunction {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> 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<W>(&self, dest: &mut CssWriter<W>) -> 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<W>(&self, dest: &mut CssWriter<W>) -> 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<f32>,
|
||||
/// The a-axis component.
|
||||
pub a: Option<f32>,
|
||||
/// The b-axis component.
|
||||
pub b: Option<f32>,
|
||||
/// The alpha component.
|
||||
pub alpha: Option<f32>,
|
||||
}
|
||||
|
||||
/// Color specified by lightness, a- and b-axis components.
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub struct Oklab {
|
||||
/// The lightness component.
|
||||
pub lightness: Option<f32>,
|
||||
/// The a-axis component.
|
||||
pub a: Option<f32>,
|
||||
/// The b-axis component.
|
||||
pub b: Option<f32>,
|
||||
/// The alpha component.
|
||||
pub alpha: Option<f32>,
|
||||
}
|
||||
|
||||
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<f32>,
|
||||
a: Option<f32>,
|
||||
b: Option<f32>,
|
||||
alpha: Option<f32>,
|
||||
) -> Self {
|
||||
Self {
|
||||
lightness,
|
||||
a,
|
||||
b,
|
||||
alpha,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for $cls {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> 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<f32>,
|
||||
/// The chroma component.
|
||||
pub chroma: Option<f32>,
|
||||
/// The hue component.
|
||||
pub hue: Option<f32>,
|
||||
/// The alpha component.
|
||||
pub alpha: Option<f32>,
|
||||
}
|
||||
|
||||
/// Color specified by lightness, chroma and hue components.
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub struct Oklch {
|
||||
/// The lightness component.
|
||||
pub lightness: Option<f32>,
|
||||
/// The chroma component.
|
||||
pub chroma: Option<f32>,
|
||||
/// The hue component.
|
||||
pub hue: Option<f32>,
|
||||
/// The alpha component.
|
||||
pub alpha: Option<f32>,
|
||||
}
|
||||
|
||||
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<f32>,
|
||||
chroma: Option<f32>,
|
||||
hue: Option<f32>,
|
||||
alpha: Option<f32>,
|
||||
) -> Self {
|
||||
Self {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for $cls {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> 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.
|
||||
/// <https://drafts.csswg.org/css-color-4/#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<f32>,
|
||||
/// The second component of the color. Either green or y.
|
||||
pub c2: Option<f32>,
|
||||
/// The third component of the color. Either blue or z.
|
||||
pub c3: Option<f32>,
|
||||
/// The alpha component of the color.
|
||||
pub alpha: Option<f32>,
|
||||
}
|
||||
|
||||
impl ColorFunction {
|
||||
/// Construct a new color function definition with the given color space and
|
||||
/// color components.
|
||||
pub fn new(
|
||||
color_space: ColorSpace,
|
||||
c1: Option<f32>,
|
||||
c2: Option<f32>,
|
||||
c3: Option<f32>,
|
||||
alpha: Option<f32>,
|
||||
) -> Self {
|
||||
Self {
|
||||
color_space,
|
||||
c1,
|
||||
c2,
|
||||
c3,
|
||||
alpha,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче