Diff
Modified: trunk/Source/WebCore/ChangeLog (272435 => 272436)
--- trunk/Source/WebCore/ChangeLog 2021-02-05 20:48:22 UTC (rev 272435)
+++ trunk/Source/WebCore/ChangeLog 2021-02-05 21:08:34 UTC (rev 272436)
@@ -1,3 +1,80 @@
+2021-02-05 Sam Weinig <wei...@apple.com>
+
+ Generalize color conversion code to reduce number of overloads required
+ https://bugs.webkit.org/show_bug.cgi?id=221443
+
+ Reviewed by Darin Adler.
+
+ Replace overloaded named conversion functions (e.g. toSRGBA(), toLab(), etc.)
+ with template specializion of a new ColorConversion struct:
+
+ template<> struct ColorConversion<Output, Input> {
+ Output convert(const Input& color) { ... }
+ };
+
+ which is accessed via a new generic convertColor<ColorType>() function.
+
+ This allows for a few improvements:
+ - Removes the need for each color type to define an identity conversion.
+ - Removes the need for each color type to define an generic conversion.
+ - Allows integration with component type conversion so a call like
+
+ convertTo<SRGBA<uint8_t>>(toSRGBA(hsla))
+
+ can now be written just as
+
+ convertColor<SRGBA<uint8_t>>(hsla)
+
+ This also provides a path forward for more optimizations / simplifications
+ since we can now reason about conversion based purely on types.
+
+ * css/parser/CSSPropertyParserHelpers.cpp:
+ (WebCore::CSSPropertyParserHelpers::parseRGBParameters):
+ (WebCore::CSSPropertyParserHelpers::parseHSLParameters):
+ (WebCore::CSSPropertyParserHelpers::parseHWBParameters):
+ (WebCore::CSSPropertyParserHelpers::parseLabParameters):
+ (WebCore::CSSPropertyParserHelpers::parseLCHParameters):
+ (WebCore::CSSPropertyParserHelpers::parseColorFunctionParameters):
+ Switch to convertColor<> and replace some unnecessary type with auto.
+
+ * editing/cocoa/DataDetection.mm:
+ (WebCore::DataDetection::detectContentInRange):
+ Adopt Color::toColorTypeLossy<> and convertColor<>.
+
+ * platform/graphics/Color.cpp:
+ (WebCore::Color::invertedColorWithAlpha const):
+ Adopt convertColor<>.
+
+ * platform/graphics/Color.h:
+ (WebCore::Color::toSRGBALossy const):
+ (WebCore::Color::toColorTypeLossy const):
+ Add generic conversion function toColorTypeLossy<>() and re-implement
+ toSRGBALossy<>() using it.
+
+ * platform/graphics/ColorConversion.cpp:
+ * platform/graphics/ColorConversion.h:
+ Replace function overloads with explicit specialization of the new ColorConversion
+ struct. Replace identity functions and fallback functions with a single non-specialized
+ ColorConversion which uses constexpr to handle the identity case, conversion to/from
+ SRGBA<uint8_t> (the only non-float color) and the fallback case.
+
+ * platform/graphics/ColorUtilities.cpp:
+ (WebCore::luminance):
+ Adopt convertColor<>.
+
+ * platform/graphics/cg/ColorCG.cpp:
+ (WebCore::roundAndClampToSRGBALossy):
+ (WebCore::leakCGColor):
+ Adopt convertColor<>.
+
+ * platform/graphics/filters/FELighting.cpp:
+ (WebCore::FELighting::drawLighting):
+ Adopt toColorTypeLossy<>.
+
+ * rendering/RenderTheme.cpp:
+ (WebCore::RenderTheme::datePlaceholderTextColor const):
+ Adopt Color::toColorTypeLossy<> and convertColor<>.
+
2021-02-05 Antti Koivisto <an...@apple.com>
[LFC][Integration] Hit testing broken for descendants of pointer-events:none boxes
Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (272435 => 272436)
--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp 2021-02-05 20:48:22 UTC (rev 272435)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp 2021-02-05 21:08:34 UTC (rev 272436)
@@ -701,7 +701,7 @@
static Color parseRGBParameters(CSSParserTokenRange& range)
{
ASSERT(range.peek().functionId() == CSSValueRgb || range.peek().functionId() == CSSValueRgba);
- CSSParserTokenRange args = consumeFunction(range);
+ auto args = consumeFunction(range);
bool isPercentage = false;
double colorParameter;
@@ -772,7 +772,7 @@
static Color parseHSLParameters(CSSParserTokenRange& range, CSSParserMode cssParserMode)
{
ASSERT(range.peek().functionId() == CSSValueHsl || range.peek().functionId() == CSSValueHsla);
- CSSParserTokenRange args = consumeFunction(range);
+ auto args = consumeFunction(range);
double hueAngleInDegrees;
if (auto angle = consumeAngleRaw(args, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid))
@@ -815,7 +815,7 @@
if (!args.atEnd())
return { };
- return convertTo<SRGBA<uint8_t>>(toSRGBA(HSLA<float> { static_cast<float>(colorArray[0]), static_cast<float>(colorArray[1]), static_cast<float>(colorArray[2]), static_cast<float>(alpha) }));
+ return convertColor<SRGBA<uint8_t>>(HSLA<float> { static_cast<float>(colorArray[0]), static_cast<float>(colorArray[1]), static_cast<float>(colorArray[2]), static_cast<float>(alpha) });
}
static Optional<float> parseOptionalAlpha(CSSParserTokenRange& range)
@@ -832,7 +832,7 @@
static Color parseHWBParameters(CSSParserTokenRange& range, CSSParserMode cssParserMode)
{
ASSERT(range.peek().functionId() == CSSValueHwb);
- CSSParserTokenRange args = consumeFunction(range);
+ auto args = consumeFunction(range);
double hueAngleInDegrees;
if (auto angle = consumeAngleRaw(args, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid))
@@ -885,13 +885,13 @@
nomalizedWhiteness /= 100.0;
nomalizedBlackness /= 100.0;
- return convertTo<SRGBA<uint8_t>>(toSRGBA(HWBA<float> { static_cast<float>(normalizedHue), static_cast<float>(nomalizedWhiteness), static_cast<float>(nomalizedBlackness), static_cast<float>(*alpha) }));
+ return convertColor<SRGBA<uint8_t>>(HWBA<float> { static_cast<float>(normalizedHue), static_cast<float>(nomalizedWhiteness), static_cast<float>(nomalizedBlackness), static_cast<float>(*alpha) });
}
static Color parseLabParameters(CSSParserTokenRange& range)
{
ASSERT(range.peek().functionId() == CSSValueLab);
- CSSParserTokenRange args = consumeFunction(range);
+ auto args = consumeFunction(range);
auto lightness = consumePercentRaw(args, ValueRangeAll);
if (!lightness)
@@ -918,7 +918,7 @@
static Color parseLCHParameters(CSSParserTokenRange& range, CSSParserMode cssParserMode)
{
ASSERT(range.peek().functionId() == CSSValueLch);
- CSSParserTokenRange args = consumeFunction(range);
+ auto args = consumeFunction(range);
auto lightness = consumePercentRaw(args, ValueRangeAll);
if (!lightness)
@@ -947,7 +947,7 @@
if (!args.atEnd())
return { };
- return toLab(LCHA<float> { static_cast<float>(*lightness), static_cast<float>(*chromaValue), static_cast<float>(hueAngleInDegrees), *alpha });
+ return convertColor<Lab<float>>(LCHA<float> { static_cast<float>(*lightness), static_cast<float>(*chromaValue), static_cast<float>(hueAngleInDegrees), *alpha });
}
template<typename ColorType>
@@ -1034,7 +1034,7 @@
static Color parseColorFunctionParameters(CSSParserTokenRange& range)
{
ASSERT(range.peek().functionId() == CSSValueColor);
- CSSParserTokenRange args = consumeFunction(range);
+ auto args = consumeFunction(range);
Color color;
switch (args.peek().id()) {
Modified: trunk/Source/WebCore/editing/cocoa/DataDetection.mm (272435 => 272436)
--- trunk/Source/WebCore/editing/cocoa/DataDetection.mm 2021-02-05 20:48:22 UTC (rev 272435)
+++ trunk/Source/WebCore/editing/cocoa/DataDetection.mm 2021-02-05 21:08:34 UTC (rev 272436)
@@ -595,13 +595,16 @@
if (renderStyle) {
auto textColor = renderStyle->visitedDependentColor(CSSPropertyColor);
if (textColor.isValid()) {
- auto hsla = toHSLA(textColor.toSRGBALossy<float>());
+ // FIXME: Consider using LCHA<float> rather than HSLA<float> for better perceptual results and to avoid clamping to sRGB gamut, which is what HSLA does.
+ auto hsla = textColor.toColorTypeLossy<HSLA<float>>();
// Force the lightness of the underline color to the middle, and multiply the alpha by 38%,
// so the color will appear on light and dark backgrounds, since only one color can be specified.
hsla.lightness = 0.5f;
hsla.alpha *= 0.38f;
- auto underlineColor = convertTo<SRGBA<uint8_t>>(toSRGBA(hsla));
+
+ // FIXME: Consider keeping color in LCHA (if that change is made) or converting back to the initial underlying color type to avoid unnecessarily clamping colors outside of sRGB.
+ auto underlineColor = convertColor<SRGBA<uint8_t>>(hsla);
anchorElement->setInlineStyleProperty(CSSPropertyColor, CSSValueCurrentcolor);
anchorElement->setInlineStyleProperty(CSSPropertyTextDecorationColor, serializationForCSS(underlineColor));
Modified: trunk/Source/WebCore/platform/graphics/Color.cpp (272435 => 272436)
--- trunk/Source/WebCore/platform/graphics/Color.cpp 2021-02-05 20:48:22 UTC (rev 272435)
+++ trunk/Source/WebCore/platform/graphics/Color.cpp 2021-02-05 21:08:34 UTC (rev 272436)
@@ -149,7 +149,7 @@
if constexpr (ColorType::Model::isInvertible)
return invertedColorWithOverridenAlpha(underlyingColor, alpha);
else
- return invertedColorWithOverridenAlpha(toSRGBA(underlyingColor), alpha);
+ return invertedColorWithOverridenAlpha(convertColor<SRGBA<float>>(underlyingColor), alpha);
});
}
Modified: trunk/Source/WebCore/platform/graphics/Color.h (272435 => 272436)
--- trunk/Source/WebCore/platform/graphics/Color.h 2021-02-05 20:48:22 UTC (rev 272435)
+++ trunk/Source/WebCore/platform/graphics/Color.h 2021-02-05 21:08:34 UTC (rev 272436)
@@ -106,9 +106,15 @@
template<typename Functor> decltype(auto) callOnUnderlyingType(Functor&&) const;
- // This will convert non-sRGB colorspace colors into sRGB.
- template<typename T> SRGBA<T> toSRGBALossy() const;
+ // This will convert the underlying color into ColorType, potentially lossily if the gamut
+ // or precision of ColorType is smaller than the current underlying type.
+ template<typename ColorType> ColorType toColorTypeLossy() const;
+ // This will convert the underlying color into sRGB, potentially lossily if the gamut
+ // or precision of sRGB is smaller than the current underlying type. This is a convenience
+ // wrapper around toColorTypeLossy<>().
+ template<typename T> SRGBA<T> toSRGBALossy() const { return toColorTypeLossy<SRGBA<T>>(); }
+
WEBCORE_EXPORT std::pair<ColorSpace, ColorComponents<float>> colorSpaceAndComponents() const;
WEBCORE_EXPORT Color lightened() const;
@@ -321,22 +327,11 @@
return std::invoke(std::forward<Functor>(functor), asInline());
}
-template<typename T> SRGBA<T> Color::toSRGBALossy() const
+template<typename ColorType> ColorType Color::toColorTypeLossy() const
{
- return callOnUnderlyingType(WTF::makeVisitor(
- [] (const SRGBA<uint8_t>& color) {
- if constexpr (std::is_same_v<T, uint8_t>)
- return color;
- if constexpr (std::is_same_v<T, float>)
- return convertTo<SRGBA<float>>(color);
- },
- [] (const auto& color) {
- if constexpr (std::is_same_v<T, uint8_t>)
- return convertTo<SRGBA<uint8_t>>(toSRGBA(color));
- if constexpr (std::is_same_v<T, float>)
- return toSRGBA(color);
- }
- ));
+ return callOnUnderlyingType([] (const auto& underlyingColor) {
+ return convertColor<ColorType>(underlyingColor);
+ });
}
inline Color Color::invertedColorWithAlpha(Optional<float> alpha) const
Modified: trunk/Source/WebCore/platform/graphics/ColorConversion.cpp (272435 => 272436)
--- trunk/Source/WebCore/platform/graphics/ColorConversion.cpp 2021-02-05 20:48:22 UTC (rev 272435)
+++ trunk/Source/WebCore/platform/graphics/ColorConversion.cpp 2021-02-05 21:08:34 UTC (rev 272436)
@@ -159,12 +159,12 @@
// A98RGB <-> LinearA98RGB conversions.
-LinearA98RGB<float> toLinearA98RGB(const A98RGB<float>& color)
+LinearA98RGB<float> ColorConversion<LinearA98RGB<float>, A98RGB<float>>::convert(const A98RGB<float>& color)
{
return toLinear<A98RGBTransferFunction<float, TransferFunctionMode::Clamped>>(color);
}
-A98RGB<float> toA98RGB(const LinearA98RGB<float>& color)
+A98RGB<float> ColorConversion<A98RGB<float>, LinearA98RGB<float>>::convert(const LinearA98RGB<float>& color)
{
return toGammaEncoded<A98RGBTransferFunction<float, TransferFunctionMode::Clamped>>(color);
}
@@ -171,12 +171,12 @@
// DisplayP3 <-> LinearDisplayP3 conversions.
-LinearDisplayP3<float> toLinearDisplayP3(const DisplayP3<float>& color)
+LinearDisplayP3<float> ColorConversion<LinearDisplayP3<float>, DisplayP3<float>>::convert(const DisplayP3<float>& color)
{
return toLinear<SRGBTransferFunction<float, TransferFunctionMode::Clamped>>(color);
}
-DisplayP3<float> toDisplayP3(const LinearDisplayP3<float>& color)
+DisplayP3<float> ColorConversion<DisplayP3<float>, LinearDisplayP3<float>>::convert(const LinearDisplayP3<float>& color)
{
return toGammaEncoded<SRGBTransferFunction<float, TransferFunctionMode::Clamped>>(color);
}
@@ -183,12 +183,12 @@
// ExtendedSRGBA <-> LinearExtendedSRGBA conversions.
-LinearExtendedSRGBA<float> toLinearExtendedSRGBA(const ExtendedSRGBA<float>& color)
+LinearExtendedSRGBA<float> ColorConversion<LinearExtendedSRGBA<float>, ExtendedSRGBA<float>>::convert(const ExtendedSRGBA<float>& color)
{
return toLinear<SRGBTransferFunction<float, TransferFunctionMode::Unclamped>>(color);
}
-ExtendedSRGBA<float> toExtendedSRGBA(const LinearExtendedSRGBA<float>& color)
+ExtendedSRGBA<float> ColorConversion<ExtendedSRGBA<float>, LinearExtendedSRGBA<float>>::convert(const LinearExtendedSRGBA<float>& color)
{
return toGammaEncoded<SRGBTransferFunction<float, TransferFunctionMode::Unclamped>>(color);
}
@@ -195,12 +195,12 @@
// ProPhotoRGB <-> LinearProPhotoRGB conversions.
-LinearProPhotoRGB<float> toLinearProPhotoRGB(const ProPhotoRGB<float>& color)
+LinearProPhotoRGB<float> ColorConversion<LinearProPhotoRGB<float>, ProPhotoRGB<float>>::convert(const ProPhotoRGB<float>& color)
{
return toLinear<ProPhotoRGBTransferFunction<float, TransferFunctionMode::Clamped>>(color);
}
-ProPhotoRGB<float> toProPhotoRGB(const LinearProPhotoRGB<float>& color)
+ProPhotoRGB<float> ColorConversion<ProPhotoRGB<float>, LinearProPhotoRGB<float>>::convert(const LinearProPhotoRGB<float>& color)
{
return toGammaEncoded<ProPhotoRGBTransferFunction<float, TransferFunctionMode::Clamped>>(color);
}
@@ -207,12 +207,12 @@
// Rec2020 <-> LinearRec2020 conversions.
-LinearRec2020<float> toLinearRec2020(const Rec2020<float>& color)
+LinearRec2020<float> ColorConversion<LinearRec2020<float>, Rec2020<float>>::convert(const Rec2020<float>& color)
{
return toLinear<Rec2020TransferFunction<float, TransferFunctionMode::Clamped>>(color);
}
-Rec2020<float> toRec2020(const LinearRec2020<float>& color)
+Rec2020<float> ColorConversion<Rec2020<float>, LinearRec2020<float>>::convert(const LinearRec2020<float>& color)
{
return toGammaEncoded<Rec2020TransferFunction<float, TransferFunctionMode::Clamped>>(color);
}
@@ -219,12 +219,12 @@
// SRGBA <-> LinearSRGBA conversions.
-LinearSRGBA<float> toLinearSRGBA(const SRGBA<float>& color)
+LinearSRGBA<float> ColorConversion<LinearSRGBA<float>, SRGBA<float>>::convert(const SRGBA<float>& color)
{
return toLinear<SRGBTransferFunction<float, TransferFunctionMode::Clamped>>(color);
}
-SRGBA<float> toSRGBA(const LinearSRGBA<float>& color)
+SRGBA<float> ColorConversion<SRGBA<float>, LinearSRGBA<float>>::convert(const LinearSRGBA<float>& color)
{
return toGammaEncoded<SRGBTransferFunction<float, TransferFunctionMode::Clamped>>(color);
}
@@ -233,12 +233,12 @@
// - LinearA98RGB matrix conversions.
-LinearA98RGB<float> toLinearA98RGB(const LinearA98RGB<float>::ReferenceXYZ& color)
+LinearA98RGB<float> ColorConversion<LinearA98RGB<float>, LinearA98RGB<float>::ReferenceXYZ>::convert(const LinearA98RGB<float>::ReferenceXYZ& color)
{
return makeFromComponentsClampingExceptAlpha<LinearA98RGB<float>>(xyzToLinearA98RGBMatrix.transformedColorComponents(asColorComponents(color)));
}
-LinearA98RGB<float>::ReferenceXYZ toXYZA(const LinearA98RGB<float>& color)
+LinearA98RGB<float>::ReferenceXYZ ColorConversion<LinearA98RGB<float>::ReferenceXYZ, LinearA98RGB<float>>::convert(const LinearA98RGB<float>& color)
{
return makeFromComponentsClampingExceptAlpha<LinearA98RGB<float>::ReferenceXYZ>(linearA98RGBToXYZMatrix.transformedColorComponents(asColorComponents(color)));
}
@@ -245,12 +245,12 @@
// - LinearDisplayP3 matrix conversions.
-LinearDisplayP3<float> toLinearDisplayP3(const LinearDisplayP3<float>::ReferenceXYZ& color)
+LinearDisplayP3<float> ColorConversion<LinearDisplayP3<float>, LinearDisplayP3<float>::ReferenceXYZ>::convert(const LinearDisplayP3<float>::ReferenceXYZ& color)
{
return makeFromComponentsClampingExceptAlpha<LinearDisplayP3<float>>(xyzToLinearDisplayP3Matrix.transformedColorComponents(asColorComponents(color)));
}
-LinearDisplayP3<float>::ReferenceXYZ toXYZA(const LinearDisplayP3<float>& color)
+LinearDisplayP3<float>::ReferenceXYZ ColorConversion<LinearDisplayP3<float>::ReferenceXYZ, LinearDisplayP3<float>>::convert(const LinearDisplayP3<float>& color)
{
return makeFromComponentsClampingExceptAlpha<LinearDisplayP3<float>::ReferenceXYZ>(linearDisplayP3ToXYZMatrix.transformedColorComponents(asColorComponents(color)));
}
@@ -257,12 +257,12 @@
// - LinearExtendedSRGBA matrix conversions.
-LinearExtendedSRGBA<float> toLinearExtendedSRGBA(const LinearExtendedSRGBA<float>::ReferenceXYZ& color)
+LinearExtendedSRGBA<float> ColorConversion<LinearExtendedSRGBA<float>, LinearExtendedSRGBA<float>::ReferenceXYZ>::convert(const LinearExtendedSRGBA<float>::ReferenceXYZ& color)
{
return makeFromComponentsClampingExceptAlpha<LinearExtendedSRGBA<float>>(xyzToLinearSRGBMatrix.transformedColorComponents(asColorComponents(color)));
}
-LinearExtendedSRGBA<float>::ReferenceXYZ toXYZA(const LinearExtendedSRGBA<float>& color)
+LinearExtendedSRGBA<float>::ReferenceXYZ ColorConversion<LinearExtendedSRGBA<float>::ReferenceXYZ, LinearExtendedSRGBA<float>>::convert(const LinearExtendedSRGBA<float>& color)
{
return makeFromComponentsClampingExceptAlpha<LinearExtendedSRGBA<float>::ReferenceXYZ>(linearSRGBToXYZMatrix.transformedColorComponents(asColorComponents(color)));
}
@@ -269,12 +269,12 @@
// - LinearProPhotoRGB matrix conversions.
-LinearProPhotoRGB<float> toLinearProPhotoRGB(const LinearProPhotoRGB<float>::ReferenceXYZ& color)
+LinearProPhotoRGB<float> ColorConversion<LinearProPhotoRGB<float>, LinearProPhotoRGB<float>::ReferenceXYZ>::convert(const LinearProPhotoRGB<float>::ReferenceXYZ& color)
{
return makeFromComponentsClampingExceptAlpha<LinearProPhotoRGB<float>>(xyzToLinearProPhotoRGBMatrix.transformedColorComponents(asColorComponents(color)));
}
-LinearProPhotoRGB<float>::ReferenceXYZ toXYZA(const LinearProPhotoRGB<float>& color)
+LinearProPhotoRGB<float>::ReferenceXYZ ColorConversion<LinearProPhotoRGB<float>::ReferenceXYZ, LinearProPhotoRGB<float>>::convert(const LinearProPhotoRGB<float>& color)
{
return makeFromComponentsClampingExceptAlpha<LinearProPhotoRGB<float>::ReferenceXYZ>(linearProPhotoRGBToXYZMatrix.transformedColorComponents(asColorComponents(color)));
}
@@ -281,12 +281,12 @@
// - LinearRec2020 matrix conversions.
-LinearRec2020<float> toLinearRec2020(const LinearRec2020<float>::ReferenceXYZ& color)
+LinearRec2020<float> ColorConversion<LinearRec2020<float>, LinearRec2020<float>::ReferenceXYZ>::convert(const LinearRec2020<float>::ReferenceXYZ& color)
{
return makeFromComponentsClampingExceptAlpha<LinearRec2020<float>>(xyzToLinearRec2020Matrix.transformedColorComponents(asColorComponents(color)));
}
-LinearRec2020<float>::ReferenceXYZ toXYZA(const LinearRec2020<float>& color)
+LinearRec2020<float>::ReferenceXYZ ColorConversion<LinearRec2020<float>::ReferenceXYZ, LinearRec2020<float>>::convert(const LinearRec2020<float>& color)
{
return makeFromComponentsClampingExceptAlpha<LinearRec2020<float>::ReferenceXYZ>(linearRec2020ToXYZMatrix.transformedColorComponents(asColorComponents(color)));
}
@@ -293,12 +293,12 @@
// - LinearSRGBA matrix conversions.
-LinearSRGBA<float> toLinearSRGBA(const LinearSRGBA<float>::ReferenceXYZ& color)
+LinearSRGBA<float> ColorConversion<LinearSRGBA<float>, LinearSRGBA<float>::ReferenceXYZ>::convert(const LinearSRGBA<float>::ReferenceXYZ& color)
{
return makeFromComponentsClampingExceptAlpha<LinearSRGBA<float>>(xyzToLinearSRGBMatrix.transformedColorComponents(asColorComponents(color)));
}
-LinearSRGBA<float>::ReferenceXYZ toXYZA(const LinearSRGBA<float>& color)
+LinearSRGBA<float>::ReferenceXYZ ColorConversion<LinearSRGBA<float>::ReferenceXYZ, LinearSRGBA<float>>::convert(const LinearSRGBA<float>& color)
{
return makeFromComponentsClampingExceptAlpha<LinearSRGBA<float>::ReferenceXYZ>(linearSRGBToXYZMatrix.transformedColorComponents(asColorComponents(color)));
}
@@ -336,7 +336,7 @@
return { hue, min, max, chroma };
}
-HSLA<float> toHSLA(const SRGBA<float>& color)
+HSLA<float> ColorConversion<HSLA<float>, SRGBA<float>>::convert(const SRGBA<float>& color)
{
// https://drafts.csswg.org/css-color-4/#hsl-to-rgb
auto [r, g, b, alpha] = color;
@@ -354,7 +354,7 @@
return { hue, saturation, lightness, alpha };
}
-SRGBA<float> toSRGBA(const HSLA<float>& color)
+SRGBA<float> ColorConversion<SRGBA<float>, HSLA<float>>::convert(const HSLA<float>& color)
{
// https://drafts.csswg.org/css-color-4/#hsl-to-rgb
auto [hue, saturation, lightness, alpha] = color;
@@ -397,7 +397,7 @@
// MARK: HWB conversions.
-HWBA<float> toHWBA(const SRGBA<float>& color)
+HWBA<float> ColorConversion<HWBA<float>, SRGBA<float>>::convert(const SRGBA<float>& color)
{
// https://drafts.csswg.org/css-color-4/#rgb-to-hwb
auto [hue, min, max, chroma] = calculateHSLHue(color);
@@ -407,7 +407,7 @@
return { hue, whiteness, blackness, color.alpha };
}
-SRGBA<float> toSRGBA(const HWBA<float>& color)
+SRGBA<float> ColorConversion<SRGBA<float>, HWBA<float>>::convert(const HWBA<float>& color)
{
// https://drafts.csswg.org/css-color-4/#hwb-to-rgb
auto [hue, whiteness, blackness, alpha] = color;
@@ -415,7 +415,7 @@
if (whiteness + blackness == 1.0f)
return { whiteness, whiteness, whiteness, alpha };
- // This is the hueToRGB function in toSRGBA(const HSLA&) with temp1 == 0
+ // This is the hueToRGB function in convertColor<SRGBA<float>>(const HSLA&) with temp1 == 0
// and temp2 == 1 strength reduced through it.
auto hueToRGB = [](float hue) {
if (hue < 1.0f)
@@ -456,7 +456,7 @@
static constexpr float LABk = 24389.0f / 27.0f;
static constexpr float D50WhiteValues[] = { 0.96422f, 1.0f, 0.82521f };
-Lab<float>::ReferenceXYZ toXYZA(const Lab<float>& color)
+Lab<float>::ReferenceXYZ ColorConversion<Lab<float>::ReferenceXYZ, Lab<float>>::convert(const Lab<float>& color)
{
float f1 = (color.lightness + 16.0f) / 116.0f;
float f0 = f1 + (color.a / 500.0f);
@@ -486,7 +486,7 @@
return { x, y, z, color.alpha };
}
-Lab<float> toLab(const Lab<float>::ReferenceXYZ& color)
+Lab<float> ColorConversion<Lab<float>, Lab<float>::ReferenceXYZ>::convert(const Lab<float>::ReferenceXYZ& color)
{
float x = color.x / D50WhiteValues[0];
float y = color.y / D50WhiteValues[1];
@@ -510,7 +510,7 @@
// MARK: LCH conversions.
-LCHA<float> toLCHA(const Lab<float>& color)
+LCHA<float> ColorConversion<LCHA<float>, Lab<float>>::convert(const Lab<float>& color)
{
// https://www.w3.org/TR/css-color-4/#lab-to-lch
float hue = rad2deg(atan2(color.b, color.a));
@@ -523,7 +523,7 @@
};
}
-Lab<float> toLab(const LCHA<float>& color)
+Lab<float> ColorConversion<Lab<float>, LCHA<float>>::convert(const LCHA<float>& color)
{
// https://www.w3.org/TR/css-color-4/#lch-to-lab
float hueAngleRadians = deg2rad(color.hue);
@@ -540,110 +540,110 @@
// - A98RGB combination functions.
-A98RGB<float>::ReferenceXYZ toXYZA(const A98RGB<float>& color)
+A98RGB<float>::ReferenceXYZ ColorConversion<A98RGB<float>::ReferenceXYZ, A98RGB<float>>::convert(const A98RGB<float>& color)
{
- return toXYZA(toLinearA98RGB(color));
+ return convertColor<A98RGB<float>::ReferenceXYZ>(convertColor<LinearA98RGB<float>>(color));
}
-A98RGB<float> toA98RGB(const A98RGB<float>::ReferenceXYZ& color)
+A98RGB<float> ColorConversion<A98RGB<float>, A98RGB<float>::ReferenceXYZ>::convert(const A98RGB<float>::ReferenceXYZ& color)
{
- return toA98RGB(toLinearA98RGB(color));
+ return convertColor<A98RGB<float>>(convertColor<LinearA98RGB<float>>(color));
}
// - DisplayP3 combination functions.
-DisplayP3<float>::ReferenceXYZ toXYZA(const DisplayP3<float>& color)
+DisplayP3<float>::ReferenceXYZ ColorConversion<DisplayP3<float>::ReferenceXYZ, DisplayP3<float>>::convert(const DisplayP3<float>& color)
{
- return toXYZA(toLinearDisplayP3(color));
+ return convertColor<DisplayP3<float>::ReferenceXYZ>(convertColor<LinearDisplayP3<float>>(color));
}
-DisplayP3<float> toDisplayP3(const DisplayP3<float>::ReferenceXYZ& color)
+DisplayP3<float> ColorConversion<DisplayP3<float>, DisplayP3<float>::ReferenceXYZ>::convert(const DisplayP3<float>::ReferenceXYZ& color)
{
- return toDisplayP3(toLinearDisplayP3(color));
+ return convertColor<DisplayP3<float>>(convertColor<LinearDisplayP3<float>>(color));
}
// - ExtendedSRGB combination functions.
-ExtendedSRGBA<float>::ReferenceXYZ toXYZA(const ExtendedSRGBA<float>& color)
+ExtendedSRGBA<float>::ReferenceXYZ ColorConversion<ExtendedSRGBA<float>::ReferenceXYZ, ExtendedSRGBA<float>>::convert(const ExtendedSRGBA<float>& color)
{
- return toXYZA(toLinearExtendedSRGBA(color));
+ return convertColor<ExtendedSRGBA<float>::ReferenceXYZ>(convertColor<LinearExtendedSRGBA<float>>(color));
}
-ExtendedSRGBA<float> toExtendedSRGBA(const ExtendedSRGBA<float>::ReferenceXYZ& color)
+ExtendedSRGBA<float> ColorConversion<ExtendedSRGBA<float>, ExtendedSRGBA<float>::ReferenceXYZ>::convert(const ExtendedSRGBA<float>::ReferenceXYZ& color)
{
- return toExtendedSRGBA(toLinearExtendedSRGBA(color));
+ return convertColor<ExtendedSRGBA<float>>(convertColor<LinearExtendedSRGBA<float>>(color));
}
// - HSLA combination functions.
-HSLA<float>::ReferenceXYZ toXYZA(const HSLA<float>& color)
+HSLA<float>::ReferenceXYZ ColorConversion<HSLA<float>::ReferenceXYZ, HSLA<float>>::convert(const HSLA<float>& color)
{
- return toXYZA(toSRGBA(color));
+ return convertColor<HSLA<float>::ReferenceXYZ>(convertColor<SRGBA<float>>(color));
}
-HSLA<float> toHSLA(const HSLA<float>::ReferenceXYZ& color)
+HSLA<float> ColorConversion<HSLA<float>, HSLA<float>::ReferenceXYZ>::convert(const HSLA<float>::ReferenceXYZ& color)
{
- return toHSLA(toSRGBA(color));
+ return convertColor<HSLA<float>>(convertColor<SRGBA<float>>(color));
}
// - HWBA combination functions.
-HWBA<float>::ReferenceXYZ toXYZA(const HWBA<float>& color)
+HWBA<float>::ReferenceXYZ ColorConversion<HWBA<float>::ReferenceXYZ, HWBA<float>>::convert(const HWBA<float>& color)
{
- return toXYZA(toSRGBA(color));
+ return convertColor<HWBA<float>::ReferenceXYZ>(convertColor<SRGBA<float>>(color));
}
-HWBA<float> toHWBA(const HWBA<float>::ReferenceXYZ& color)
+HWBA<float> ColorConversion<HWBA<float>, HWBA<float>::ReferenceXYZ>::convert(const HWBA<float>::ReferenceXYZ& color)
{
- return toHWBA(toSRGBA(color));
+ return convertColor<HWBA<float>>(convertColor<SRGBA<float>>(color));
}
// - LCHA combination functions.
-LCHA<float>::ReferenceXYZ toXYZA(const LCHA<float>& color)
+LCHA<float>::ReferenceXYZ ColorConversion<LCHA<float>::ReferenceXYZ, LCHA<float>>::convert(const LCHA<float>& color)
{
- return toXYZA(toLab(color));
+ return convertColor<LCHA<float>::ReferenceXYZ>(convertColor<Lab<float>>(color));
}
-LCHA<float> toLCHA(const LCHA<float>::ReferenceXYZ& color)
+LCHA<float> ColorConversion<LCHA<float>, LCHA<float>::ReferenceXYZ>::convert(const LCHA<float>::ReferenceXYZ& color)
{
- return toLCHA(toLab(color));
+ return convertColor<LCHA<float>>(convertColor<Lab<float>>(color));
}
// - ProPhotoRGB combination functions.
-ProPhotoRGB<float>::ReferenceXYZ toXYZA(const ProPhotoRGB<float>& color)
+ProPhotoRGB<float>::ReferenceXYZ ColorConversion<ProPhotoRGB<float>::ReferenceXYZ, ProPhotoRGB<float>>::convert(const ProPhotoRGB<float>& color)
{
- return toXYZA(toLinearProPhotoRGB(color));
+ return convertColor<ProPhotoRGB<float>::ReferenceXYZ>(convertColor<LinearProPhotoRGB<float>>(color));
}
-ProPhotoRGB<float> toProPhotoRGB(const ProPhotoRGB<float>::ReferenceXYZ& color)
+ProPhotoRGB<float> ColorConversion<ProPhotoRGB<float>, ProPhotoRGB<float>::ReferenceXYZ>::convert(const ProPhotoRGB<float>::ReferenceXYZ& color)
{
- return toProPhotoRGB(toLinearProPhotoRGB(color));
+ return convertColor<ProPhotoRGB<float>>(convertColor<LinearProPhotoRGB<float>>(color));
}
// - Rec2020 combination functions.
-Rec2020<float>::ReferenceXYZ toXYZA(const Rec2020<float>& color)
+Rec2020<float>::ReferenceXYZ ColorConversion<Rec2020<float>::ReferenceXYZ, Rec2020<float>>::convert(const Rec2020<float>& color)
{
- return toXYZA(toLinearRec2020(color));
+ return convertColor<Rec2020<float>::ReferenceXYZ>(convertColor<LinearRec2020<float>>(color));
}
-Rec2020<float> toRec2020(const Rec2020<float>::ReferenceXYZ& color)
+Rec2020<float> ColorConversion<Rec2020<float>, Rec2020<float>::ReferenceXYZ>::convert(const Rec2020<float>::ReferenceXYZ& color)
{
- return toRec2020(toLinearRec2020(color));
+ return convertColor<Rec2020<float>>(convertColor<LinearRec2020<float>>(color));
}
// - SRGB combination functions.
-SRGBA<float>::ReferenceXYZ toXYZA(const SRGBA<float>& color)
+SRGBA<float>::ReferenceXYZ ColorConversion<SRGBA<float>::ReferenceXYZ, SRGBA<float>>::convert(const SRGBA<float>& color)
{
- return toXYZA(toLinearSRGBA(color));
+ return convertColor<SRGBA<float>::ReferenceXYZ>(convertColor<LinearSRGBA<float>>(color));
}
-SRGBA<float> toSRGBA(const SRGBA<float>::ReferenceXYZ& color)
+SRGBA<float> ColorConversion<SRGBA<float>, SRGBA<float>::ReferenceXYZ>::convert(const SRGBA<float>::ReferenceXYZ& color)
{
- return toSRGBA(toLinearSRGBA(color));
+ return convertColor<SRGBA<float>>(convertColor<LinearSRGBA<float>>(color));
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/ColorConversion.h (272435 => 272436)
--- trunk/Source/WebCore/platform/graphics/ColorConversion.h 2021-02-05 20:48:22 UTC (rev 272435)
+++ trunk/Source/WebCore/platform/graphics/ColorConversion.h 2021-02-05 21:08:34 UTC (rev 272436)
@@ -26,126 +26,281 @@
#pragma once
#include "ColorTypes.h"
+#include "ColorUtilities.h"
namespace WebCore {
// All color types must at least implement the following conversions to and from their reference XYZ color space
//
-// `ColorType`<float>::ReferenceXYZ toXYZA(const `ColorType`<float>&);
-// `ColorType`<float> to`ColorType`(const `ColorType`<float>::ReferenceXYZ&);
+// template<> struct ColorConversion<`ColorType`<float>::ReferenceXYZ, `ColorType`<float>> {
+// WEBCORE_EXPORT static `ColorType`<float>::ReferenceXYZ convert(const `ColorType`<float>&);
+// };
+//
+// template<> struct ColorConversion<`ColorType`<float>, `ColorType`<float>::ReferenceXYZ> {
+// WEBCORE_EXPORT static `ColorType`<float> convert(const `ColorType`<float>::ReferenceXYZ&);
+// };
//
-// as well as an identity conversion
-//
-// constexpr `ColorType`<float> to`ColorType`(const `ColorType`<float>& color) { return color; }
-//
-// and a generic conversion utilizing a conversion to the reference XYZ color space and a chromatic
-// adapatation if the white points differ
-//
-// template<typename T> `ColorType`<float> to`ColorType`(const T& color)
-//
// Any additional conversions can be thought of as optimizations, shortcutting unnecessary steps, though
// some may be integral to the base conversion.
+template<typename Output, typename Input> struct ColorConversion;
+
+template<typename Output, typename Input> inline Output convertColor(const Input& color)
+{
+ return ColorConversion<Output, Input>::convert(color);
+}
+
+
// A98RGB
-WEBCORE_EXPORT A98RGB<float>::ReferenceXYZ toXYZA(const A98RGB<float>&);
-WEBCORE_EXPORT A98RGB<float> toA98RGB(const A98RGB<float>::ReferenceXYZ&);
+template<> struct ColorConversion<A98RGB<float>::ReferenceXYZ, A98RGB<float>> {
+ WEBCORE_EXPORT static A98RGB<float>::ReferenceXYZ convert(const A98RGB<float>&);
+};
+
+template<> struct ColorConversion<A98RGB<float>, A98RGB<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static A98RGB<float> convert(const A98RGB<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT LinearA98RGB<float> toLinearA98RGB(const A98RGB<float>&);
+template<> struct ColorConversion<LinearA98RGB<float>, A98RGB<float>> {
+ WEBCORE_EXPORT static LinearA98RGB<float> convert(const A98RGB<float>&);
+};
+
// DisplayP3
-WEBCORE_EXPORT DisplayP3<float>::ReferenceXYZ toXYZA(const DisplayP3<float>&);
-WEBCORE_EXPORT DisplayP3<float> toDisplayP3(const DisplayP3<float>::ReferenceXYZ&);
+template<> struct ColorConversion<DisplayP3<float>::ReferenceXYZ, DisplayP3<float>> {
+ WEBCORE_EXPORT static DisplayP3<float>::ReferenceXYZ convert(const DisplayP3<float>&);
+};
+
+template<> struct ColorConversion<DisplayP3<float>, DisplayP3<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static DisplayP3<float> convert(const DisplayP3<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT LinearDisplayP3<float> toLinearDisplayP3(const DisplayP3<float>&);
+template<> struct ColorConversion<LinearDisplayP3<float>, DisplayP3<float>> {
+ WEBCORE_EXPORT static LinearDisplayP3<float> convert(const DisplayP3<float>&);
+};
+
// ExtendedSRGBA
-WEBCORE_EXPORT ExtendedSRGBA<float>::ReferenceXYZ toXYZA(const ExtendedSRGBA<float>&);
-WEBCORE_EXPORT ExtendedSRGBA<float> toExtendedSRGBA(const ExtendedSRGBA<float>::ReferenceXYZ&);
+template<> struct ColorConversion<ExtendedSRGBA<float>::ReferenceXYZ, ExtendedSRGBA<float>> {
+ WEBCORE_EXPORT static ExtendedSRGBA<float>::ReferenceXYZ convert(const ExtendedSRGBA<float>&);
+};
+
+template<> struct ColorConversion<ExtendedSRGBA<float>, ExtendedSRGBA<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static ExtendedSRGBA<float> convert(const ExtendedSRGBA<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT LinearExtendedSRGBA<float> toLinearExtendedSRGBA(const ExtendedSRGBA<float>&);
+template<> struct ColorConversion<LinearExtendedSRGBA<float>, ExtendedSRGBA<float>> {
+ WEBCORE_EXPORT static LinearExtendedSRGBA<float> convert(const ExtendedSRGBA<float>&);
+};
+
// HSLA
-WEBCORE_EXPORT HSLA<float>::ReferenceXYZ toXYZA(const HSLA<float>&);
-WEBCORE_EXPORT HSLA<float> toHSLA(const HSLA<float>::ReferenceXYZ&);
+template<> struct ColorConversion<HSLA<float>::ReferenceXYZ, HSLA<float>> {
+ WEBCORE_EXPORT static HSLA<float>::ReferenceXYZ convert(const HSLA<float>&);
+};
+
+template<> struct ColorConversion<HSLA<float>, HSLA<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static HSLA<float> convert(const HSLA<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT SRGBA<float> toSRGBA(const HSLA<float>&);
+template<> struct ColorConversion<SRGBA<float>, HSLA<float>> {
+ WEBCORE_EXPORT static SRGBA<float> convert(const HSLA<float>&);
+};
+
// HWBA
-WEBCORE_EXPORT HWBA<float>::ReferenceXYZ toXYZA(const HWBA<float>&);
-WEBCORE_EXPORT HWBA<float> toHWBA(const HWBA<float>::ReferenceXYZ&);
+template<> struct ColorConversion<HWBA<float>::ReferenceXYZ, HWBA<float>> {
+ WEBCORE_EXPORT static HWBA<float>::ReferenceXYZ convert(const HWBA<float>&);
+};
+
+template<> struct ColorConversion<HWBA<float>, HWBA<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static HWBA<float> convert(const HWBA<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT SRGBA<float> toSRGBA(const HWBA<float>&);
+template<> struct ColorConversion<SRGBA<float>, HWBA<float>> {
+ WEBCORE_EXPORT static SRGBA<float> convert(const HWBA<float>&);
+};
+
// LCHA
-WEBCORE_EXPORT LCHA<float>::ReferenceXYZ toXYZA(const LCHA<float>&);
-WEBCORE_EXPORT LCHA<float> toLCHA(const LCHA<float>::ReferenceXYZ&);
+template<> struct ColorConversion<LCHA<float>::ReferenceXYZ, LCHA<float>> {
+ WEBCORE_EXPORT static LCHA<float>::ReferenceXYZ convert(const LCHA<float>&);
+};
+
+template<> struct ColorConversion<LCHA<float>, LCHA<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static LCHA<float> convert(const LCHA<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT Lab<float> toLab(const LCHA<float>&);
+template<> struct ColorConversion<Lab<float>, LCHA<float>> {
+ WEBCORE_EXPORT static Lab<float> convert(const LCHA<float>&);
+};
+
// Lab
-WEBCORE_EXPORT Lab<float>::ReferenceXYZ toXYZA(const Lab<float>&);
-WEBCORE_EXPORT Lab<float> toLab(const Lab<float>::ReferenceXYZ&);
+template<> struct ColorConversion<Lab<float>::ReferenceXYZ, Lab<float>> {
+ WEBCORE_EXPORT static Lab<float>::ReferenceXYZ convert(const Lab<float>&);
+};
+
+template<> struct ColorConversion<Lab<float>, Lab<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static Lab<float> convert(const Lab<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT LCHA<float> toLCHA(const Lab<float>&);
+template<> struct ColorConversion<LCHA<float>, Lab<float>> {
+ WEBCORE_EXPORT static LCHA<float> convert(const Lab<float>&);
+};
+
// LinearA98RGB
-WEBCORE_EXPORT LinearA98RGB<float>::ReferenceXYZ toXYZA(const LinearA98RGB<float>&);
-WEBCORE_EXPORT LinearA98RGB<float> toLinearA98RGB(const LinearA98RGB<float>::ReferenceXYZ&);
+template<> struct ColorConversion<LinearA98RGB<float>::ReferenceXYZ, LinearA98RGB<float>> {
+ WEBCORE_EXPORT static LinearA98RGB<float>::ReferenceXYZ convert(const LinearA98RGB<float>&);
+};
+
+template<> struct ColorConversion<LinearA98RGB<float>, LinearA98RGB<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static LinearA98RGB<float> convert(const LinearA98RGB<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT A98RGB<float> toA98RGB(const LinearA98RGB<float>& color);
+template<> struct ColorConversion<A98RGB<float>, LinearA98RGB<float>> {
+ WEBCORE_EXPORT static A98RGB<float> convert(const LinearA98RGB<float>&);
+};
+
// LinearDisplayP3
-WEBCORE_EXPORT LinearDisplayP3<float>::ReferenceXYZ toXYZA(const LinearDisplayP3<float>&);
-WEBCORE_EXPORT LinearDisplayP3<float> toLinearDisplayP3(const LinearDisplayP3<float>::ReferenceXYZ&);
+template<> struct ColorConversion<LinearDisplayP3<float>::ReferenceXYZ, LinearDisplayP3<float>> {
+ WEBCORE_EXPORT static LinearDisplayP3<float>::ReferenceXYZ convert(const LinearDisplayP3<float>&);
+};
+
+template<> struct ColorConversion<LinearDisplayP3<float>, LinearDisplayP3<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static LinearDisplayP3<float> convert(const LinearDisplayP3<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT DisplayP3<float> toDisplayP3(const LinearDisplayP3<float>&);
+template<> struct ColorConversion<DisplayP3<float>, LinearDisplayP3<float>> {
+ WEBCORE_EXPORT static DisplayP3<float> convert(const LinearDisplayP3<float>&);
+};
+
// LinearExtendedSRGBA
-WEBCORE_EXPORT LinearExtendedSRGBA<float>::ReferenceXYZ toXYZA(const LinearExtendedSRGBA<float>&);
-WEBCORE_EXPORT LinearExtendedSRGBA<float> toLinearExtendedSRGBA(const LinearExtendedSRGBA<float>::ReferenceXYZ&);
+template<> struct ColorConversion<LinearExtendedSRGBA<float>::ReferenceXYZ, LinearExtendedSRGBA<float>> {
+ WEBCORE_EXPORT static LinearExtendedSRGBA<float>::ReferenceXYZ convert(const LinearExtendedSRGBA<float>&);
+};
+
+template<> struct ColorConversion<LinearExtendedSRGBA<float>, LinearExtendedSRGBA<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static LinearExtendedSRGBA<float> convert(const LinearExtendedSRGBA<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT ExtendedSRGBA<float> toExtendedSRGBA(const LinearExtendedSRGBA<float>&);
+template<> struct ColorConversion<ExtendedSRGBA<float>, LinearExtendedSRGBA<float>> {
+ WEBCORE_EXPORT static ExtendedSRGBA<float> convert(const LinearExtendedSRGBA<float>&);
+};
+
// LinearProPhotoRGB
-WEBCORE_EXPORT LinearProPhotoRGB<float>::ReferenceXYZ toXYZA(const LinearProPhotoRGB<float>&);
-WEBCORE_EXPORT LinearProPhotoRGB<float> toLinearProPhotoRGB(const LinearProPhotoRGB<float>::ReferenceXYZ&);
+template<> struct ColorConversion<LinearProPhotoRGB<float>::ReferenceXYZ, LinearProPhotoRGB<float>> {
+ WEBCORE_EXPORT static LinearProPhotoRGB<float>::ReferenceXYZ convert(const LinearProPhotoRGB<float>&);
+};
+
+template<> struct ColorConversion<LinearProPhotoRGB<float>, LinearProPhotoRGB<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static LinearProPhotoRGB<float> convert(const LinearProPhotoRGB<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT ProPhotoRGB<float> toProPhotoRGB(const LinearProPhotoRGB<float>&);
+template<> struct ColorConversion<ProPhotoRGB<float>, LinearProPhotoRGB<float>> {
+ WEBCORE_EXPORT static ProPhotoRGB<float> convert(const LinearProPhotoRGB<float>&);
+};
+
// LinearRec2020
-WEBCORE_EXPORT LinearRec2020<float>::ReferenceXYZ toXYZA(const LinearRec2020<float>&);
-WEBCORE_EXPORT LinearRec2020<float> toLinearRec2020(const LinearRec2020<float>::ReferenceXYZ&);
+template<> struct ColorConversion<LinearRec2020<float>::ReferenceXYZ, LinearRec2020<float>> {
+ WEBCORE_EXPORT static LinearRec2020<float>::ReferenceXYZ convert(const LinearRec2020<float>&);
+};
+
+template<> struct ColorConversion<LinearRec2020<float>, LinearRec2020<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static LinearRec2020<float> convert(const LinearRec2020<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT Rec2020<float> toRec2020(const LinearRec2020<float>&);
+template<> struct ColorConversion<Rec2020<float>, LinearRec2020<float>> {
+ WEBCORE_EXPORT static Rec2020<float> convert(const LinearRec2020<float>&);
+};
+
// LinearSRGBA
-WEBCORE_EXPORT LinearSRGBA<float>::ReferenceXYZ toXYZA(const LinearSRGBA<float>&);
-WEBCORE_EXPORT LinearSRGBA<float> toLinearSRGBA(const LinearSRGBA<float>::ReferenceXYZ&);
+template<> struct ColorConversion<LinearSRGBA<float>::ReferenceXYZ, LinearSRGBA<float>> {
+ WEBCORE_EXPORT static LinearSRGBA<float>::ReferenceXYZ convert(const LinearSRGBA<float>&);
+};
+
+template<> struct ColorConversion<LinearSRGBA<float>, LinearSRGBA<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static LinearSRGBA<float> convert(const LinearSRGBA<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT SRGBA<float> toSRGBA(const LinearSRGBA<float>&);
+template<> struct ColorConversion<SRGBA<float>, LinearSRGBA<float>> {
+ WEBCORE_EXPORT static SRGBA<float> convert(const LinearSRGBA<float>&);
+};
+
// ProPhotoRGB
-WEBCORE_EXPORT ProPhotoRGB<float>::ReferenceXYZ toXYZA(const ProPhotoRGB<float>&);
-WEBCORE_EXPORT ProPhotoRGB<float> toProPhotoRGB(const ProPhotoRGB<float>::ReferenceXYZ&);
+template<> struct ColorConversion<ProPhotoRGB<float>::ReferenceXYZ, ProPhotoRGB<float>> {
+ WEBCORE_EXPORT static ProPhotoRGB<float>::ReferenceXYZ convert(const ProPhotoRGB<float>&);
+};
+
+template<> struct ColorConversion<ProPhotoRGB<float>, ProPhotoRGB<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static ProPhotoRGB<float> convert(const ProPhotoRGB<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT LinearProPhotoRGB<float> toLinearProPhotoRGB(const ProPhotoRGB<float>&);
+template<> struct ColorConversion<LinearProPhotoRGB<float>, ProPhotoRGB<float>> {
+ WEBCORE_EXPORT static LinearProPhotoRGB<float> convert(const ProPhotoRGB<float>&);
+};
+
// Rec2020
-WEBCORE_EXPORT Rec2020<float>::ReferenceXYZ toXYZA(const Rec2020<float>&);
-WEBCORE_EXPORT Rec2020<float> toRec2020(const Rec2020<float>::ReferenceXYZ&);
+template<> struct ColorConversion<Rec2020<float>::ReferenceXYZ, Rec2020<float>> {
+ WEBCORE_EXPORT static Rec2020<float>::ReferenceXYZ convert(const Rec2020<float>&);
+};
+
+template<> struct ColorConversion<Rec2020<float>, Rec2020<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static Rec2020<float> convert(const Rec2020<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT LinearRec2020<float> toLinearRec2020(const Rec2020<float>&);
+template<> struct ColorConversion<LinearRec2020<float>, Rec2020<float>> {
+ WEBCORE_EXPORT static LinearRec2020<float> convert(const Rec2020<float>&);
+};
+
// SRGBA
-WEBCORE_EXPORT SRGBA<float>::ReferenceXYZ toXYZA(const SRGBA<float>&);
-WEBCORE_EXPORT SRGBA<float> toSRGBA(const SRGBA<float>::ReferenceXYZ&);
+template<> struct ColorConversion<SRGBA<float>::ReferenceXYZ, SRGBA<float>> {
+ WEBCORE_EXPORT static SRGBA<float>::ReferenceXYZ convert(const SRGBA<float>&);
+};
+
+template<> struct ColorConversion<SRGBA<float>, SRGBA<float>::ReferenceXYZ> {
+ WEBCORE_EXPORT static SRGBA<float> convert(const SRGBA<float>::ReferenceXYZ&);
+};
+
// Additions
-WEBCORE_EXPORT LinearSRGBA<float> toLinearSRGBA(const SRGBA<float>&);
-WEBCORE_EXPORT HSLA<float> toHSLA(const SRGBA<float>&);
-WEBCORE_EXPORT HWBA<float> toHWBA(const SRGBA<float>&);
+template<> struct ColorConversion<LinearSRGBA<float>, SRGBA<float>> {
+ WEBCORE_EXPORT static LinearSRGBA<float> convert(const SRGBA<float>&);
+};
+template<> struct ColorConversion<HSLA<float>, SRGBA<float>> {
+ WEBCORE_EXPORT static HSLA<float> convert(const SRGBA<float>&);
+};
+template<> struct ColorConversion<HWBA<float>, SRGBA<float>> {
+ WEBCORE_EXPORT static HWBA<float> convert(const SRGBA<float>&);
+};
+
+
+
// Chromatic Adaptation conversions.
WEBCORE_EXPORT XYZA<float, WhitePoint::D65> convertFromD50WhitePointToD65WhitePoint(const XYZA<float, WhitePoint::D50>&);
WEBCORE_EXPORT XYZA<float, WhitePoint::D50> convertFromD65WhitePointToD50WhitePoint(const XYZA<float, WhitePoint::D65>&);
@@ -162,111 +317,58 @@
return convertFromD50WhitePointToD65WhitePoint(color);
}
-
-// Identity conversions (useful for generic contexts).
-
-constexpr A98RGB<float> toA98RGB(const A98RGB<float>& color) { return color; }
-constexpr DisplayP3<float> toDisplayP3(const DisplayP3<float>& color) { return color; }
-constexpr ExtendedSRGBA<float> toExtendedSRGBA(const ExtendedSRGBA<float>& color) { return color; }
-constexpr HSLA<float> toHSLA(const HSLA<float>& color) { return color; }
-constexpr HWBA<float> toHWBA(const HWBA<float>& color) { return color; }
-constexpr LCHA<float> toLCHA(const LCHA<float>& color) { return color; }
-constexpr Lab<float> toLab(const Lab<float>& color) { return color; }
-constexpr LinearA98RGB<float> toLinearA98RGB(const LinearA98RGB<float>& color) { return color; }
-constexpr LinearDisplayP3<float> toLinearDisplayP3(const LinearDisplayP3<float>& color) { return color; }
-constexpr LinearExtendedSRGBA<float> toLinearExtendedSRGBA(const LinearExtendedSRGBA<float>& color) { return color; }
-constexpr LinearProPhotoRGB<float> toLinearRec2020(const LinearProPhotoRGB<float>& color) { return color; }
-constexpr LinearRec2020<float> toLinearRec2020(const LinearRec2020<float>& color) { return color; }
-constexpr LinearSRGBA<float> toLinearSRGBA(const LinearSRGBA<float>& color) { return color; }
-constexpr ProPhotoRGB<float> toProPhotoRGB(const ProPhotoRGB<float>& color) { return color; }
-constexpr Rec2020<float> toRec2020(const Rec2020<float>& color) { return color; }
-constexpr SRGBA<float> toSRGBA(const SRGBA<float>& color) { return color; }
-template<WhitePoint W> constexpr XYZA<float, W> toXYZA(const XYZA<float, W>& color) { return color; }
-
-
// Fallback conversions.
-// All types are required to have a conversion to their reference XYZ space, so these are guaranteed
-// to work if another overload is not already provided.
+// All types are required to have a conversion to their reference XYZ space, so this is guaranteed
+// to work if another specialization is not already provided.
-template<typename T> A98RGB<float> toA98RGB(const T& color)
-{
- return toA98RGB(performChomaticAdapatation<A98RGB<float>>(toXYZA(color)));
-}
+// FIXME: Rather than always converting through reference XYZ color space
+// we should instead switch to computing the least common reference ancestor
+// type where each color type defines its reference type as the color it needs
+// to get one step closer to the reference XYZ color space. For instance,
+// the reference type of SRGBA is LinearSRGBA, and the reference type of LCHA
+// is Lab. Together, the color types make a tree with XYZ at the root. The
+// conversion should end up looking something like:
+//
+// using LCA = LeastCommonAncestor<Output, Input>::Type;
+// return convertColor<Output>(convertColor<LCA>(color));
+//
+// An example of where this would be more efficient is when converting from
+// HSLA<float> to HWBA<float>. LCA for this pair is SRGBA<float> so conversion
+// through XYZ is wasteful. This model would also allow us to remove the
+// combination conversions, reducing the number of things each new color type
+// requires.
+//
+// FIXME: Reduce total number of matrix tranforms by concatenating the matrices
+// of sequential matrix transforms at compile time. Take the conversion from
+// ProPhotoRGB<float> to SRGBA<float> as an example:
+//
+// 1. ProPhotoRGB<float> -> LinearProPhotoRGB<float> (transfer function transform, not matrix)
+// 2. LinearProPhotoRGB<float> -> XYZA<float, WhitePoint::D50> MATRIX TRANSFORM
+// 3. XYZA<float, WhitePoint::D50> -> XYZA<float, WhitePoint::D65> MATRIX TRANSFORM
+// 4. XYZA<float, WhitePoint::D65> -> LinearSRGBA<float> MATRIX TRANSFORM
+// 5. LinearSRGBA<float> -> SRGBA<float> (transfer function transform, not matrix)
+//
+// Steps 2, 3, and 4 can be combined into one single matrix if we linearly
+// concatented the three matrices. To do this, we will have to tag which conversions
+// are matrix based, expose the matrices, add support for constexpr concatenting
+// of ColorMatrix and find a way to merge the conversions.
-template<typename T> DisplayP3<float> toDisplayP3(const T& color)
-{
- return toDisplayP3(performChomaticAdapatation<DisplayP3<float>>(toXYZA(color)));
-}
+template<typename Output, typename Input> struct ColorConversion {
+ static Output convert(const Input& color)
+ {
+ if constexpr(std::is_same_v<Output, Input>)
+ return color;
+ else if constexpr (std::is_same_v<typename Input::ComponentType, uint8_t>)
+ return convertColor<Output>(convertTo<SRGBA<float>>(color));
+ else if constexpr (std::is_same_v<typename Output::ComponentType, uint8_t>)
+ return convertTo<SRGBA<uint8_t>>(convertColor<SRGBA<float>>(color));
+ else {
+ auto xyz1 = convertColor<typename Input::ReferenceXYZ>(color);
+ auto xyz2 = performChomaticAdapatation<Output>(xyz1);
+ return convertColor<Output>(xyz2);
+ }
+ }
+};
-template<typename T> ExtendedSRGBA<float> toExtendedSRGBA(const T& color)
-{
- return toExtendedSRGBA(performChomaticAdapatation<ExtendedSRGBA<float>>(toXYZA(color)));
-}
-
-template<typename T> HSLA<float> toHSLA(const T& color)
-{
- return toHSLA(performChomaticAdapatation<HSLA<float>>(toXYZA(color)));
-}
-
-template<typename T> HWBA<float> toHWBA(const T& color)
-{
- return toHWBA(performChomaticAdapatation<HWBA<float>>(toXYZA(color)));
-}
-
-template<typename T> LCHA<float> toLCHA(const T& color)
-{
- return toLCHA(performChomaticAdapatation<LCHA<float>>(toXYZA(color)));
-}
-
-template<typename T> Lab<float> toLab(const T& color)
-{
- return toLab(performChomaticAdapatation<Lab<float>>(toXYZA(color)));
-}
-
-template<typename T> LinearA98RGB<float> toLinearA98RGB(const T& color)
-{
- return toLinearA98RGB(performChomaticAdapatation<LinearA98RGB<float>>(toXYZA(color)));
-}
-
-template<typename T> LinearDisplayP3<float> toLinearDisplayP3(const T& color)
-{
- return toLinearDisplayP3(performChomaticAdapatation<LinearDisplayP3<float>>(toXYZA(color)));
-}
-
-template<typename T> LinearExtendedSRGBA<float> toLinearExtendedSRGBA(const T& color)
-{
- return toLinearExtendedSRGBA(performChomaticAdapatation<LinearExtendedSRGBA<float>>(toXYZA(color)));
-}
-
-template<typename T> LinearProPhotoRGB<float> toLinearProPhotoRGB(const T& color)
-{
- return toLinearProPhotoRGB(performChomaticAdapatation<LinearProPhotoRGB<float>>(toXYZA(color)));
-}
-
-template<typename T> LinearRec2020<float> toLinearRec2020(const T& color)
-{
- return toLinearRec2020(performChomaticAdapatation<LinearRec2020<float>>(toXYZA(color)));
-}
-
-template<typename T> LinearSRGBA<float> toLinearSRGBA(const T& color)
-{
- return toLinearSRGBA(performChomaticAdapatation<LinearSRGBA<float>>(toXYZA(color)));
-}
-
-template<typename T> ProPhotoRGB<float> toProPhotoRGB(const T& color)
-{
- return toProPhotoRGB(performChomaticAdapatation<ProPhotoRGB<float>>(toXYZA(color)));
-}
-
-template<typename T> Rec2020<float> toRec2020(const T& color)
-{
- return toRec2020(performChomaticAdapatation<Rec2020<float>>(toXYZA(color)));
-}
-
-template<typename T> SRGBA<float> toSRGBA(const T& color)
-{
- return toSRGBA(performChomaticAdapatation<SRGBA<float>>(toXYZA(color)));
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/ColorUtilities.cpp (272435 => 272436)
--- trunk/Source/WebCore/platform/graphics/ColorUtilities.cpp 2021-02-05 20:48:22 UTC (rev 272435)
+++ trunk/Source/WebCore/platform/graphics/ColorUtilities.cpp 2021-02-05 21:08:34 UTC (rev 272436)
@@ -39,10 +39,10 @@
float luminance(const SRGBA<float>& color)
{
- // NOTE: This is the equivalent of toXYZA(toLinearSRGBA(color)).y
+ // NOTE: This is the equivalent of convertColor<XYZA<float, WhitePoint::D65>>(color).y
// FIMXE: If we can generalize ColorMatrix a bit more, it might be nice to write this as:
- // return toLinearSRGBA(color) * linearSRGBToXYZMatrix.row(1);
- auto [r, g, b, a] = toLinearSRGBA(color);
+ // return convertColor<LinearSRGBA<float>>(color) * linearSRGBToXYZMatrix.row(1);
+ auto [r, g, b, a] = convertColor<LinearSRGBA<float>>(color);
return 0.2126f * r + 0.7152f * g + 0.0722f * b;
}
Modified: trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp (272435 => 272436)
--- trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp 2021-02-05 20:48:22 UTC (rev 272435)
+++ trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp 2021-02-05 21:08:34 UTC (rev 272436)
@@ -81,7 +81,7 @@
ASSERT_NOT_REACHED();
}
- return convertTo<SRGBA<uint8_t>>(SRGBA { r, g, b, a });
+ return convertColor<SRGBA<uint8_t>>(SRGBA { r, g, b, a });
}
Color::Color(CGColorRef color)
@@ -108,7 +108,7 @@
// more explicit.
if (colorSpace != ColorSpace::SRGB && cgColorSpace == sRGBColorSpaceRef()) {
auto colorConvertedToExtendedSRGBA = callWithColorType(components, colorSpace, [] (const auto& color) {
- return toExtendedSRGBA(color);
+ return convertColor<ExtendedSRGBA<float>>(color);
});
components = asColorComponents(colorConvertedToExtendedSRGBA);
cgColorSpace = extendedSRGBColorSpaceRef();
Modified: trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp (272435 => 272436)
--- trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp 2021-02-05 20:48:22 UTC (rev 272435)
+++ trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp 2021-02-05 21:08:34 UTC (rev 272436)
@@ -405,7 +405,7 @@
data.heightDecreasedByOne = height - 1;
if (operatingColorSpace() == ColorSpace::LinearRGB) {
- auto [r, g, b, a] = toLinearSRGBA(m_lightingColor.toSRGBALossy<float>());
+ auto [r, g, b, a] = m_lightingColor.toColorTypeLossy<LinearSRGBA<float>>();
paintingData.initialLightingData.colorVector = FloatPoint3D(r, g, b);
} else {
auto [r, g, b, a] = m_lightingColor.toSRGBALossy<float>();
Modified: trunk/Source/WebCore/rendering/RenderTheme.cpp (272435 => 272436)
--- trunk/Source/WebCore/rendering/RenderTheme.cpp 2021-02-05 20:48:22 UTC (rev 272435)
+++ trunk/Source/WebCore/rendering/RenderTheme.cpp 2021-02-05 21:08:34 UTC (rev 272436)
@@ -1419,13 +1419,15 @@
Color RenderTheme::datePlaceholderTextColor(const Color& textColor, const Color& backgroundColor) const
{
- auto hsla = toHSLA(textColor.toSRGBALossy<float>());
+ // FIXME: Consider using LCHA<float> rather than HSLA<float> for better perceptual results and to avoid clamping to sRGB gamut, which is what HSLA does.
+ auto hsla = textColor.toColorTypeLossy<HSLA<float>>();
if (textColor.luminance() < backgroundColor.luminance())
hsla.lightness += datePlaceholderColorLightnessAdjustmentFactor * (1.0f - hsla.lightness);
else
hsla.lightness *= datePlaceholderColorLightnessAdjustmentFactor;
- return toSRGBA(hsla);
+ // FIXME: Consider keeping color in LCHA (if that change is made) or converting back to the initial underlying color type to avoid unnecessarily clamping colors outside of sRGB.
+ return convertColor<SRGBA<float>>(hsla);
}
void RenderTheme::setCustomFocusRingColor(const Color& color)
Modified: trunk/Tools/ChangeLog (272435 => 272436)
--- trunk/Tools/ChangeLog 2021-02-05 20:48:22 UTC (rev 272435)
+++ trunk/Tools/ChangeLog 2021-02-05 21:08:34 UTC (rev 272436)
@@ -1,3 +1,14 @@
+2021-02-05 Sam Weinig <wei...@apple.com>
+
+ Generalize color conversion code to reduce number of overloads required
+ https://bugs.webkit.org/show_bug.cgi?id=221443
+
+ Reviewed by Darin Adler.
+
+ * TestWebKitAPI/Tests/WebCore/ColorTests.cpp:
+ (TestWebKitAPI::TEST):
+ Update tests to use convertColor<>.
+
2021-02-05 Aakash Jain <aakash_j...@apple.com>
[ews] commit-queue should use commits.webkit.org url instead of trac url
Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/ColorTests.cpp (272435 => 272436)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ColorTests.cpp 2021-02-05 20:48:22 UTC (rev 272435)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ColorTests.cpp 2021-02-05 21:08:34 UTC (rev 272436)
@@ -38,7 +38,7 @@
{
Color color = Color::white;
- auto hslaColor = toHSLA(color.toSRGBALossy<float>());
+ auto hslaColor = color.toColorTypeLossy<HSLA<float>>();
EXPECT_FLOAT_EQ(0, hslaColor.hue);
EXPECT_FLOAT_EQ(0, hslaColor.saturation);
@@ -46,7 +46,7 @@
EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
- auto roundTrippedColor = convertTo<SRGBA<uint8_t>>(toSRGBA(hslaColor));
+ auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
EXPECT_EQ(color, roundTrippedColor);
}
@@ -54,7 +54,7 @@
{
Color color = Color::black;
- auto hslaColor = toHSLA(color.toSRGBALossy<float>());
+ auto hslaColor = color.toColorTypeLossy<HSLA<float>>();
EXPECT_FLOAT_EQ(0, hslaColor.hue);
EXPECT_FLOAT_EQ(0, hslaColor.saturation);
@@ -62,7 +62,7 @@
EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
- auto roundTrippedColor = convertTo<SRGBA<uint8_t>>(toSRGBA(hslaColor));
+ auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
EXPECT_EQ(color, roundTrippedColor);
}
@@ -70,7 +70,7 @@
{
Color color = Color::red;
- auto hslaColor = toHSLA(color.toSRGBALossy<float>());
+ auto hslaColor = color.toColorTypeLossy<HSLA<float>>();
EXPECT_FLOAT_EQ(0, hslaColor.hue);
EXPECT_FLOAT_EQ(1, hslaColor.saturation);
@@ -78,7 +78,7 @@
EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
- auto roundTrippedColor = convertTo<SRGBA<uint8_t>>(toSRGBA(hslaColor));
+ auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
EXPECT_EQ(color, roundTrippedColor);
}
@@ -86,7 +86,7 @@
{
Color color = Color::green;
- auto hslaColor = toHSLA(color.toSRGBALossy<float>());
+ auto hslaColor = color.toColorTypeLossy<HSLA<float>>();
EXPECT_FLOAT_EQ(0.33333334, hslaColor.hue);
EXPECT_FLOAT_EQ(1, hslaColor.saturation);
@@ -94,7 +94,7 @@
EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
- auto roundTrippedColor = convertTo<SRGBA<uint8_t>>(toSRGBA(hslaColor));
+ auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
EXPECT_EQ(color, roundTrippedColor);
}
@@ -102,7 +102,7 @@
{
Color color = Color::blue;
- auto hslaColor = toHSLA(color.toSRGBALossy<float>());
+ auto hslaColor = color.toColorTypeLossy<HSLA<float>>();
EXPECT_FLOAT_EQ(0.66666669, hslaColor.hue);
EXPECT_FLOAT_EQ(1, hslaColor.saturation);
@@ -110,7 +110,7 @@
EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
- auto roundTrippedColor = convertTo<SRGBA<uint8_t>>(toSRGBA(hslaColor));
+ auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
EXPECT_EQ(color, roundTrippedColor);
}
@@ -118,7 +118,7 @@
{
Color color = Color::darkGray;
- auto hslaColor = toHSLA(color.toSRGBALossy<float>());
+ auto hslaColor = color.toColorTypeLossy<HSLA<float>>();
EXPECT_FLOAT_EQ(0, hslaColor.hue);
EXPECT_FLOAT_EQ(0, hslaColor.saturation);
@@ -126,7 +126,7 @@
EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
- auto roundTrippedColor = convertTo<SRGBA<uint8_t>>(toSRGBA(hslaColor));
+ auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
EXPECT_EQ(color, roundTrippedColor);
}
@@ -134,7 +134,7 @@
{
Color color = Color::gray;
- auto hslaColor = toHSLA(color.toSRGBALossy<float>());
+ auto hslaColor = color.toColorTypeLossy<HSLA<float>>();
EXPECT_FLOAT_EQ(0, hslaColor.hue);
EXPECT_FLOAT_EQ(0, hslaColor.saturation);
@@ -142,7 +142,7 @@
EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
- auto roundTrippedColor = convertTo<SRGBA<uint8_t>>(toSRGBA(hslaColor));
+ auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
EXPECT_EQ(color, roundTrippedColor);
}
@@ -150,7 +150,7 @@
{
Color color = Color::lightGray;
- auto hslaColor = toHSLA(color.toSRGBALossy<float>());
+ auto hslaColor = color.toColorTypeLossy<HSLA<float>>();
EXPECT_FLOAT_EQ(0, hslaColor.hue);
EXPECT_FLOAT_EQ(0, hslaColor.saturation);
@@ -158,7 +158,7 @@
EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
- auto roundTrippedColor = convertTo<SRGBA<uint8_t>>(toSRGBA(hslaColor));
+ auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
EXPECT_EQ(color, roundTrippedColor);
}