forked from mirrors/gecko-dev
Bug 1899011 - In Lab/Oklab, very small a and b values makes the color achromatic r=layout-reviewers,emilio
Using an dynamic epsilon to check for small a and b values. Differential Revision: https://phabricator.services.mozilla.com/D211665
This commit is contained in:
parent
0c79149d0a
commit
7ace11cfe2
3 changed files with 21 additions and 12 deletions
|
|
@ -141,17 +141,29 @@ pub fn rgb_to_hwb(from: &ColorComponents) -> ColorComponents {
|
|||
ColorComponents(hue, whiteness * 100.0, blackness * 100.0)
|
||||
}
|
||||
|
||||
/// Calculate an epsilon for a specified range.
|
||||
#[inline]
|
||||
pub fn epsilon_for_range(min: f32, max: f32) -> f32 {
|
||||
(max - min) / 1.0e5
|
||||
}
|
||||
|
||||
/// Convert from the rectangular orthogonal to the cylindrical polar coordinate
|
||||
/// system. This is used to convert (ok)lab to (ok)lch.
|
||||
/// <https://drafts.csswg.org/css-color-4/#lab-to-lch>
|
||||
#[inline]
|
||||
pub fn orthogonal_to_polar(from: &ColorComponents) -> ColorComponents {
|
||||
pub fn orthogonal_to_polar(from: &ColorComponents, e: f32) -> ColorComponents {
|
||||
let ColorComponents(lightness, a, b) = *from;
|
||||
|
||||
let chroma = (a * a + b * b).sqrt();
|
||||
|
||||
let hue = if a.abs() < e && b.abs() < e {
|
||||
// For extremely small values of a and b ... the reported hue angle
|
||||
// swinging about wildly and being essentially random ... this means
|
||||
// the hue is powerless, and treated as missing when converted into LCH
|
||||
// or Oklch.
|
||||
f32::NAN
|
||||
} else if chroma.abs() < e {
|
||||
// Very small chroma values make the hue component powerless.
|
||||
let hue = if chroma.abs() < 1.0e-6 {
|
||||
f32::NAN
|
||||
} else {
|
||||
normalize_hue(b.atan2(a).to_degrees())
|
||||
|
|
@ -794,7 +806,7 @@ impl ColorSpaceConversion for Lch {
|
|||
let lab = Lab::from_xyz(&from);
|
||||
|
||||
// Then convert the Lab to LCH.
|
||||
orthogonal_to_polar(&lab)
|
||||
orthogonal_to_polar(&lab, epsilon_for_range(0.0, 100.0))
|
||||
}
|
||||
|
||||
fn to_gamma_encoded(from: &ColorComponents) -> ColorComponents {
|
||||
|
|
@ -892,7 +904,7 @@ impl ColorSpaceConversion for Oklch {
|
|||
let lab = Oklab::from_xyz(&from);
|
||||
|
||||
// Then convert Oklab to OkLCH.
|
||||
orthogonal_to_polar(&lab)
|
||||
orthogonal_to_polar(&lab, epsilon_for_range(0.0, 1.0))
|
||||
}
|
||||
|
||||
fn to_gamma_encoded(from: &ColorComponents) -> ColorComponents {
|
||||
|
|
|
|||
|
|
@ -555,7 +555,10 @@ impl AbsoluteColor {
|
|||
(Srgb, Hwb) => convert::rgb_to_hwb(&components),
|
||||
(Hsl, Srgb) => convert::hsl_to_rgb(&components),
|
||||
(Hwb, Srgb) => convert::hwb_to_rgb(&components),
|
||||
(Lab, Lch) | (Oklab, Oklch) => convert::orthogonal_to_polar(&components),
|
||||
(Lab, Lch) | (Oklab, Oklch) => convert::orthogonal_to_polar(
|
||||
&components,
|
||||
convert::epsilon_for_range(0.0, if color_space == Lch { 100.0 } else { 1.0 }),
|
||||
),
|
||||
(Lch, Lab) | (Oklch, Oklab) => convert::polar_to_orthogonal(&components),
|
||||
|
||||
// All other conversions need to convert to XYZ first.
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
[color-computed-color-mix-function.html]
|
||||
[Property color value 'color-mix(in lch, white, blue)']
|
||||
expected: FAIL
|
||||
|
||||
[Property color value 'color-mix(in lch, white 10%, blue)']
|
||||
expected: FAIL
|
||||
Loading…
Reference in a new issue