Extended Color: Additional color cleanups
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 30 May 2020 22:25:54 +0000 (22:25 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 30 May 2020 22:25:54 +0000 (22:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=212567

Reviewed by Simon Fraser.

Source/WebCore:

A few unrelated quality-of-life cleanups to Color and related classes:
- Rename Color::asSimpleColor() to Color::asSimple() for parity with Color::asExtended().
- Move SimpleColor implementations of invertedColorWithAlpha() and asSRGBFloatComponents()
  to SimpleColor for parity with ExtenedColor.
- Rename ExtendedColor::channels() to ExtendedColor::components() to consistency.
- Adds operator[] to ColorComponents to allow direct access to components rather than
  requiring and additional .components[]
- Using std::minmax() where possible.
- Renaming colorFloatToSimpleColorByte to scaleRoundAndClampColorChannel to have a consistent
  naming and location of conversion to 8-bit color channels.

* platform/graphics/Color.cpp:
(WebCore::Color::serialized const):
(WebCore::Color::cssText const):
(WebCore::Color::nameForRenderTreeAsText const):
(WebCore::Color::light const):
(WebCore::Color::dark const):
(WebCore::Color::colorWithAlpha const):
(WebCore::Color::colorWithAlphaUsingAlternativeRounding const):
(WebCore::Color::invertedColorWithAlpha const):
(WebCore::Color::colorSpaceAndComponents const):
(WebCore::Color::toSRGBASimpleColorLossy const):
(WebCore::Color::toSRGBAComponentsLossy const):
* platform/graphics/Color.h:
(WebCore::Color::isOpaque const):
(WebCore::Color::isVisible const):
(WebCore::Color::alpha const):
(WebCore::Color::alphaAsFloat const):
(WebCore::Color::asSimple const):
(WebCore::Color::isBlackColor):
(WebCore::Color::isWhiteColor):
(WebCore::Color::encode const):
(WebCore::Color::asSimpleColor const): Deleted.
* platform/graphics/ColorComponents.h:
(WebCore::ColorComponents::operator[]):
(WebCore::ColorComponents::operator[] const):
(WebCore::=):
(WebCore::perComponentMax):
(WebCore::perComponentMin):
* platform/graphics/ColorMatrix.h:
(WebCore::Rows>::transformedColorComponents const):
* platform/graphics/ColorUtilities.cpp:
(WebCore::areEssentiallyEqual):
(WebCore::rgbToLinearComponents):
(WebCore::linearToRGBComponents):
(WebCore::lightness):
(WebCore::luminance):
(WebCore::sRGBToHSL):
(WebCore::hslToSRGB):
* platform/graphics/ColorUtilities.h:
(WebCore::scaleRoundAndClampColorChannel):
(WebCore::scaleRoundAndClampColorChannelUsingAlternativeRounding):
(WebCore::colorFloatToSimpleColorByte): Deleted.
* platform/graphics/ExtendedColor.cpp:
(WebCore::ExtendedColor::hash const):
(WebCore::ExtendedColor::cssText const):
(WebCore::ExtendedColor::colorWithAlpha const):
(WebCore::ExtendedColor::invertedColorWithAlpha const):
(WebCore::ExtendedColor::toSRGBAComponentsLossy const):
(WebCore::ExtendedColor::isWhite const):
(WebCore::ExtendedColor::isBlack const):
* platform/graphics/ExtendedColor.h:
(WebCore::ExtendedColor::alpha const):
(WebCore::ExtendedColor::components const):
(WebCore::ExtendedColor::ExtendedColor):
(WebCore::operator==):
(WebCore::ExtendedColor::channels const): Deleted.
* platform/graphics/SimpleColor.cpp:
(WebCore::makeSimpleColorFromFloats):
(WebCore::makeSimpleColorFromHSLA):
* platform/graphics/SimpleColor.h:
(WebCore::SimpleColor::SimpleColor):
(WebCore::SimpleColor::valueAsARGB const):
(WebCore::SimpleColor::colorWithAlpha const):
(WebCore::SimpleColor::invertedColorWithAlpha const):
(WebCore::SimpleColor::asSRGBFloatComponents const):
(WebCore::makeSimpleColor):
* platform/graphics/cg/ColorCG.cpp:
(WebCore::cachedCGColor):
* platform/graphics/filters/FELighting.cpp:
(WebCore::FELighting::drawLighting):
* platform/graphics/filters/FETurbulence.cpp:
(WebCore::toIntBasedColorComponents):
* platform/graphics/filters/FilterOperation.cpp:
(WebCore::BasicComponentTransferFilterOperation::transformColor const):
(WebCore::InvertLightnessFilterOperation::transformColor const):
(WebCore::InvertLightnessFilterOperation::inverseTransformColor const):
* platform/graphics/filters/FilterOperations.cpp:
(WebCore::FilterOperations::transformColor const):
(WebCore::FilterOperations::inverseTransformColor const):

Tools:

* TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp:
(TestWebKitAPI::TEST):
Update for rename from ExtendedColor::channels() to ExtendedColor::components()

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262352 268f45cc-cd09-0410-ab3c-d52691b4dbfc

18 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/Color.cpp
Source/WebCore/platform/graphics/Color.h
Source/WebCore/platform/graphics/ColorComponents.h
Source/WebCore/platform/graphics/ColorMatrix.h
Source/WebCore/platform/graphics/ColorUtilities.cpp
Source/WebCore/platform/graphics/ColorUtilities.h
Source/WebCore/platform/graphics/ExtendedColor.cpp
Source/WebCore/platform/graphics/ExtendedColor.h
Source/WebCore/platform/graphics/SimpleColor.cpp
Source/WebCore/platform/graphics/SimpleColor.h
Source/WebCore/platform/graphics/cg/ColorCG.cpp
Source/WebCore/platform/graphics/filters/FELighting.cpp
Source/WebCore/platform/graphics/filters/FETurbulence.cpp
Source/WebCore/platform/graphics/filters/FilterOperation.cpp
Source/WebCore/platform/graphics/filters/FilterOperations.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp

index 5199a8b..9bab477 100644 (file)
@@ -1,3 +1,101 @@
+2020-05-30  Sam Weinig  <weinig@apple.com>
+
+        Extended Color: Additional color cleanups
+        https://bugs.webkit.org/show_bug.cgi?id=212567
+
+        Reviewed by Simon Fraser.
+
+        A few unrelated quality-of-life cleanups to Color and related classes:
+        - Rename Color::asSimpleColor() to Color::asSimple() for parity with Color::asExtended().
+        - Move SimpleColor implementations of invertedColorWithAlpha() and asSRGBFloatComponents()
+          to SimpleColor for parity with ExtenedColor.
+        - Rename ExtendedColor::channels() to ExtendedColor::components() to consistency.
+        - Adds operator[] to ColorComponents to allow direct access to components rather than
+          requiring and additional .components[]
+        - Using std::minmax() where possible.
+        - Renaming colorFloatToSimpleColorByte to scaleRoundAndClampColorChannel to have a consistent 
+          naming and location of conversion to 8-bit color channels.
+
+        * platform/graphics/Color.cpp:
+        (WebCore::Color::serialized const):
+        (WebCore::Color::cssText const):
+        (WebCore::Color::nameForRenderTreeAsText const):
+        (WebCore::Color::light const):
+        (WebCore::Color::dark const):
+        (WebCore::Color::colorWithAlpha const):
+        (WebCore::Color::colorWithAlphaUsingAlternativeRounding const):
+        (WebCore::Color::invertedColorWithAlpha const):
+        (WebCore::Color::colorSpaceAndComponents const):
+        (WebCore::Color::toSRGBASimpleColorLossy const):
+        (WebCore::Color::toSRGBAComponentsLossy const):
+        * platform/graphics/Color.h:
+        (WebCore::Color::isOpaque const):
+        (WebCore::Color::isVisible const):
+        (WebCore::Color::alpha const):
+        (WebCore::Color::alphaAsFloat const):
+        (WebCore::Color::asSimple const):
+        (WebCore::Color::isBlackColor):
+        (WebCore::Color::isWhiteColor):
+        (WebCore::Color::encode const):
+        (WebCore::Color::asSimpleColor const): Deleted.
+        * platform/graphics/ColorComponents.h:
+        (WebCore::ColorComponents::operator[]):
+        (WebCore::ColorComponents::operator[] const):
+        (WebCore::=):
+        (WebCore::perComponentMax):
+        (WebCore::perComponentMin):
+        * platform/graphics/ColorMatrix.h:
+        (WebCore::Rows>::transformedColorComponents const):
+        * platform/graphics/ColorUtilities.cpp:
+        (WebCore::areEssentiallyEqual):
+        (WebCore::rgbToLinearComponents):
+        (WebCore::linearToRGBComponents):
+        (WebCore::lightness):
+        (WebCore::luminance):
+        (WebCore::sRGBToHSL):
+        (WebCore::hslToSRGB):
+        * platform/graphics/ColorUtilities.h:
+        (WebCore::scaleRoundAndClampColorChannel):
+        (WebCore::scaleRoundAndClampColorChannelUsingAlternativeRounding):
+        (WebCore::colorFloatToSimpleColorByte): Deleted.
+        * platform/graphics/ExtendedColor.cpp:
+        (WebCore::ExtendedColor::hash const):
+        (WebCore::ExtendedColor::cssText const):
+        (WebCore::ExtendedColor::colorWithAlpha const):
+        (WebCore::ExtendedColor::invertedColorWithAlpha const):
+        (WebCore::ExtendedColor::toSRGBAComponentsLossy const):
+        (WebCore::ExtendedColor::isWhite const):
+        (WebCore::ExtendedColor::isBlack const):
+        * platform/graphics/ExtendedColor.h:
+        (WebCore::ExtendedColor::alpha const):
+        (WebCore::ExtendedColor::components const):
+        (WebCore::ExtendedColor::ExtendedColor):
+        (WebCore::operator==):
+        (WebCore::ExtendedColor::channels const): Deleted.
+        * platform/graphics/SimpleColor.cpp:
+        (WebCore::makeSimpleColorFromFloats):
+        (WebCore::makeSimpleColorFromHSLA):
+        * platform/graphics/SimpleColor.h:
+        (WebCore::SimpleColor::SimpleColor):
+        (WebCore::SimpleColor::valueAsARGB const):
+        (WebCore::SimpleColor::colorWithAlpha const):
+        (WebCore::SimpleColor::invertedColorWithAlpha const):
+        (WebCore::SimpleColor::asSRGBFloatComponents const):
+        (WebCore::makeSimpleColor):
+        * platform/graphics/cg/ColorCG.cpp:
+        (WebCore::cachedCGColor):
+        * platform/graphics/filters/FELighting.cpp:
+        (WebCore::FELighting::drawLighting):
+        * platform/graphics/filters/FETurbulence.cpp:
+        (WebCore::toIntBasedColorComponents):
+        * platform/graphics/filters/FilterOperation.cpp:
+        (WebCore::BasicComponentTransferFilterOperation::transformColor const):
+        (WebCore::InvertLightnessFilterOperation::transformColor const):
+        (WebCore::InvertLightnessFilterOperation::inverseTransformColor const):
+        * platform/graphics/filters/FilterOperations.cpp:
+        (WebCore::FilterOperations::transformColor const):
+        (WebCore::FilterOperations::inverseTransformColor const):
+
 2020-05-30  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, reverting r262335.
index 75ce77a..f979aeb 100644 (file)
@@ -113,27 +113,27 @@ String Color::serialized() const
 {
     if (isExtended())
         return asExtended().cssText();
-    return asSimpleColor().serializationForHTML();
+    return asSimple().serializationForHTML();
 }
 
 String Color::cssText() const
 {
     if (isExtended())
         return asExtended().cssText();
-    return asSimpleColor().serializationForCSS();
+    return asSimple().serializationForCSS();
 }
 
 String Color::nameForRenderTreeAsText() const
 {
     if (isExtended())
         return asExtended().cssText();
-    return asSimpleColor().serializationForRenderTreeAsText();
+    return asSimple().serializationForRenderTreeAsText();
 }
 
 Color Color::light() const
 {
     // Hardcode this common case for speed.
-    if (!isExtended() && asSimpleColor() == black)
+    if (!isExtended() && asSimple() == black)
         return lightenedBlack;
     
     const float scaleFactor = nextafterf(256.0f, 0.0f);
@@ -158,7 +158,7 @@ Color Color::light() const
 Color Color::dark() const
 {
     // Hardcode this common case for speed.
-    if (!isExtended() && asSimpleColor() == white)
+    if (!isExtended() && asSimple() == white)
         return darkenedWhite;
     
     const float scaleFactor = nextafterf(256.0f, 0.0f);
@@ -269,7 +269,7 @@ Color Color::colorWithAlpha(float alpha) const
     // FIXME: This is where this function differs from colorWithAlphaUsingAlternativeRounding.
     uint8_t newAlpha = alpha * 0xFF;
 
-    Color result = asSimpleColor().colorWithAlpha(newAlpha);
+    Color result = asSimple().colorWithAlpha(newAlpha);
     if (isSemantic())
         result.setIsSemantic();
     return result;
@@ -281,9 +281,9 @@ Color Color::colorWithAlphaUsingAlternativeRounding(float alpha) const
         return asExtended().colorWithAlpha(alpha);
 
     // FIXME: This is where this function differs from colorWithAlphaUsing.
-    uint8_t newAlpha = colorFloatToSimpleColorByte(alpha);
+    uint8_t newAlpha = scaleRoundAndClampColorChannel(alpha);
 
-    Color result = asSimpleColor().colorWithAlpha(newAlpha);
+    Color result = asSimple().colorWithAlpha(newAlpha);
     if (isSemantic())
         result.setIsSemantic();
     return result;
@@ -292,10 +292,8 @@ Color Color::colorWithAlphaUsingAlternativeRounding(float alpha) const
 Color Color::invertedColorWithAlpha(float alpha) const
 {
     if (isExtended())
-        return Color { asExtended().invertedColorWithAlpha(alpha) };
-
-    auto [r, g, b, existingAlpha] = asSimpleColor();
-    return { 0xFF - r, 0xFF - g, 0xFF - b, colorFloatToSimpleColorByte(alpha) };
+        return asExtended().invertedColorWithAlpha(alpha);
+    return asSimple().invertedColorWithAlpha(scaleRoundAndClampColorChannel(alpha));
 }
 
 Color Color::semanticColor() const
@@ -308,38 +306,23 @@ Color Color::semanticColor() const
 
 std::pair<ColorSpace, ColorComponents<float>> Color::colorSpaceAndComponents() const
 {
-    if (isExtended()) {
-        auto& extendedColor = asExtended();
-        return { extendedColor.colorSpace(), extendedColor.channels() };
-    }
-
-    auto [r, g, b, a] = asSimpleColor();
-    return { ColorSpace::SRGB, ColorComponents<float> { r / 255.0f, g / 255.0f, b / 255.0f,  a / 255.0f } };
+    if (isExtended())
+        return { asExtended().colorSpace(), asExtended().components() };
+    return { ColorSpace::SRGB, asSimple().asSRGBFloatComponents() };
 }
 
 SimpleColor Color::toSRGBASimpleColorLossy() const
 {
-    if (isExtended()) {
-        auto [r, g, b, a] = toSRGBAComponentsLossy();
-        return makeSimpleColorFromFloats(r, g, b, a);
-    }
-
-    return asSimpleColor();
+    if (isExtended())
+        return makeSimpleColor(toSRGBAComponentsLossy());
+    return asSimple();
 }
 
 ColorComponents<float> Color::toSRGBAComponentsLossy() const
 {
-    auto [colorSpace, components] = colorSpaceAndComponents();
-    switch (colorSpace) {
-    case ColorSpace::SRGB:
-        return components;
-    case ColorSpace::LinearRGB:
-        return linearToRGBComponents(components);
-    case ColorSpace::DisplayP3:
-        return p3ToSRGB(components);
-    }
-    ASSERT_NOT_REACHED();
-    return { };
+    if (isExtended())
+        return asExtended().toSRGBAComponentsLossy();
+    return asSimple().asSRGBFloatComponents();
 }
 
 bool extendedColorsEqual(const Color& a, const Color& b)
index 8aeed97..223cf29 100644 (file)
@@ -140,11 +140,11 @@ public:
 
     bool isValid() const { return isExtended() || (m_colorData.simpleColorAndFlags & validSimpleColorBit); }
 
-    bool isOpaque() const { return isExtended() ? asExtended().alpha() == 1.0 : asSimpleColor().isOpaque(); }
-    bool isVisible() const { return isExtended() ? asExtended().alpha() > 0.0 : asSimpleColor().isVisible(); }
+    bool isOpaque() const { return isExtended() ? asExtended().alpha() == 1.0 : asSimple().isOpaque(); }
+    bool isVisible() const { return isExtended() ? asExtended().alpha() > 0.0 : asSimple().isVisible(); }
 
-    int alpha() const { return isExtended() ? asExtended().alpha() * 255 : asSimpleColor().alphaComponent(); }
-    float alphaAsFloat() const { return isExtended() ? asExtended().alpha() : asSimpleColor().alphaComponentAsFloat(); }
+    int alpha() const { return isExtended() ? asExtended().alpha() * 255 : asSimple().alphaComponent(); }
+    float alphaAsFloat() const { return isExtended() ? asExtended().alpha() : asSimple().alphaComponentAsFloat(); }
 
     unsigned hash() const;
 
@@ -232,7 +232,7 @@ public:
     template<class Decoder> static Optional<Color> decode(Decoder&);
 
 private:
-    const SimpleColor asSimpleColor() const;
+    const SimpleColor asSimple() const;
 
     void setSimpleColor(SimpleColor);
     void setIsSemantic() { m_colorData.simpleColorAndFlags |= isSemanticSimpleColorBit; }
@@ -318,7 +318,7 @@ inline const ExtendedColor& Color::asExtended() const
     return *m_colorData.extendedColor;
 }
 
-inline const SimpleColor Color::asSimpleColor() const
+inline const SimpleColor Color::asSimple() const
 {
     ASSERT(!isExtended());
     return { static_cast<uint32_t>(m_colorData.simpleColorAndFlags >> 32) };
@@ -334,14 +334,14 @@ inline bool Color::isBlackColor(const Color& color)
 {
     if (color.isExtended())
         return color.asExtended().isBlack();
-    return color.asSimpleColor() == Color::black;
+    return color.asSimple() == Color::black;
 }
 
 inline bool Color::isWhiteColor(const Color& color)
 {
     if (color.isExtended())
         return color.asExtended().isWhite();
-    return color.asSimpleColor() == Color::white;
+    return color.asSimple() == Color::white;
 }
 
 template<class Encoder>
@@ -351,7 +351,7 @@ void Color::encode(Encoder& encoder) const
         encoder << true;
 
         auto& extendedColor = asExtended();
-        auto [c1, c2, c3, alpha] = extendedColor.channels();
+        auto [c1, c2, c3, alpha] = extendedColor.components();
         encoder << c1;
         encoder << c2;
         encoder << c3;
@@ -370,7 +370,7 @@ void Color::encode(Encoder& encoder) const
     // FIXME: This should encode whether the color is semantic.
 
     encoder << true;
-    encoder << asSimpleColor().value();
+    encoder << asSimple().value();
 }
 
 template<class Decoder>
index fc35bbb..d36a358 100644 (file)
@@ -49,6 +49,9 @@ struct ColorComponents {
 
     constexpr ColorComponents abs() const;
 
+    constexpr T& operator[](size_t i) { return components[i]; }
+    constexpr const T& operator[](size_t i) const { return components[i]; }
+
     template<std::size_t N>
     constexpr T get() const;
 
@@ -58,10 +61,10 @@ struct ColorComponents {
 template<typename T>
 constexpr ColorComponents<T>& ColorComponents<T>::operator+=(const ColorComponents& rhs)
 {
-    components[0] += rhs.components[0];
-    components[1] += rhs.components[1];
-    components[2] += rhs.components[2];
-    components[3] += rhs.components[3];
+    components[0] += rhs[0];
+    components[1] += rhs[1];
+    components[2] += rhs[2];
+    components[3] += rhs[3];
     return *this;
 }
 
@@ -120,10 +123,10 @@ template<typename T>
 constexpr ColorComponents<T> perComponentMax(const ColorComponents<T>& a, const ColorComponents<T>& b)
 {
     return {
-        std::max(a.components[0], b.components[0]),
-        std::max(a.components[1], b.components[1]),
-        std::max(a.components[2], b.components[2]),
-        std::max(a.components[3], b.components[3])
+        std::max(a[0], b[0]),
+        std::max(a[1], b[1]),
+        std::max(a[2], b[2]),
+        std::max(a[3], b[3])
     };
 }
 
@@ -131,10 +134,10 @@ template<typename T>
 constexpr ColorComponents<T> perComponentMin(const ColorComponents<T>& a, const ColorComponents<T>& b)
 {
     return {
-        std::min(a.components[0], b.components[0]),
-        std::min(a.components[1], b.components[1]),
-        std::min(a.components[2], b.components[2]),
-        std::min(a.components[3], b.components[3])
+        std::min(a[0], b[0]),
+        std::min(a[1], b[1]),
+        std::min(a[2], b[2]),
+        std::min(a[3], b[3])
     };
 }
 
index 172dbe8..aa339fa 100644 (file)
@@ -115,17 +115,17 @@ constexpr ColorComponents<float> ColorMatrix<Columns, Rows>::transformedColorCom
     for (size_t row = 0; row < Rows; ++row) {
         if constexpr (Columns <= ColorComponents<float>::Size) {
             for (size_t column = 0; column < Columns; ++column)
-                result.components[row] += at(row, column) * inputVector.components[column];
+                result[row] += at(row, column) * inputVector[column];
         } else if constexpr (Columns > ColorComponents<float>::Size) {
             for (size_t column = 0; column < ColorComponents<float>::Size; ++column)
-                result.components[row] += at(row, column) * inputVector.components[column];
+                result[row] += at(row, column) * inputVector[column];
             for (size_t additionalColumn = ColorComponents<float>::Size; additionalColumn < Columns; ++additionalColumn)
-                result.components[row] += at(row, additionalColumn);
+                result[row] += at(row, additionalColumn);
         }
     }
     if constexpr (ColorComponents<float>::Size > Rows) {
         for (size_t additionalRow = Rows; additionalRow < ColorComponents<float>::Size; ++additionalRow)
-            result.components[additionalRow] = inputVector.components[additionalRow];
+            result[additionalRow] = inputVector[additionalRow];
     }
 
     return result;
index 19cecbf..417cc20 100644 (file)
@@ -33,10 +33,10 @@ namespace WebCore {
 
 bool areEssentiallyEqual(const ColorComponents<float>& a, const ColorComponents<float>& b)
 {
-    return WTF::areEssentiallyEqual(a.components[0], b.components[0])
-        && WTF::areEssentiallyEqual(a.components[1], b.components[1])
-        && WTF::areEssentiallyEqual(a.components[2], b.components[2])
-        && WTF::areEssentiallyEqual(a.components[3], b.components[3]);
+    return WTF::areEssentiallyEqual(a[0], b[0])
+        && WTF::areEssentiallyEqual(a[1], b[1])
+        && WTF::areEssentiallyEqual(a[2], b[2])
+        && WTF::areEssentiallyEqual(a[3], b[3]);
 }
 
 // These are the standard sRGB <-> linearRGB conversion functions (https://en.wikipedia.org/wiki/SRGB).
@@ -59,20 +59,20 @@ float rgbToLinearColorComponent(float c)
 ColorComponents<float> rgbToLinearComponents(const ColorComponents<float>& RGBColor)
 {
     return {
-        rgbToLinearColorComponent(RGBColor.components[0]),
-        rgbToLinearColorComponent(RGBColor.components[1]),
-        rgbToLinearColorComponent(RGBColor.components[2]),
-        RGBColor.components[3]
+        rgbToLinearColorComponent(RGBColor[0]),
+        rgbToLinearColorComponent(RGBColor[1]),
+        rgbToLinearColorComponent(RGBColor[2]),
+        RGBColor[3]
     };
 }
 
 ColorComponents<float> linearToRGBComponents(const ColorComponents<float>& linearRGB)
 {
     return {
-        linearToRGBColorComponent(linearRGB.components[0]),
-        linearToRGBColorComponent(linearRGB.components[1]),
-        linearToRGBColorComponent(linearRGB.components[2]),
-        linearRGB.components[3]
+        linearToRGBColorComponent(linearRGB[0]),
+        linearToRGBColorComponent(linearRGB[1]),
+        linearToRGBColorComponent(linearRGB[2]),
+        linearRGB[3]
     };
 }
 
@@ -142,8 +142,7 @@ float lightness(const ColorComponents<float>& sRGBCompontents)
 {
     auto [r, g, b, a] = sRGBCompontents;
 
-    float max = std::max({ r, g, b });
-    float min = std::min({ r, g, b });
+    auto [min, max] = std::minmax({ r, g, b });
 
     return 0.5f * (max + min);
 }
@@ -162,9 +161,9 @@ static float sRGBToLinearColorComponentForLuminance(float c)
 float luminance(const ColorComponents<float>& sRGBComponents)
 {
     // Values from https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
-    return 0.2126f * sRGBToLinearColorComponentForLuminance(sRGBComponents.components[0])
-        + 0.7152f * sRGBToLinearColorComponentForLuminance(sRGBComponents.components[1])
-        + 0.0722f * sRGBToLinearColorComponentForLuminance(sRGBComponents.components[2]);
+    return 0.2126f * sRGBToLinearColorComponentForLuminance(sRGBComponents[0])
+        + 0.7152f * sRGBToLinearColorComponentForLuminance(sRGBComponents[1])
+        + 0.0722f * sRGBToLinearColorComponentForLuminance(sRGBComponents[2]);
 }
 
 float contrastRatio(const ColorComponents<float>& componentsA, const ColorComponents<float>& componentsB)
@@ -185,8 +184,7 @@ ColorComponents<float> sRGBToHSL(const ColorComponents<float>& sRGBCompontents)
     // http://en.wikipedia.org/wiki/HSL_color_space.
     auto [r, g, b, alpha] = sRGBCompontents;
 
-    float max = std::max({ r, g, b });
-    float min = std::min({ r, g, b });
+    auto [min, max] = std::minmax({ r, g, b });
     float chroma = max - min;
 
     float hue;
@@ -242,9 +240,7 @@ static float calcHue(float temp1, float temp2, float hueVal)
 // further explanation available at http://en.wikipedia.org/wiki/HSL_color_space
 ColorComponents<float> hslToSRGB(const ColorComponents<float>& hslColor)
 {
-    float hue = hslColor.components[0];
-    float saturation = hslColor.components[1];
-    float lightness = hslColor.components[2];
+    auto [hue, saturation, lightness, alpha] = hslColor;
 
     // Convert back to RGB.
     if (!saturation) {
@@ -252,7 +248,7 @@ ColorComponents<float> hslToSRGB(const ColorComponents<float>& hslColor)
             lightness,
             lightness,
             lightness,
-            hslColor.components[3]
+            alpha
         };
     }
     
@@ -264,7 +260,7 @@ ColorComponents<float> hslToSRGB(const ColorComponents<float>& hslColor)
         calcHue(temp1, temp2, hue + 2.0f),
         calcHue(temp1, temp2, hue),
         calcHue(temp1, temp2, hue - 2.0f),
-        hslColor.components[3]
+        alpha
     };
 }
 
index 9be04c7..94fcb48 100644 (file)
@@ -63,6 +63,11 @@ inline uint8_t roundAndClampColorChannel(float value)
     return std::clamp(std::round(value), 0.f, 255.f);
 }
 
+inline uint8_t scaleRoundAndClampColorChannel(float f)
+{
+    return std::clamp(static_cast<int>(lroundf(255.0f * f)), 0, 255);
+}
+
 constexpr uint16_t fastMultiplyBy255(uint16_t value)
 {
     return (value << 8) - value;
@@ -77,9 +82,5 @@ constexpr uint16_t fastDivideBy255(uint16_t value)
     return approximation + (remainder >> 8);
 }
 
-inline uint8_t colorFloatToSimpleColorByte(float f)
-{
-    return std::clamp(static_cast<int>(lroundf(255.0f * f)), 0, 255);
-}
 
 } // namespace WebCore
index 44294d4..ec2faab 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "ExtendedColor.h"
 
+#include "ColorUtilities.h"
 #include <wtf/Hasher.h>
 #include <wtf/MathExtras.h>
 #include <wtf/text/StringConcatenateNumbers.h>
@@ -39,7 +40,7 @@ Ref<ExtendedColor> ExtendedColor::create(float c1, float c2, float c3, float alp
 
 unsigned ExtendedColor::hash() const
 {
-    auto [c1, c2, c3, alpha] = channels();
+    auto [c1, c2, c3, alpha] = components();
     return computeHash(c1, c2, c3, alpha, m_colorSpace);
 }
 
@@ -58,7 +59,7 @@ String ExtendedColor::cssText() const
         return WTF::emptyString();
     }
 
-    auto [c1, c2, c3, existingAlpha] = channels();
+    auto [c1, c2, c3, existingAlpha] = components();
 
     if (WTF::areEssentiallyEqual(alpha(), 1.0f))
         return makeString("color(", colorSpace, ' ', c1, ' ', c2, ' ', c3, ')');
@@ -68,25 +69,39 @@ String ExtendedColor::cssText() const
 
 Ref<ExtendedColor> ExtendedColor::colorWithAlpha(float overrideAlpha) const
 {
-    auto [c1, c2, c3, existingAlpha] = channels();
+    auto [c1, c2, c3, existingAlpha] = components();
     return ExtendedColor::create(c1, c2, c3, overrideAlpha, colorSpace());
 }
 
 Ref<ExtendedColor> ExtendedColor::invertedColorWithAlpha(float overrideAlpha) const
 {
-    auto [c1, c2, c3, existingAlpha] = channels();
+    auto [c1, c2, c3, existingAlpha] = components();
     return ExtendedColor::create(1.0f - c1, 1.0f - c2, 1.0f - c3, overrideAlpha, colorSpace());
 }
 
+ColorComponents<float> ExtendedColor::toSRGBAComponentsLossy() const
+{
+    switch (m_colorSpace) {
+    case ColorSpace::SRGB:
+        return m_components;
+    case ColorSpace::LinearRGB:
+        return linearToRGBComponents(m_components);
+    case ColorSpace::DisplayP3:
+        return p3ToSRGB(m_components);
+    }
+    ASSERT_NOT_REACHED();
+    return { };
+}
+
 bool ExtendedColor::isWhite() const
 {
-    auto [c1, c2, c3, alpha] = channels();
+    auto [c1, c2, c3, alpha] = components();
     return c1 == 1 && c2 == 1 && c3 == 1 && alpha == 1;
 }
 
 bool ExtendedColor::isBlack() const
 {
-    auto [c1, c2, c3, alpha] = channels();
+    auto [c1, c2, c3, alpha] = components();
     return !c1 && !c2 && !c3 && alpha == 1;
 }
 
index e490522..a480eda 100644 (file)
@@ -37,9 +37,9 @@ class ExtendedColor : public RefCounted<ExtendedColor> {
 public:
     static Ref<ExtendedColor> create(float, float, float, float alpha, ColorSpace = ColorSpace::SRGB);
 
-    float alpha() const { return m_channels.components[3]; }
+    float alpha() const { return m_components[3]; }
 
-    const ColorComponents<float>& channels() const { return m_channels; }
+    const ColorComponents<float>& components() const { return m_components; }
     ColorSpace colorSpace() const { return m_colorSpace; }
 
     WEBCORE_EXPORT unsigned hash() const;
@@ -49,22 +49,24 @@ public:
     Ref<ExtendedColor> colorWithAlpha(float) const;
     Ref<ExtendedColor> invertedColorWithAlpha(float) const;
 
+    ColorComponents<float> toSRGBAComponentsLossy() const;
+
     bool isWhite() const;
     bool isBlack() const;
 
 private:
     ExtendedColor(float c1, float c2, float c3, float alpha, ColorSpace colorSpace)
-        : m_channels(c1, c2, c3, alpha)
+        : m_components(c1, c2, c3, alpha)
         , m_colorSpace(colorSpace)
     { }
 
-    ColorComponents<float> m_channels;
+    ColorComponents<float> m_components;
     ColorSpace m_colorSpace { ColorSpace::SRGB };
 };
 
 inline bool operator==(const ExtendedColor& a, const ExtendedColor& b)
 {
-    return a.colorSpace() == b.colorSpace() && a.channels() == b.channels();
+    return a.colorSpace() == b.colorSpace() && a.components() == b.components();
 }
 
 inline bool operator!=(const ExtendedColor& a, const ExtendedColor& b)
index 09a048d..fce7746 100644 (file)
@@ -69,18 +69,23 @@ SimpleColor makeUnpremultipliedSimpleColor(SimpleColor pixelColor)
 
 SimpleColor makeSimpleColorFromFloats(float r, float g, float b, float a)
 {
-    return makeSimpleColor(colorFloatToSimpleColorByte(r), colorFloatToSimpleColorByte(g), colorFloatToSimpleColorByte(b), colorFloatToSimpleColorByte(a));
+    return makeSimpleColor(
+        scaleRoundAndClampColorChannel(r),
+        scaleRoundAndClampColorChannel(g),
+        scaleRoundAndClampColorChannel(b),
+        scaleRoundAndClampColorChannel(a)
+    );
 }
 
 SimpleColor makeSimpleColorFromHSLA(float hue, float saturation, float lightness, float alpha)
 {
-    const float scaleFactor = 255.0;
-    auto floatResult = hslToSRGB({ hue, saturation, lightness, alpha });
+    auto [r, g, b, a] = hslToSRGB({ hue, saturation, lightness, alpha });
     return makeSimpleColor(
-        round(floatResult.components[0] * scaleFactor),
-        round(floatResult.components[1] * scaleFactor),
-        round(floatResult.components[2] * scaleFactor),
-        round(floatResult.components[3] * scaleFactor));
+        round(r * 255.0f),
+        round(g * 255.0f),
+        round(b * 255.0f),
+        round(a * 255.0f)
+    );
 }
 
 SimpleColor makeSimpleColorFromCMYKA(float c, float m, float y, float k, float a)
index bcab9d1..f848d49 100644 (file)
@@ -31,11 +31,12 @@ namespace WebCore {
 
 // Color value with 8-bit components for red, green, blue, and alpha.
 // For historical reasons, stored as a 32-bit integer, with alpha in the high bits: ARGB.
-// FIXME: This class should be consolidated with ColorComponents.
 class SimpleColor {
 public:
     constexpr SimpleColor(uint32_t value = 0) : m_value { value } { }
+    constexpr SimpleColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : m_value { static_cast<unsigned>(a << 24 | r << 16 | g << 8 | b) } { }
 
+    constexpr uint32_t valueAsARGB() const { return m_value; }
     constexpr uint32_t value() const { return m_value; }
 
     constexpr uint8_t redComponent() const { return m_value >> 16; }
@@ -52,7 +53,20 @@ public:
     String serializationForCSS() const;
     String serializationForRenderTreeAsText() const;
 
-    constexpr SimpleColor colorWithAlpha(uint8_t alpha) const { return { (m_value & 0x00FFFFFF) | alpha << 24 }; }
+    constexpr SimpleColor colorWithAlpha(uint8_t alpha) const
+    {
+        return { (m_value & 0x00FFFFFF) | alpha << 24 };
+    }
+
+    constexpr SimpleColor invertedColorWithAlpha(uint8_t alpha) const
+    {
+        return { static_cast<uint8_t>(0xFF - redComponent()), static_cast<uint8_t>(0xFF - greenComponent()), static_cast<uint8_t>(0xFF - blueComponent()), alpha };
+    }
+
+    constexpr ColorComponents<float> asSRGBFloatComponents() const
+    {
+        return { redComponent() / 255.0f, greenComponent() / 255.0f, blueComponent() / 255.0f,  alphaComponent() / 255.0f };
+    }
 
     template<std::size_t N>
     constexpr uint8_t get() const
@@ -78,6 +92,8 @@ bool operator!=(SimpleColor, SimpleColor);
 constexpr SimpleColor makeSimpleColor(int r, int g, int b);
 constexpr SimpleColor makeSimpleColor(int r, int g, int b, int a);
 
+SimpleColor makeSimpleColor(const ColorComponents<float>& sRGBComponents);
+
 SimpleColor makePremultipliedSimpleColor(int r, int g, int b, int a, bool ceiling = true);
 SimpleColor makePremultipliedSimpleColor(SimpleColor);
 SimpleColor makeUnpremultipliedSimpleColor(int r, int g, int b, int a);
@@ -87,7 +103,6 @@ WEBCORE_EXPORT SimpleColor makeSimpleColorFromFloats(float r, float g, float b,
 WEBCORE_EXPORT SimpleColor makeSimpleColorFromHSLA(float h, float s, float l, float a);
 SimpleColor makeSimpleColorFromCMYKA(float c, float m, float y, float k, float a);
 
-
 inline bool operator==(SimpleColor a, SimpleColor b)
 {
     return a.value() == b.value();
@@ -105,7 +120,18 @@ constexpr SimpleColor makeSimpleColor(int r, int g, int b)
 
 constexpr SimpleColor makeSimpleColor(int r, int g, int b, int a)
 {
-    return { static_cast<unsigned>(std::clamp(a, 0, 0xFF) << 24 | std::clamp(r, 0, 0xFF) << 16 | std::clamp(g, 0, 0xFF) << 8 | std::clamp(b, 0, 0xFF)) };
+    return { static_cast<uint8_t>(std::clamp(r, 0, 0xFF)), static_cast<uint8_t>(std::clamp(g, 0, 0xFF)), static_cast<uint8_t>(std::clamp(b, 0, 0xFF)), static_cast<uint8_t>(std::clamp(a, 0, 0xFF)) };
+}
+
+inline SimpleColor makeSimpleColor(const ColorComponents<float>& sRGBComponents)
+{
+    auto [r, g, b, a] = sRGBComponents;
+    return makeSimpleColor(
+        scaleRoundAndClampColorChannel(r),
+        scaleRoundAndClampColorChannel(g),
+        scaleRoundAndClampColorChannel(b),
+        scaleRoundAndClampColorChannel(a)
+    );
 }
 
 } // namespace WebCore
index 822c04c..a2d926e 100644 (file)
@@ -130,7 +130,7 @@ static CGColorRef leakCGColor(const Color& color)
 CGColorRef cachedCGColor(const Color& color)
 {
     if (!color.isExtended()) {
-        switch (color.asSimpleColor().value()) {
+        switch (color.asSimple().value()) {
         case Color::transparent.value(): {
             static CGColorRef transparentCGColor = leakCGColor(color);
             return transparentCGColor;
@@ -146,7 +146,7 @@ CGColorRef cachedCGColor(const Color& color)
         }
     }
 
-    ASSERT(color.isExtended() || color.asSimpleColor().value());
+    ASSERT(color.isExtended() || color.asSimple().value());
 
     static NeverDestroyed<TinyLRUCache<Color, RetainPtr<CGColorRef>, 32>> cache;
     return cache.get().get(color).get();
index 68a191f..28974c0 100644 (file)
@@ -405,7 +405,7 @@ bool FELighting::drawLighting(Uint8ClampedArray& pixels, int width, int height)
     data.heightDecreasedByOne = height - 1;
     
     auto lightColor = (operatingColorSpace() == ColorSpace::LinearRGB) ? rgbToLinearComponents(m_lightingColor.toSRGBAComponentsLossy()) : m_lightingColor.toSRGBAComponentsLossy();
-    paintingData.initialLightingData.colorVector = FloatPoint3D(lightColor.components[0], lightColor.components[1], lightColor.components[2]);
+    paintingData.initialLightingData.colorVector = FloatPoint3D(lightColor[0], lightColor[1], lightColor[2]);
     m_lightSource->initPaintingData(*this, paintingData);
 
     // Top left.
index ec0ff7f..9ba50ee 100644 (file)
@@ -325,10 +325,10 @@ ColorComponents<float> FETurbulence::noise2D(const PaintingData& paintingData, c
 static inline ColorComponents<uint8_t> toIntBasedColorComponents(const ColorComponents<float>& floatComponents)
 {
     return {
-        std::clamp<uint8_t>(static_cast<int>(floatComponents.components[0] * 255), 0, 255),
-        std::clamp<uint8_t>(static_cast<int>(floatComponents.components[1] * 255), 0, 255),
-        std::clamp<uint8_t>(static_cast<int>(floatComponents.components[2] * 255), 0, 255),
-        std::clamp<uint8_t>(static_cast<int>(floatComponents.components[3] * 255), 0, 255),
+        std::clamp<uint8_t>(static_cast<int>(floatComponents[0] * 255), 0, 255),
+        std::clamp<uint8_t>(static_cast<int>(floatComponents[1] * 255), 0, 255),
+        std::clamp<uint8_t>(static_cast<int>(floatComponents[2] * 255), 0, 255),
+        std::clamp<uint8_t>(static_cast<int>(floatComponents[3] * 255), 0, 255),
     };
 }
 
index ad41948..c4b77d4 100644 (file)
@@ -156,26 +156,26 @@ bool BasicComponentTransferFilterOperation::transformColor(ColorComponents<float
 {
     switch (m_type) {
     case OPACITY:
-        colorComponents.components[3] *= m_amount;
+        colorComponents[3] *= m_amount;
         return true;
     case INVERT: {
         float oneMinusAmount = 1.f - m_amount;
-        colorComponents.components[0] = 1 - (oneMinusAmount + colorComponents.components[0] * (m_amount - oneMinusAmount));
-        colorComponents.components[1] = 1 - (oneMinusAmount + colorComponents.components[1] * (m_amount - oneMinusAmount));
-        colorComponents.components[2] = 1 - (oneMinusAmount + colorComponents.components[2] * (m_amount - oneMinusAmount));
+        colorComponents[0] = 1 - (oneMinusAmount + colorComponents[0] * (m_amount - oneMinusAmount));
+        colorComponents[1] = 1 - (oneMinusAmount + colorComponents[1] * (m_amount - oneMinusAmount));
+        colorComponents[2] = 1 - (oneMinusAmount + colorComponents[2] * (m_amount - oneMinusAmount));
         return true;
     }
     case CONTRAST: {
         float intercept = -(0.5f * m_amount) + 0.5f;
-        colorComponents.components[0] = clampTo<float>(intercept + m_amount * colorComponents.components[0], 0, 1);
-        colorComponents.components[1] = clampTo<float>(intercept + m_amount * colorComponents.components[1], 0, 1);
-        colorComponents.components[2] = clampTo<float>(intercept + m_amount * colorComponents.components[2], 0, 1);
+        colorComponents[0] = clampTo<float>(intercept + m_amount * colorComponents[0], 0, 1);
+        colorComponents[1] = clampTo<float>(intercept + m_amount * colorComponents[1], 0, 1);
+        colorComponents[2] = clampTo<float>(intercept + m_amount * colorComponents[2], 0, 1);
         return true;
     }
     case BRIGHTNESS:
-        colorComponents.components[0] = std::max<float>(m_amount * colorComponents.components[0], 0);
-        colorComponents.components[1] = std::max<float>(m_amount * colorComponents.components[1], 0);
-        colorComponents.components[2] = std::max<float>(m_amount * colorComponents.components[2], 0);
+        colorComponents[0] = std::max<float>(m_amount * colorComponents[0], 0);
+        colorComponents[1] = std::max<float>(m_amount * colorComponents[1], 0);
+        colorComponents[2] = std::max<float>(m_amount * colorComponents[2], 0);
         return true;
     default:
         ASSERT_NOT_REACHED();
@@ -231,7 +231,7 @@ bool InvertLightnessFilterOperation::transformColor(ColorComponents<float>& sRGB
     auto hslComponents = sRGBToHSL(sRGBColorComponents);
     
     // Rotate the hue 180deg.
-    hslComponents.components[0] = fmod(hslComponents.components[0] + 0.5f, 1.0f);
+    hslComponents[0] = fmod(hslComponents[0] + 0.5f, 1.0f);
     
     // Convert back to RGB.
     sRGBColorComponents = hslToSRGB(hslComponents);
@@ -261,7 +261,7 @@ bool InvertLightnessFilterOperation::inverseTransformColor(ColorComponents<float
     // Convert to HSL.
     auto hslComponents = sRGBToHSL(rgbComponents);
     // Hue rotate by 180deg.
-    hslComponents.components[0] = fmod(hslComponents.components[0] + 0.5f, 1.0f);
+    hslComponents[0] = fmod(hslComponents[0] + 0.5f, 1.0f);
     // And return RGB.
     sRGBColorComponents = hslToSRGB(hslComponents);
     return true;
index 65ce55c..c8c14c1 100644 (file)
@@ -111,15 +111,14 @@ bool FilterOperations::transformColor(Color& color) const
     if (color.isSemantic())
         return false;
 
-    auto components = color.toSRGBAComponentsLossy();
+    auto sRGBAComponents = color.toSRGBAComponentsLossy();
 
     for (auto& operation : m_operations) {
-        if (!operation->transformColor(components))
+        if (!operation->transformColor(sRGBAComponents))
             return false;
     }
 
-    auto [r, g, b, a] = components;
-    color = makeSimpleColorFromFloats(r, g, b, a);
+    color = makeSimpleColor(sRGBAComponents);
     return true;
 }
 
@@ -131,15 +130,14 @@ bool FilterOperations::inverseTransformColor(Color& color) const
     if (color.isSemantic())
         return false;
 
-    auto components = color.toSRGBAComponentsLossy();
+    auto sRGBAComponents = color.toSRGBAComponentsLossy();
 
     for (auto& operation : m_operations) {
-        if (!operation->inverseTransformColor(components))
+        if (!operation->inverseTransformColor(sRGBAComponents))
             return false;
     }
 
-    auto [r, g, b, a] = components;
-    color = makeSimpleColorFromFloats(r, g, b, a);
+    color = makeSimpleColor(sRGBAComponents);
     return true;
 }
 
index 479d265..4829bfc 100644 (file)
@@ -1,3 +1,14 @@
+2020-05-30  Sam Weinig  <weinig@apple.com>
+
+        Extended Color: Additional color cleanups
+        https://bugs.webkit.org/show_bug.cgi?id=212567
+
+        Reviewed by Simon Fraser.
+
+        * TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp:
+        (TestWebKitAPI::TEST):
+        Update for rename from ExtendedColor::channels() to ExtendedColor::components()
+
 2020-05-30  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] WebDriver: stop using GdkEvent API in preparation for GTK4
index 03cbfa8..fb678f7 100644 (file)
@@ -39,7 +39,7 @@ TEST(ExtendedColor, Constructor)
     Color c1(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3);
     EXPECT_TRUE(c1.isExtended());
 
-    auto [r, g, b, alpha] = c1.asExtended().channels();
+    auto [r, g, b, alpha] = c1.asExtended().components();
 
     EXPECT_FLOAT_EQ(1.0, r);
     EXPECT_FLOAT_EQ(0.5, g);
@@ -56,7 +56,7 @@ TEST(ExtendedColor, CopyConstructor)
 
     Color c2(c1);
 
-    auto [r, g, b, alpha] = c2.asExtended().channels();
+    auto [r, g, b, alpha] = c2.asExtended().components();
 
     EXPECT_FLOAT_EQ(1.0, r);
     EXPECT_FLOAT_EQ(0.5, g);
@@ -74,7 +74,7 @@ TEST(ExtendedColor, Assignment)
 
     Color c2 = c1;
 
-    auto [r, g, b, alpha] = c2.asExtended().channels();
+    auto [r, g, b, alpha] = c2.asExtended().components();
 
     EXPECT_FLOAT_EQ(1.0, r);
     EXPECT_FLOAT_EQ(0.5, g);
@@ -159,7 +159,7 @@ TEST(ExtendedColor, MoveConstructor)
     EXPECT_FALSE(c1.isExtended());
     EXPECT_FALSE(c1.isValid());
 
-    auto [r, g, b, alpha] = c2.asExtended().channels();
+    auto [r, g, b, alpha] = c2.asExtended().components();
 
     EXPECT_FLOAT_EQ(1.0, r);
     EXPECT_FLOAT_EQ(0.5, g);
@@ -181,7 +181,7 @@ TEST(ExtendedColor, MoveAssignment)
     EXPECT_FALSE(c1.isExtended());
     EXPECT_FALSE(c1.isValid());
 
-    auto [r, g, b, alpha] = c2.asExtended().channels();
+    auto [r, g, b, alpha] = c2.asExtended().components();
 
     EXPECT_FLOAT_EQ(1.0, r);
     EXPECT_FLOAT_EQ(0.5, g);
@@ -199,7 +199,7 @@ TEST(ExtendedColor, BasicReferenceCounting)
     Color* c2 = new Color(*c1);
     Color* c3 = new Color(*c2);
 
-    auto [r, g, b, alpha] = c2->asExtended().channels();
+    auto [r, g, b, alpha] = c2->asExtended().components();
 
     EXPECT_FLOAT_EQ(1.0, r);
     EXPECT_FLOAT_EQ(0.5, g);