<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[278070] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/278070">278070</a></dd>
<dt>Author</dt> <dd>weinig@apple.com</dd>
<dt>Date</dt> <dd>2021-05-25 18:10:08 -0700 (Tue, 25 May 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>Support byte components for all bounded RGB color types, not just SRGBA
https://bugs.webkit.org/show_bug.cgi?id=226222

Reviewed by Darin Adler.

We currently arbitrarily restrict byte components (e.g. SRGBA<uint8_t>)
to just SRGBA by only supporting conversion for that one color type. Support
for any bounded (e.g. [0..1]) RGB type would have the same semantics and
be useful now that we can get pixel buffers that are not SRGBA only out
of ImageBuffer.

To do this, we replace the ColorConversion specializations for this type
of conversion, and inline it directly in the main conversion convert function,
allowing for a more complex conditional without SFINAE complexity.

To make things a bit simpler, this also simplifies the RGB color type descriptors
to no longer be templates, as the description of the types is always float
based, regardless of the component used. This allows for a simpler new helper,
SelfWithReplacementComponent, to convert to and from ColorType<float>/ColorType<uint8_t>.

* platform/graphics/ColorConversion.cpp:
(WebCore::SRGBA<uint8_t>>::convert): Deleted.
* platform/graphics/ColorConversion.h:
(WebCore::ColorConversion::convert):
(WebCore::ColorConversion::handleToFloatConversion):
(WebCore::ColorConversion::handleToByteConversion):
* platform/graphics/ColorTypes.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsColorConversioncpp">trunk/Source/WebCore/platform/graphics/ColorConversion.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsColorConversionh">trunk/Source/WebCore/platform/graphics/ColorConversion.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsColorTypesh">trunk/Source/WebCore/platform/graphics/ColorTypes.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (278069 => 278070)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-05-26 00:37:19 UTC (rev 278069)
+++ trunk/Source/WebCore/ChangeLog      2021-05-26 01:10:08 UTC (rev 278070)
</span><span class="lines">@@ -1,3 +1,33 @@
</span><ins>+2021-05-25  Sam Weinig  <weinig@apple.com>
+
+        Support byte components for all bounded RGB color types, not just SRGBA
+        https://bugs.webkit.org/show_bug.cgi?id=226222
+
+        Reviewed by Darin Adler.
+
+        We currently arbitrarily restrict byte components (e.g. SRGBA<uint8_t>)
+        to just SRGBA by only supporting conversion for that one color type. Support
+        for any bounded (e.g. [0..1]) RGB type would have the same semantics and
+        be useful now that we can get pixel buffers that are not SRGBA only out
+        of ImageBuffer.
+
+        To do this, we replace the ColorConversion specializations for this type
+        of conversion, and inline it directly in the main conversion convert function,
+        allowing for a more complex conditional without SFINAE complexity.
+
+        To make things a bit simpler, this also simplifies the RGB color type descriptors
+        to no longer be templates, as the description of the types is always float
+        based, regardless of the component used. This allows for a simpler new helper,
+        SelfWithReplacementComponent, to convert to and from ColorType<float>/ColorType<uint8_t>.
+
+        * platform/graphics/ColorConversion.cpp:
+        (WebCore::SRGBA<uint8_t>>::convert): Deleted.
+        * platform/graphics/ColorConversion.h:
+        (WebCore::ColorConversion::convert):
+        (WebCore::ColorConversion::handleToFloatConversion):
+        (WebCore::ColorConversion::handleToByteConversion):
+        * platform/graphics/ColorTypes.h:
+
</ins><span class="cx"> 2021-05-25  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><span class="cx">         CSP does not apply to AudioWorklets
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsColorConversioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ColorConversion.cpp (278069 => 278070)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ColorConversion.cpp       2021-05-26 00:37:19 UTC (rev 278069)
+++ trunk/Source/WebCore/platform/graphics/ColorConversion.cpp  2021-05-26 01:10:08 UTC (rev 278070)
</span><span class="lines">@@ -273,22 +273,6 @@
</span><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// MARK: SRGBA<uint8_t> conversions.
-
-SRGBA<float> ColorConversion<SRGBA<float>, SRGBA<uint8_t>>::convert(const SRGBA<uint8_t>& color)
-{
-    return makeFromComponents<SRGBA<float>>(asColorComponents(color).map([](uint8_t value) -> float {
-        return value / 255.0f;
-    }));
-}
-
-SRGBA<uint8_t> ColorConversion<SRGBA<uint8_t>, SRGBA<float>>::convert(const SRGBA<float>& color)
-{
-    return makeFromComponents<SRGBA<uint8_t>>(asColorComponents(color).map([](float value) -> uint8_t {
-        return std::clamp(std::lround(value * 255.0f), 0l, 255l);
-    }));
-}
-
</del><span class="cx"> // MARK: Conversion functions for raw color components with associated color spaces.
</span><span class="cx"> 
</span><span class="cx"> ColorComponents<float, 4> converColorComponents(ColorSpace inputColorSpace, ColorComponents<float, 4> inputColorComponents, ColorSpace outputColorSpace)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsColorConversionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ColorConversion.h (278069 => 278070)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ColorConversion.h 2021-05-26 00:37:19 UTC (rev 278069)
+++ trunk/Source/WebCore/platform/graphics/ColorConversion.h    2021-05-26 01:10:08 UTC (rev 278070)
</span><span class="lines">@@ -114,16 +114,6 @@
</span><span class="cx">     WEBCORE_EXPORT static Lab<float> convert(const XYZA<float, WhitePoint::D50>&);
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-// MARK: SRGBA<uint8_t>
-// Only sRGB supports non-floating point component types.
-template<> struct ColorConversion<SRGBA<float>, SRGBA<uint8_t>> {
-    WEBCORE_EXPORT static SRGBA<float> convert(const SRGBA<uint8_t>&);
-};
-template<> struct ColorConversion<SRGBA<uint8_t>, SRGBA<float>> {
-    WEBCORE_EXPORT static SRGBA<uint8_t> convert(const SRGBA<float>&);
-};
-
-
</del><span class="cx"> // Identity conversion.
</span><span class="cx"> 
</span><span class="cx"> template<typename ColorType> struct ColorConversion<ColorType, ColorType> {
</span><span class="lines">@@ -154,19 +144,21 @@
</span><span class="cx"> // │    Lab    │    ││ Gamma  │ │ GammaExtended  ││   │   ││ Gamma  │ │ GammaExtended  ││ ││ Gamma  │ │ GammaExtended  ││ ││ Gamma  │ │ GammaExtended  ││ ││ Gamma  │ │ GammaExtended  ││
</span><span class="cx"> // └─────▲─────┘    │└────────┘ └────────────────┘│   │   │└────▲───┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│
</span><span class="cx"> //       │          └─────────────────────────────┘   │   └─────┼───────────────────────┘ └─────────────────────────────┘ └─────────────────────────────┘ └─────────────────────────────┘
</span><del>-//       │                                            │      ┌──┴──────────┬─────────────┐
-//       │                                            │      │             │             │
-// ┌───────────┐                                      │┌───────────┐ ┌───────────┐┌─────────────┐
-// │    LCH    │                                      ││    HSL    │ │    HWB    ││SRGB<uint8_t>│
-// └───────────┘                                      │└───────────┘ └───────────┘└─────────────┘
</del><ins>+//       │                                            │      ┌──┴──────────┐
+//       │                                            │      │             │
+// ┌───────────┐                                      │┌───────────┐ ┌───────────┐
+// │    LCH    │                                      ││    HSL    │ │    HWB    │
+// └───────────┘                                      │└───────────┘ └───────────┘
</ins><span class="cx"> 
</span><span class="cx"> template<typename Output, typename Input, typename> struct ColorConversion {
</span><span class="cx"> public:
</span><span class="cx">     static constexpr Output convert(const Input& color)
</span><span class="cx">     {
</span><del>-        // 1. Handle the special case SRGBA<uint8_t> for Input and Output.
-        if constexpr (std::is_same_v<Input, SRGBA<uint8_t>> || std::is_same_v<Output, SRGBA<uint8_t>>)
-            return convertColor<Output>(convertColor<SRGBA<float>>(color));
</del><ins>+        // 1. Handle the special case of Input or Output with a uint8_t component type.
+        if constexpr (std::is_same_v<typename Input::ComponentType, uint8_t>)
+            return handleToFloatConversion(color);
+        else if constexpr (std::is_same_v<typename Output::ComponentType, uint8_t>)
+            return handleToByteConversion(color);
</ins><span class="cx"> 
</span><span class="cx">         // 2. Handle all color types that are not IsRGBType<T> or IsXYZA<T> for Input and Output. For all
</span><span class="cx">         //    these other color types, we can uncondtionally convert them to their "reference" color, as
</span><span class="lines">@@ -194,6 +186,28 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    static inline constexpr Output handleToFloatConversion(const Input& color)
+    {
+        static_assert(IsRGBBoundedType<Input>, "Only bounded ([0..1]) RGB color types support conversion to/from bytes.");
+
+        using InputWithReplacement = ColorTypeWithReplacementComponent<Input, float>;
+        if constexpr (std::is_same_v<InputWithReplacement, Output>)
+            return makeFromComponents<InputWithReplacement>(asColorComponents(color).map([](uint8_t value) -> float { return value / 255.0f; }));
+        else
+            return convertColor<Output>(convertColor<InputWithReplacement>(color));
+    }
+
+    static inline constexpr Output handleToByteConversion(const Input& color)
+    {
+        static_assert(IsRGBBoundedType<Output>, "Only bounded ([0..1]) RGB color types support conversion to/from bytes.");
+
+        using OutputWithReplacement = ColorTypeWithReplacementComponent<Output, float>;
+        if constexpr (std::is_same_v<OutputWithReplacement, Input>)
+            return makeFromComponents<Output>(asColorComponents(color).map([](float value) -> uint8_t { return std::clamp(std::lround(value * 255.0f), 0l, 255l); }));
+        else
+            return convertColor<Output>(convertColor<OutputWithReplacement>(color));
+    }
+
</ins><span class="cx">     template<typename ColorType> static inline constexpr auto toLinearEncoded(const ColorType& color) -> typename ColorType::LinearCounterpart
</span><span class="cx">     {
</span><span class="cx">         auto [c1, c2, c3, alpha] = color;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsColorTypesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ColorTypes.h (278069 => 278070)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ColorTypes.h      2021-05-26 00:37:19 UTC (rev 278069)
+++ trunk/Source/WebCore/platform/graphics/ColorTypes.h 2021-05-26 01:10:08 UTC (rev 278070)
</span><span class="lines">@@ -158,6 +158,9 @@
</span><span class="cx"> template<typename T> inline constexpr bool IsColorType = IsConvertibleToColorComponents<T> && HasComponentTypeMember<T>;
</span><span class="cx"> template<typename T, typename U> inline constexpr bool IsColorTypeWithComponentType = IsConvertibleToColorComponents<T> && HasComponentType<T, U>;
</span><span class="cx"> 
</span><ins>+template<template<typename> class ColorType, typename Replacement> struct ColorTypeReplacingComponentTypeHelper { using type = ColorType<Replacement>; };
+template<template<typename> class ColorType, typename Replacement> using ColorTypeReplacingComponentType = typename ColorTypeReplacingComponentTypeHelper<ColorType, Replacement>::type;
+
</ins><span class="cx"> template<typename Parent> struct ColorWithAlphaHelper {
</span><span class="cx">     // Helper to allow convenient syntax for working with color types.
</span><span class="cx">     // e.g. auto yellowWith50PercentAlpha = Color::yellow.colorWithAlphaByte(128);
</span><span class="lines">@@ -221,16 +224,18 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> template<typename T, typename D>
</span><del>-struct BoundedGammaEncoded : RGBAType<T, D, BoundedGammaEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Clamped>> {
-    using RGBAType<T, D, BoundedGammaEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Clamped>>::RGBAType;
</del><ins>+struct BoundedGammaEncoded : RGBAType<T, D, BoundedGammaEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Clamped>> {
+    using RGBAType<T, D, BoundedGammaEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Clamped>>::RGBAType;
</ins><span class="cx"> 
</span><span class="cx">     using LinearCounterpart = BoundedLinearEncoded<T, D>;
</span><span class="cx">     using ExtendedCounterpart = ExtendedGammaEncoded<T, D>;
</span><ins>+    
+    template<typename Replacement> using SelfWithReplacementComponent = BoundedGammaEncoded<Replacement, D>;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template<typename T, typename D>
</span><del>-struct BoundedLinearEncoded : RGBAType<T, D, BoundedLinearEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Clamped>> {
-    using RGBAType<T, D, BoundedLinearEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Clamped>>::RGBAType;
</del><ins>+struct BoundedLinearEncoded : RGBAType<T, D, BoundedLinearEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Clamped>> {
+    using RGBAType<T, D, BoundedLinearEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Clamped>>::RGBAType;
</ins><span class="cx"> 
</span><span class="cx">     static constexpr auto linearToXYZ = D::linearToXYZ;
</span><span class="cx">     static constexpr auto xyzToLinear = D::xyzToLinear;
</span><span class="lines">@@ -237,11 +242,13 @@
</span><span class="cx"> 
</span><span class="cx">     using GammaEncodedCounterpart = BoundedGammaEncoded<T, D>;
</span><span class="cx">     using ExtendedCounterpart = ExtendedLinearEncoded<T, D>;
</span><ins>+
+    template<typename Replacement> using SelfWithReplacementComponent = BoundedLinearEncoded<Replacement, D>;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template<typename T, typename D>
</span><del>-struct ExtendedGammaEncoded : RGBAType<T, D, ExtendedGammaEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Unclamped>> {
-    using RGBAType<T, D, ExtendedGammaEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Unclamped>>::RGBAType;
</del><ins>+struct ExtendedGammaEncoded : RGBAType<T, D, ExtendedGammaEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Unclamped>> {
+    using RGBAType<T, D, ExtendedGammaEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Unclamped>>::RGBAType;
</ins><span class="cx"> 
</span><span class="cx">     using LinearCounterpart = ExtendedLinearEncoded<T, D>;
</span><span class="cx">     using BoundedCounterpart = BoundedGammaEncoded<T, D>;
</span><span class="lines">@@ -249,8 +256,8 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template<typename T, typename D>
</span><del>-struct ExtendedLinearEncoded : RGBAType<T, D, ExtendedLinearEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Unclamped>> {
-    using RGBAType<T, D, ExtendedLinearEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Unclamped>>::RGBAType;
</del><ins>+struct ExtendedLinearEncoded : RGBAType<T, D, ExtendedLinearEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Unclamped>> {
+    using RGBAType<T, D, ExtendedLinearEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Unclamped>>::RGBAType;
</ins><span class="cx"> 
</span><span class="cx">     static constexpr auto linearToXYZ = D::linearToXYZ;
</span><span class="cx">     static constexpr auto xyzToLinear = D::xyzToLinear;
</span><span class="lines">@@ -275,6 +282,11 @@
</span><span class="cx"> template<typename, typename = void> inline constexpr bool HasLinearCounterpartMember = false;
</span><span class="cx"> template<typename ColorType> inline constexpr bool HasLinearCounterpartMember<ColorType, std::void_t<typename ColorType::LinearCounterpart>> = true;
</span><span class="cx"> 
</span><ins>+template<typename, typename = void> inline constexpr bool HasSelfWithReplacementComponentMember = false;
+template<typename ColorType> inline constexpr bool HasSelfWithReplacementComponentMember<ColorType, std::void_t<typename ColorType::SelfWithReplacementComponent>> = true;
+
+template<typename ColorType, typename Replacement> using ColorTypeWithReplacementComponent = typename ColorType::template SelfWithReplacementComponent<Replacement>;
+
</ins><span class="cx"> template<typename ColorType> inline constexpr bool IsRGBType = HasDescriptorMember<ColorType>;
</span><span class="cx"> template<typename ColorType> inline constexpr bool IsRGBExtendedType = IsRGBType<ColorType> && HasBoundedCounterpartMember<ColorType>;
</span><span class="cx"> template<typename ColorType> inline constexpr bool IsRGBBoundedType = IsRGBType<ColorType> && HasExtendedCounterpartMember<ColorType>;
</span><span class="lines">@@ -285,8 +297,8 @@
</span><span class="cx"> template<typename ColorType1, typename ColorType2> inline constexpr bool IsSameRGBTypeFamilyValue<ColorType1, ColorType2, true> = std::is_same_v<typename ColorType1::Descriptor, typename ColorType2::Descriptor>;
</span><span class="cx"> template<typename ColorType1, typename ColorType2> inline constexpr bool IsSameRGBTypeFamily = IsSameRGBTypeFamilyValue<ColorType1, ColorType2, IsRGBType<ColorType1> && IsRGBType<ColorType2>>;
</span><span class="cx"> 
</span><del>-template<typename T> struct SRGBADescriptor {
-    template<TransferFunctionMode Mode> using TransferFunction = SRGBTransferFunction<T, Mode>;
</del><ins>+struct SRGBADescriptor {
+    template<typename T, TransferFunctionMode Mode> using TransferFunction = SRGBTransferFunction<T, Mode>;
</ins><span class="cx">     static constexpr WhitePoint whitePoint = WhitePoint::D65;
</span><span class="cx"> 
</span><span class="cx">     // https://drafts.csswg.org/css-color/#color-conversion-code
</span><span class="lines">@@ -302,14 +314,14 @@
</span><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-template<typename T> using SRGBA = BoundedGammaEncoded<T, SRGBADescriptor<T>>;
-template<typename T> using LinearSRGBA = BoundedLinearEncoded<T, SRGBADescriptor<T>>;
-template<typename T> using ExtendedSRGBA = ExtendedGammaEncoded<T, SRGBADescriptor<T>>;
-template<typename T> using LinearExtendedSRGBA = ExtendedLinearEncoded<T, SRGBADescriptor<T>>;
</del><ins>+template<typename T> using SRGBA = BoundedGammaEncoded<T, SRGBADescriptor>;
+template<typename T> using LinearSRGBA = BoundedLinearEncoded<T, SRGBADescriptor>;
+template<typename T> using ExtendedSRGBA = ExtendedGammaEncoded<T, SRGBADescriptor>;
+template<typename T> using LinearExtendedSRGBA = ExtendedLinearEncoded<T, SRGBADescriptor>;
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-template<typename T> struct A98RGBDescriptor {
-    template<TransferFunctionMode Mode> using TransferFunction = A98RGBTransferFunction<T, Mode>;
</del><ins>+struct A98RGBDescriptor {
+    template<typename T, TransferFunctionMode Mode> using TransferFunction = A98RGBTransferFunction<T, Mode>;
</ins><span class="cx">     static constexpr WhitePoint whitePoint = WhitePoint::D65;
</span><span class="cx"> 
</span><span class="cx">     // https://drafts.csswg.org/css-color/#color-conversion-code
</span><span class="lines">@@ -325,12 +337,12 @@
</span><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-template<typename T> using A98RGB = BoundedGammaEncoded<T, A98RGBDescriptor<T>>;
-template<typename T> using LinearA98RGB = BoundedLinearEncoded<T, A98RGBDescriptor<T>>;
</del><ins>+template<typename T> using A98RGB = BoundedGammaEncoded<T, A98RGBDescriptor>;
+template<typename T> using LinearA98RGB = BoundedLinearEncoded<T, A98RGBDescriptor>;
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-template<typename T> struct DisplayP3Descriptor {
-    template<TransferFunctionMode Mode> using TransferFunction = SRGBTransferFunction<T, Mode>;
</del><ins>+struct DisplayP3Descriptor {
+    template<typename T, TransferFunctionMode Mode> using TransferFunction = SRGBTransferFunction<T, Mode>;
</ins><span class="cx">     static constexpr WhitePoint whitePoint = WhitePoint::D65;
</span><span class="cx"> 
</span><span class="cx">     // https://drafts.csswg.org/css-color/#color-conversion-code
</span><span class="lines">@@ -346,12 +358,12 @@
</span><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-template<typename T> using DisplayP3 = BoundedGammaEncoded<T, DisplayP3Descriptor<T>>;
-template<typename T> using LinearDisplayP3 = BoundedLinearEncoded<T, DisplayP3Descriptor<T>>;
</del><ins>+template<typename T> using DisplayP3 = BoundedGammaEncoded<T, DisplayP3Descriptor>;
+template<typename T> using LinearDisplayP3 = BoundedLinearEncoded<T, DisplayP3Descriptor>;
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-template<typename T> struct ProPhotoRGBDescriptor {
-    template<TransferFunctionMode Mode> using TransferFunction = ProPhotoRGBTransferFunction<T, Mode>;
</del><ins>+struct ProPhotoRGBDescriptor {
+    template<typename T, TransferFunctionMode Mode> using TransferFunction = ProPhotoRGBTransferFunction<T, Mode>;
</ins><span class="cx">     static constexpr WhitePoint whitePoint = WhitePoint::D50;
</span><span class="cx"> 
</span><span class="cx">     // https://drafts.csswg.org/css-color/#color-conversion-code
</span><span class="lines">@@ -367,12 +379,12 @@
</span><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-template<typename T> using ProPhotoRGB = BoundedGammaEncoded<T, ProPhotoRGBDescriptor<T>>;
-template<typename T> using LinearProPhotoRGB = BoundedLinearEncoded<T, ProPhotoRGBDescriptor<T>>;
</del><ins>+template<typename T> using ProPhotoRGB = BoundedGammaEncoded<T, ProPhotoRGBDescriptor>;
+template<typename T> using LinearProPhotoRGB = BoundedLinearEncoded<T, ProPhotoRGBDescriptor>;
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-template<typename T> struct Rec2020Descriptor {
-    template<TransferFunctionMode Mode> using TransferFunction = Rec2020TransferFunction<T, Mode>;
</del><ins>+struct Rec2020Descriptor {
+    template<typename T, TransferFunctionMode Mode> using TransferFunction = Rec2020TransferFunction<T, Mode>;
</ins><span class="cx">     static constexpr WhitePoint whitePoint = WhitePoint::D65;
</span><span class="cx"> 
</span><span class="cx">     // https://drafts.csswg.org/css-color/#color-conversion-code
</span><span class="lines">@@ -388,8 +400,8 @@
</span><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-template<typename T> using Rec2020 = BoundedGammaEncoded<T, Rec2020Descriptor<T>>;
-template<typename T> using LinearRec2020 = BoundedLinearEncoded<T, Rec2020Descriptor<T>>;
</del><ins>+template<typename T> using Rec2020 = BoundedGammaEncoded<T, Rec2020Descriptor>;
+template<typename T> using LinearRec2020 = BoundedLinearEncoded<T, Rec2020Descriptor>;
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> // MARK: - Lab Color Type.
</span></span></pre>
</div>
</div>

</body>
</html>