Title: [264272] trunk
Revision
264272
Author
[email protected]
Date
2020-07-11 18:01:25 -0700 (Sat, 11 Jul 2020)

Log Message

Reduce surface area of the ExtendedColor class to a bare minimum
https://bugs.webkit.org/show_bug.cgi?id=214204

Reviewed by Darin Adler.

Source/WebCore:

- Add helper function to Color to operate on the underlying color type
  and reimplement a bunch of functionality using it, reducing the need
  for duplicate implementations in ExtendedColor.
- Add constructors to Color that take extended color types, replacing
  the makeExtendedColor helper function.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
Remove ExtenedColor.cpp

* css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::parseColorFunctionParameters):
Use new Color constructor taking ColorComponents and ColorSpace.

* platform/graphics/Color.cpp:
(WebCore::Color::colorWithAlpha const): Reimpliment using callOnUnderlyingType.
(WebCore::Color::invertedColorWithAlpha const): Reimpliment using callOnUnderlyingType.
* platform/graphics/Color.h:
(WebCore::Color::Color):
(WebCore::Color::hash const):
(WebCore::Color::callOnUnderlyingType const):
(WebCore::Color::toSRGBALossy const):
(WebCore::Color::setColor):
(WebCore::Color::isBlackColor):
(WebCore::Color::isWhiteColor):
- Add new constructors taking extended color types: SRGBA<float>, LinearSRGBA<float> and DiplayP3<float>.
- Add new function, callOnUnderlyingType, to make working with any underlying type more streamlined.

* platform/graphics/ColorConversion.h:
(WebCore::toSRGBA):
(WebCore::toLinearSRGBA):
(WebCore::toDisplayP3):
(WebCore::toLinearDisplayP3):
(WebCore::toHSLA):
Add identity conversion functions to make implementing generic functions like Color::toSRGBALossy more
straigtforward.

* platform/graphics/ColorSerialization.cpp:
(WebCore::serialization):
(WebCore::serializationForCSS):
(WebCore::serializationForHTML):
(WebCore::serializationForRenderTreeAsText):
* platform/graphics/ColorSerialization.h:
Replace serialization of the ExtendedColor type itself, with serialization for the underlying color
types. Use callOnUnderlyingType to dispatch to the right one.

* platform/graphics/ColorTypes.h:
- Adds ComponentTraits struct to get information like min/max value of the component types.
- Adds `using ComponentType = T;` to each color type, to allow easy access to the type in
  deduced contexts.
- Adds static constexpr ColorSpace to each color type that currently has a ColorSpace mapping.

* platform/graphics/ColorUtilities.h:
(WebCore::isBlack):
(WebCore::isWhite):
Add helpers to implement Color::isBlack/Color::isWhiteColor for each color type.

* platform/graphics/ExtendedColor.cpp: Removed.
* platform/graphics/ExtendedColor.h:
(WebCore::ExtendedColor::create):
(WebCore::ExtendedColor::ExtendedColor):
(WebCore::ExtendedColor::callOnUnderlyingType const):
(WebCore::ExtendedColor::toSRGBALossy const): Deleted.
Reduce down to just construction, member access and the callOnUnderlyingType helper.
In future revisions, ExtendedColor should be converted to an internal class of Color.

* platform/graphics/gtk/ColorGtk.cpp:
(WebCore::Color::Color):
* platform/graphics/win/ColorDirect2D.cpp:
(WebCore::Color::Color):
Update to use constructor delegation.

Tools:

* TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp:
(TestWebKitAPI::TEST):
(TestWebKitAPI::makeColor):
Update using new Color constructor for extended colors.

Modified Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (264271 => 264272)


--- trunk/Source/WebCore/ChangeLog	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/ChangeLog	2020-07-12 01:01:25 UTC (rev 264272)
@@ -1,3 +1,82 @@
+2020-07-11  Sam Weinig  <[email protected]>
+
+        Reduce surface area of the ExtendedColor class to a bare minimum
+        https://bugs.webkit.org/show_bug.cgi?id=214204
+
+        Reviewed by Darin Adler.
+
+        - Add helper function to Color to operate on the underlying color type
+          and reimplement a bunch of functionality using it, reducing the need
+          for duplicate implementations in ExtendedColor.
+        - Add constructors to Color that take extended color types, replacing
+          the makeExtendedColor helper function. 
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        Remove ExtenedColor.cpp
+
+        * css/parser/CSSPropertyParserHelpers.cpp:
+        (WebCore::CSSPropertyParserHelpers::parseColorFunctionParameters):
+        Use new Color constructor taking ColorComponents and ColorSpace.
+
+        * platform/graphics/Color.cpp:
+        (WebCore::Color::colorWithAlpha const): Reimpliment using callOnUnderlyingType.
+        (WebCore::Color::invertedColorWithAlpha const): Reimpliment using callOnUnderlyingType.
+        * platform/graphics/Color.h:
+        (WebCore::Color::Color):  
+        (WebCore::Color::hash const):
+        (WebCore::Color::callOnUnderlyingType const):
+        (WebCore::Color::toSRGBALossy const):
+        (WebCore::Color::setColor):
+        (WebCore::Color::isBlackColor):
+        (WebCore::Color::isWhiteColor):
+        - Add new constructors taking extended color types: SRGBA<float>, LinearSRGBA<float> and DiplayP3<float>.
+        - Add new function, callOnUnderlyingType, to make working with any underlying type more streamlined.
+
+        * platform/graphics/ColorConversion.h:
+        (WebCore::toSRGBA):
+        (WebCore::toLinearSRGBA):
+        (WebCore::toDisplayP3):
+        (WebCore::toLinearDisplayP3):
+        (WebCore::toHSLA):
+        Add identity conversion functions to make implementing generic functions like Color::toSRGBALossy more
+        straigtforward.
+
+        * platform/graphics/ColorSerialization.cpp:
+        (WebCore::serialization):
+        (WebCore::serializationForCSS):
+        (WebCore::serializationForHTML):
+        (WebCore::serializationForRenderTreeAsText):
+        * platform/graphics/ColorSerialization.h:
+        Replace serialization of the ExtendedColor type itself, with serialization for the underlying color
+        types. Use callOnUnderlyingType to dispatch to the right one.
+
+        * platform/graphics/ColorTypes.h:
+        - Adds ComponentTraits struct to get information like min/max value of the component types.
+        - Adds `using ComponentType = T;` to each color type, to allow easy access to the type in
+          deduced contexts.
+        - Adds static constexpr ColorSpace to each color type that currently has a ColorSpace mapping. 
+
+        * platform/graphics/ColorUtilities.h:
+        (WebCore::isBlack):
+        (WebCore::isWhite):
+        Add helpers to implement Color::isBlack/Color::isWhiteColor for each color type.
+
+        * platform/graphics/ExtendedColor.cpp: Removed.
+        * platform/graphics/ExtendedColor.h:
+        (WebCore::ExtendedColor::create):
+        (WebCore::ExtendedColor::ExtendedColor):
+        (WebCore::ExtendedColor::callOnUnderlyingType const):
+        (WebCore::ExtendedColor::toSRGBALossy const): Deleted.
+        Reduce down to just construction, member access and the callOnUnderlyingType helper.
+        In future revisions, ExtendedColor should be converted to an internal class of Color.
+
+        * platform/graphics/gtk/ColorGtk.cpp:
+        (WebCore::Color::Color):
+        * platform/graphics/win/ColorDirect2D.cpp:
+        (WebCore::Color::Color):
+        Update to use constructor delegation.
+
 2020-07-11  Darin Adler  <[email protected]>
 
         Remove live ranges from AccessibilityObject.h, AccessibilityObjectInterface.h, AccessibilityRenderObject.h, AXIsolatedObject.h

Modified: trunk/Source/WebCore/Sources.txt (264271 => 264272)


--- trunk/Source/WebCore/Sources.txt	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/Sources.txt	2020-07-12 01:01:25 UTC (rev 264272)
@@ -1827,7 +1827,6 @@
 platform/graphics/DisplayRefreshMonitor.cpp
 platform/graphics/DisplayRefreshMonitorClient.cpp
 platform/graphics/DisplayRefreshMonitorManager.cpp
-platform/graphics/ExtendedColor.cpp
 platform/graphics/FloatPoint.cpp
 platform/graphics/FloatPoint3D.cpp
 platform/graphics/FloatPolygon.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (264271 => 264272)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-07-12 01:01:25 UTC (rev 264272)
@@ -7228,7 +7228,6 @@
 		31D26BC51F86D268008FF255 /* JSImageBitmapOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSImageBitmapOptions.h; sourceTree = "<group>"; };
 		31D26BC61F86D269008FF255 /* JSImageBitmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSImageBitmap.cpp; sourceTree = "<group>"; };
 		31D591B116697A6C00E6BF02 /* PlugInClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlugInClient.h; sourceTree = "<group>"; };
-		31DCDF411DA1C45400EA5B93 /* ExtendedColor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExtendedColor.cpp; sourceTree = "<group>"; };
 		31DCDF421DA1C45400EA5B93 /* ExtendedColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtendedColor.h; sourceTree = "<group>"; };
 		31DEA4531B39F4D900F77178 /* WebSystemBackdropLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebSystemBackdropLayer.mm; sourceTree = "<group>"; };
 		31DEA4541B39F4D900F77178 /* WebSystemBackdropLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSystemBackdropLayer.h; sourceTree = "<group>"; };
@@ -19582,8 +19581,8 @@
 			children = (
 				515BE1971D54F6BD00DD7C68 /* HIDGamepad.cpp */,
 				515BE1981D54F6BD00DD7C68 /* HIDGamepad.h */,
+				515BE19A1D54F6BD00DD7C68 /* HIDGamepadProvider.h */,
 				515BE1991D54F6BD00DD7C68 /* HIDGamepadProvider.mm */,
-				515BE19A1D54F6BD00DD7C68 /* HIDGamepadProvider.h */,
 				517E03F424B6B9630054895A /* MultiGamepadProvider.h */,
 				517E03F524B6B9640054895A /* MultiGamepadProvider.mm */,
 			);
@@ -25556,7 +25555,6 @@
 				2D29ECC2192ECC8300984B78 /* DisplayRefreshMonitorClient.h */,
 				2D29ECC3192ECC8300984B78 /* DisplayRefreshMonitorManager.cpp */,
 				2D29ECC4192ECC8300984B78 /* DisplayRefreshMonitorManager.h */,
-				31DCDF411DA1C45400EA5B93 /* ExtendedColor.cpp */,
 				31DCDF421DA1C45400EA5B93 /* ExtendedColor.h */,
 				6E67D2A81280E8BD008758F7 /* ExtensionsGL.h */,
 				B275353A0B053814002CE64F /* FloatPoint.cpp */,
@@ -26880,7 +26878,6 @@
 		CD94A5CB1F71CB4600F525C5 /* encryptedmedia */ = {
 			isa = PBXGroup;
 			children = (
-				CDE3AE1324B4936F00128E7E /* CDMUtilities.cpp */,
 				CD94A5D91F71CB9F00F525C5 /* clearkey */,
 				CDF7569B215C23A400EFCB50 /* CDMEncryptionScheme.h */,
 				CD94A5D11F71CB6B00F525C5 /* CDMFactory.cpp */,
@@ -26895,12 +26892,13 @@
 				CD94A5D61F71CB6D00F525C5 /* CDMMessageType.h */,
 				CD3CE11C240451AF004BA01D /* CDMPrivate.cpp */,
 				CD94A5CF1F71CB6A00F525C5 /* CDMPrivate.h */,
-				CDE3AE1024B4916900128E7E /* CDMUtilities.h */,
 				CD94A5CF1F71CB6100F525D5 /* CDMProxy.cpp */,
 				CD94A5CF1F71CB6100F525C5 /* CDMProxy.h */,
 				CD94A5CC1F71CB6900F525C5 /* CDMRequirement.h */,
 				CD94A5D01F71CB6B00F525C5 /* CDMRestrictions.h */,
 				CD94A5D51F71CB6D00F525C5 /* CDMSessionType.h */,
+				CDE3AE1324B4936F00128E7E /* CDMUtilities.cpp */,
+				CDE3AE1024B4916900128E7E /* CDMUtilities.h */,
 			);
 			path = encryptedmedia;
 			sourceTree = "<group>";
@@ -30082,6 +30080,7 @@
 				CD3CE1032401AADA004BA01D /* CDMRestrictions.h in Headers */,
 				CDE595971BF26E2100A1CBE8 /* CDMSessionMediaSourceAVFObjC.h in Headers */,
 				CD3CE1042401AADA004BA01D /* CDMSessionType.h in Headers */,
+				CDE3AE1224B4916A00128E7E /* CDMUtilities.h in Headers */,
 				5FA904CA178E61F5004C8A2D /* CertificateInfo.h in Headers */,
 				91B8F0B521953D65000C2B00 /* CertificateInfoBase.h in Headers */,
 				FE36FD1516C7826500F887C1 /* ChangeVersionData.h in Headers */,
@@ -31219,7 +31218,6 @@
 				F344C75311294D9D00F26EEE /* InspectorFrontendClientLocal.h in Headers */,
 				7A0E770F10C00A8800A0276E /* InspectorFrontendHost.h in Headers */,
 				7A54858014E02D51006AE05A /* InspectorHistory.h in Headers */,
-				CDE3AE1224B4916A00128E7E /* CDMUtilities.h in Headers */,
 				A5B81CAE1FAA44620037D1E6 /* InspectorIndexedDBAgent.h in Headers */,
 				20D629271253690B00081543 /* InspectorInstrumentation.h in Headers */,
 				A5860E6D230DE30300461AAE /* InspectorInstrumentationPublic.h in Headers */,
@@ -32402,6 +32400,7 @@
 				85031B480A44EFC700F992E0 /* MouseRelatedEvent.h in Headers */,
 				93309DFC099E64920056E581 /* MoveSelectionCommand.h in Headers */,
 				FDB1700614A2BAB200A2B5D9 /* MultiChannelResampler.h in Headers */,
+				517E03F724B6D9840054895A /* MultiGamepadProvider.h in Headers */,
 				26F756B01B3B65AC0005DD79 /* MutableRange.h in Headers */,
 				26F756B11B3B65AC0005DD79 /* MutableRangeList.h in Headers */,
 				C6F0900A14327B6100685849 /* MutationCallback.h in Headers */,
@@ -33281,7 +33280,6 @@
 				ECA680C71E67724500731D20 /* StringUtilities.h in Headers */,
 				9B6C41531344949000085B62 /* StringWithDirection.h in Headers */,
 				849F77760EFEC6200090849D /* StrokeStyleApplier.h in Headers */,
-				517E03F724B6D9840054895A /* MultiGamepadProvider.h in Headers */,
 				414B82051D6DF0E50077EBE3 /* StructuredClone.h in Headers */,
 				E45BA6B6237622A3004DFC07 /* StyleAdjuster.h in Headers */,
 				BC5EB6A30E81DC4F00B25965 /* StyleBackgroundData.h in Headers */,
@@ -34473,6 +34471,7 @@
 				CDDE02ED18B3ED6D00CF7FF1 /* CDMSessionAVFoundationObjC.mm in Sources */,
 				CDDE02F018B5651300CF7FF1 /* CDMSessionAVStreamSession.mm in Sources */,
 				CDE5959D1BF2757100A1CBE8 /* CDMSessionMediaSourceAVFObjC.mm in Sources */,
+				CDE3AE1424B4937000128E7E /* CDMUtilities.cpp in Sources */,
 				A14090FB1AA51E1D0091191A /* ContentFilterUnblockHandlerCocoa.mm in Sources */,
 				07AFF4231EFB144900B545B3 /* CoreAudioCaptureSourceIOS.mm in Sources */,
 				46C696CC1E7205FC00597937 /* CPUMonitor.cpp in Sources */,
@@ -34802,7 +34801,6 @@
 				DECA7DB71F9E67B600E3B661 /* UnifiedSource167.cpp in Sources */,
 				DECA7DB81F9E67B600E3B661 /* UnifiedSource168.cpp in Sources */,
 				DECA7DB91F9E67B600E3B661 /* UnifiedSource169.cpp in Sources */,
-				CDE3AE1424B4937000128E7E /* CDMUtilities.cpp in Sources */,
 				DECA7DBA1F9E67B600E3B661 /* UnifiedSource170.cpp in Sources */,
 				DECA7DFB1F9EB36400E3B661 /* UnifiedSource171.cpp in Sources */,
 				DECA7DFC1F9EB36400E3B661 /* UnifiedSource172.cpp in Sources */,

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (264271 => 264272)


--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2020-07-12 01:01:25 UTC (rev 264272)
@@ -658,7 +658,7 @@
         colorSpace = ColorSpace::DisplayP3;
         break;
     default:
-        return Color();
+        return { };
     }
     consumeIdent(args);
 
@@ -676,7 +676,7 @@
         if (!alphaParameter)
             alphaParameter = consumeNumber(args, ValueRangeAll);
         if (!alphaParameter)
-            return Color();
+            return { };
 
         colorChannels[3] = std::max(0.0, std::min(1.0, alphaParameter->isPercentage() ? (alphaParameter->doubleValue() / 100) : alphaParameter->doubleValue()));
     }
@@ -684,9 +684,9 @@
     // FIXME: Support the comma-separated list of fallback color values.
 
     if (!args.atEnd())
-        return Color();
-    
-    return makeExtendedColor(colorChannels[0], colorChannels[1], colorChannels[2], colorChannels[3], colorSpace);
+        return { };
+
+    return Color { ColorComponents { static_cast<float>(colorChannels[0]), static_cast<float>(colorChannels[1]), static_cast<float>(colorChannels[2]), static_cast<float>(colorChannels[3]) }, colorSpace };
 }
 
 static Optional<SRGBA<uint8_t>> parseHexColor(CSSParserTokenRange& range, bool acceptQuirkyColors)

Modified: trunk/Source/WebCore/platform/graphics/Color.cpp (264271 => 264272)


--- trunk/Source/WebCore/platform/graphics/Color.cpp	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/platform/graphics/Color.cpp	2020-07-12 01:01:25 UTC (rev 264272)
@@ -26,12 +26,9 @@
 #include "config.h"
 #include "Color.h"
 
-#include "AnimationUtilities.h"
 #include "ColorSerialization.h"
 #include "ColorUtilities.h"
 #include <wtf/Assertions.h>
-#include <wtf/MathExtras.h>
-#include <wtf/text/StringBuilder.h>
 #include <wtf/text/TextStream.h>
 
 namespace WebCore {
@@ -126,22 +123,26 @@
 
 Color Color::colorWithAlpha(float alpha) const
 {
-    if (isExtended())
-        return asExtended().colorWithAlpha(alpha);
+    return callOnUnderlyingType(WTF::makeVisitor(
+        [&] (const SRGBA<uint8_t>& underlyingColor) -> Color {
+            Color result = colorWithOverridenAlpha(underlyingColor, alpha);
 
-    Color result = colorWithOverridenAlpha(asInline(), alpha);
-
-    // FIXME: Why is preserving the semantic bit desired and/or correct here?
-    if (isSemantic())
-        result.tagAsSemantic();
-    return result;
+            // FIXME: Why is preserving the semantic bit desired and/or correct here?
+            if (isSemantic())
+                result.tagAsSemantic();
+            return result;
+        },
+        [&] (const auto& underlyingColor) -> Color {
+            return colorWithOverridenAlpha(underlyingColor, alpha);
+        }
+    ));
 }
 
 Color Color::invertedColorWithAlpha(float alpha) const
 {
-    if (isExtended())
-        return asExtended().invertedColorWithAlpha(alpha);
-    return invertedColorWithOverridenAlpha(asInline(), alpha);
+    return callOnUnderlyingType([&] (const auto& underlyingColor) -> Color {
+        return invertedColorWithOverridenAlpha(underlyingColor, alpha);
+    });
 }
 
 Color Color::semanticColor() const

Modified: trunk/Source/WebCore/platform/graphics/Color.h (264271 => 264272)


--- trunk/Source/WebCore/platform/graphics/Color.h	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/platform/graphics/Color.h	2020-07-12 01:01:25 UTC (rev 264272)
@@ -30,6 +30,7 @@
 #include "SimpleColor.h"
 #include <wtf/Forward.h>
 #include <wtf/HashFunctions.h>
+#include <wtf/Hasher.h>
 #include <wtf/Optional.h>
 
 #if USE(CG)
@@ -51,6 +52,18 @@
 
 namespace WebCore {
 
+// Able to represent:
+//    - Special "invalid color" state, treated as transparent black but distinguishable
+//    - 4x 8-bit (0-255) sRGBA, stored inline, no allocation
+//    - 4x float (0-1) sRGBA, stored in a reference counted sub-object
+//    - 4x float (0-1) Linear sRGBA, stored in a reference counted sub-object
+//    - 4x float (0-1) DisplayP3, stored in a reference counted sub-object
+//
+// Additionally, the inline 8-bit sRGBA can have an optional "semantic" bit set on it,
+// which indicates the color originated from a CSS semantic color name.
+// FIXME: If we keep the "semantic" bit on Color, we should extend support to all colors,
+// not just inline ones, by using the unused pointer bits.
+
 class Color {
     WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -63,7 +76,10 @@
     Color(SRGBA<uint8_t>, SemanticTag);
     Color(Optional<SRGBA<uint8_t>>, SemanticTag);
 
-    Color(Ref<ExtendedColor>&&);
+    Color(ColorComponents<float>, ColorSpace);
+    Color(const SRGBA<float>&);
+    Color(const LinearSRGBA<float>&);
+    Color(const DisplayP3<float>&);
 
     explicit Color(WTF::HashTableEmptyValueType);
     explicit Color(WTF::HashTableDeletedValueType);
@@ -72,34 +88,34 @@
     WEBCORE_EXPORT Color(const Color&);
     WEBCORE_EXPORT Color(Color&&);
 
+    WEBCORE_EXPORT Color& operator=(const Color&);
+    WEBCORE_EXPORT Color& operator=(Color&&);
+
     ~Color();
 
+    unsigned hash() const;
+
     bool isValid() const { return isExtended() || (m_colorData.inlineColorAndFlags & validInlineColorBit); }
-
-    // True if the color originated from a CSS semantic color name.
     bool isSemantic() const { return isInline() && (m_colorData.inlineColorAndFlags & isSemanticInlineColorBit); }
 
     bool isOpaque() const { return isExtended() ? asExtended().alpha() == 1.0 : asInline().alpha == 255; }
     bool isVisible() const { return isExtended() ? asExtended().alpha() > 0.0 : asInline().alpha > 0; }
-
     uint8_t alpha() const { return isExtended() ? convertToComponentByte(asExtended().alpha()) : asInline().alpha; }
     float alphaAsFloat() const { return isExtended() ? asExtended().alpha() : convertToComponentFloat(asInline().alpha); }
 
-    unsigned hash() const;
+    WEBCORE_EXPORT float luminance() const;
+    WEBCORE_EXPORT float lightness() const; // FIXME: Replace remaining uses with luminance.
 
-    WEBCORE_EXPORT std::pair<ColorSpace, ColorComponents<float>> colorSpaceAndComponents() const;
+    template<typename Functor> decltype(auto) callOnUnderlyingType(Functor&&) const;
 
     // This will convert non-sRGB colorspace colors into sRGB.
     template<typename T> SRGBA<T> toSRGBALossy() const;
 
+    WEBCORE_EXPORT std::pair<ColorSpace, ColorComponents<float>> colorSpaceAndComponents() const;
+
     WEBCORE_EXPORT Color lightened() const;
     WEBCORE_EXPORT Color darkened() const;
 
-    WEBCORE_EXPORT float luminance() const;
-
-    // FIXME: Replace remaining uses with luminance.
-    WEBCORE_EXPORT float lightness() const;
-
     Color invertedColorWithAlpha(Optional<float> alpha) const;
     Color invertedColorWithAlpha(float alpha) const;
 
@@ -144,9 +160,6 @@
     const ExtendedColor& asExtended() const;
     SRGBA<uint8_t> asInline() const;
 
-    WEBCORE_EXPORT Color& operator=(const Color&);
-    WEBCORE_EXPORT Color& operator=(Color&&);
-
     // Extended and non-extended colors will always be non-equal.
     friend bool operator==(const Color& a, const Color& b);
     friend bool equalIgnoringSemanticColor(const Color& a, const Color& b);
@@ -159,7 +172,12 @@
     template<class Decoder> static Optional<Color> decode(Decoder&);
 
 private:
-    void setInlineColor(SRGBA<uint8_t>);
+    Color(Ref<ExtendedColor>&&);
+
+    void setColor(SRGBA<uint8_t>);
+    void setColor(const SRGBA<float>&);
+    void setColor(const LinearSRGBA<float>&);
+    void setColor(const DisplayP3<float>&);
     void setExtendedColor(Ref<ExtendedColor>&&);
 
     void tagAsSemantic() { m_colorData.inlineColorAndFlags |= isSemanticInlineColorBit; }
@@ -227,18 +245,18 @@
 
 inline Color::Color(SRGBA<uint8_t> color)
 {
-    setInlineColor(color);
+    setColor(color);
 }
 
 inline Color::Color(Optional<SRGBA<uint8_t>> color)
 {
     if (color)
-        setInlineColor(*color);
+        setColor(*color);
 }
 
 inline Color::Color(SRGBA<uint8_t> color, SemanticTag)
 {
-    setInlineColor(color);
+    setColor(color);
     tagAsSemantic();
 }
 
@@ -245,11 +263,41 @@
 inline Color::Color(Optional<SRGBA<uint8_t>> color, SemanticTag)
 {
     if (color) {
-        setInlineColor(*color);
+        setColor(*color);
         tagAsSemantic();
     }
 }
 
+inline Color::Color(ColorComponents<float> components, ColorSpace colorSpace)
+{
+    switch (colorSpace) {
+    case ColorSpace::SRGB:
+        setColor(asSRGBA(components));
+        return;
+    case ColorSpace::LinearRGB:
+        setColor(asLinearSRGBA(components));
+        return;
+    case ColorSpace::DisplayP3:
+        setColor(asDisplayP3(components));
+        return;
+    }
+}
+
+inline Color::Color(const SRGBA<float>& color)
+{
+    setColor(color);
+}
+
+inline Color::Color(const LinearSRGBA<float>& color)
+{
+    setColor(color);
+}
+
+inline Color::Color(const DisplayP3<float>& color)
+{
+    setColor(color);
+}
+
 inline Color::Color(Ref<ExtendedColor>&& extendedColor)
 {
     setExtendedColor(WTFMove(extendedColor));
@@ -281,20 +329,35 @@
 inline unsigned Color::hash() const
 {
     if (isExtended())
-        return asExtended().hash();
+        return computeHash(asExtended().components(), asExtended().colorSpace());
     return WTF::intHash(m_colorData.inlineColorAndFlags);
 }
 
-template<typename T> SRGBA<T> Color::toSRGBALossy() const
+template<typename Functor> decltype(auto) Color::callOnUnderlyingType(Functor&& functor) const
 {
     if (isExtended())
-        return asExtended().toSRGBALossy<T>();
-    if constexpr (std::is_same_v<T, uint8_t>)
-        return asInline();
-    if constexpr (std::is_same_v<T, float>)
-        return convertToComponentFloats(asInline());
+        return asExtended().callOnUnderlyingType(std::forward<Functor>(functor));
+    return std::invoke(std::forward<Functor>(functor), asInline());
 }
 
+template<typename T> SRGBA<T> Color::toSRGBALossy() 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 convertToComponentFloats(color);
+        },
+        [] (const auto& color) {
+            if constexpr (std::is_same_v<T, uint8_t>)
+                return convertToComponentBytes(toSRGBA(color));
+            if constexpr (std::is_same_v<T, float>)
+                return toSRGBA(color);
+        }
+    ));
+}
+
 inline Color Color::invertedColorWithAlpha(Optional<float> alpha) const
 {
     return alpha ? invertedColorWithAlpha(alpha.value()) : *this;
@@ -327,12 +390,27 @@
     return asSRGBA(Packed::RGBA { static_cast<uint32_t>(m_colorData.inlineColorAndFlags >> 32) });
 }
 
-inline void Color::setInlineColor(SRGBA<uint8_t> color)
+inline void Color::setColor(SRGBA<uint8_t> color)
 {
     m_colorData.inlineColorAndFlags = static_cast<uint64_t>(Packed::RGBA { color }.value) << 32;
     tagAsValid();
 }
 
+inline void Color::setColor(const SRGBA<float>& color)
+{
+    setExtendedColor(ExtendedColor::create(color));
+}
+
+inline void Color::setColor(const LinearSRGBA<float>& color)
+{
+    setExtendedColor(ExtendedColor::create(color));
+}
+
+inline void Color::setColor(const DisplayP3<float>& color)
+{
+    setExtendedColor(ExtendedColor::create(color));
+}
+
 inline void Color::setExtendedColor(Ref<ExtendedColor>&& extendedColor)
 {
     // Zero the union, just in case a 32-bit system only assigns the
@@ -344,20 +422,19 @@
 
 inline bool Color::isBlackColor(const Color& color)
 {
-    if (color.isExtended())
-        return color.asExtended().isBlack();
-    return color.asInline() == Color::black;
+    return color.callOnUnderlyingType([] (const auto& color) {
+        return WebCore::isBlack(color);
+    });
 }
 
 inline bool Color::isWhiteColor(const Color& color)
 {
-    if (color.isExtended())
-        return color.asExtended().isWhite();
-    return color.asInline() == Color::white;
+    return color.callOnUnderlyingType([] (const auto& color) {
+        return WebCore::isWhite(color);
+    });
 }
 
-template<class Encoder>
-void Color::encode(Encoder& encoder) const
+template<class Encoder> void Color::encode(Encoder& encoder) const
 {
     if (isExtended()) {
         encoder << true;
@@ -385,8 +462,7 @@
     encoder << Packed::RGBA { asInline() }.value;
 }
 
-template<class Decoder>
-Optional<Color> Color::decode(Decoder& decoder)
+template<class Decoder> Optional<Color> Color::decode(Decoder& decoder)
 {
     bool isExtended;
     if (!decoder.decode(isExtended))
@@ -408,7 +484,7 @@
             return WTF::nullopt;
         if (!decoder.decode(colorSpace))
             return WTF::nullopt;
-        return Color { ExtendedColor::create(c1, c2, c3, alpha, colorSpace) };
+        return Color { ExtendedColor::create({ c1, c2, c3, alpha }, colorSpace) };
     }
 
     bool isValid;

Modified: trunk/Source/WebCore/platform/graphics/ColorConversion.h (264271 => 264272)


--- trunk/Source/WebCore/platform/graphics/ColorConversion.h	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/platform/graphics/ColorConversion.h	2020-07-12 01:01:25 UTC (rev 264272)
@@ -25,27 +25,22 @@
 
 #pragma once
 
+#include "ColorTypes.h"
+
 namespace WebCore {
 
-template<typename> struct CMYKA;
-template<typename> struct DisplayP3;
-template<typename> struct HSLA;
-template<typename> struct LinearDisplayP3;
-template<typename> struct LinearSRGBA;
-template<typename> struct SRGBA;
-
 // These are the standard sRGB <-> LinearRGB / DisplayP3 <-> LinearDisplayP3 conversion functions (https://en.wikipedia.org/wiki/SRGB).
 float linearToRGBColorComponent(float);
 float rgbToLinearColorComponent(float);
 
-LinearSRGBA<float> toLinearSRGBA(const SRGBA<float>&);
-SRGBA<float> toSRGBA(const LinearSRGBA<float>&);
+WEBCORE_EXPORT LinearSRGBA<float> toLinearSRGBA(const SRGBA<float>&);
+WEBCORE_EXPORT SRGBA<float> toSRGBA(const LinearSRGBA<float>&);
 
-LinearDisplayP3<float> toLinearDisplayP3(const DisplayP3<float>&);
-DisplayP3<float> toDisplayP3(const LinearDisplayP3<float>&);
+WEBCORE_EXPORT LinearDisplayP3<float> toLinearDisplayP3(const DisplayP3<float>&);
+WEBCORE_EXPORT DisplayP3<float> toDisplayP3(const LinearDisplayP3<float>&);
 
-SRGBA<float> toSRGBA(const DisplayP3<float>&);
-DisplayP3<float> toDisplayP3(const SRGBA<float>&);
+WEBCORE_EXPORT SRGBA<float> toSRGBA(const DisplayP3<float>&);
+WEBCORE_EXPORT DisplayP3<float> toDisplayP3(const SRGBA<float>&);
 
 WEBCORE_EXPORT HSLA<float> toHSLA(const SRGBA<float>&);
 WEBCORE_EXPORT SRGBA<float> toSRGBA(const HSLA<float>&);
@@ -52,4 +47,13 @@
 
 SRGBA<float> toSRGBA(const CMYKA<float>&);
 
+
+// Identity conversions (useful for generic contexts)
+
+constexpr SRGBA<float> toSRGBA(const SRGBA<float>& color) { return color; }
+constexpr LinearSRGBA<float> toLinearSRGBA(const LinearSRGBA<float>& color) { return color; }
+constexpr DisplayP3<float> toDisplayP3(const DisplayP3<float>& color) { return color; }
+constexpr LinearDisplayP3<float> toLinearDisplayP3(const LinearDisplayP3<float>& color) { return color; }
+constexpr HSLA<float> toHSLA(const HSLA<float>& color) { return color; }
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/ColorSerialization.cpp (264271 => 264272)


--- trunk/Source/WebCore/platform/graphics/ColorSerialization.cpp	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/platform/graphics/ColorSerialization.cpp	2020-07-12 01:01:25 UTC (rev 264272)
@@ -100,45 +100,87 @@
     return ""_s;
 }
 
-String serializationForCSS(const ExtendedColor& color)
+template<typename ColorType> static String serialization(const ColorType& color)
 {
-    auto [c1, c2, c3, alpha] = color.components();
+    auto [c1, c2, c3, alpha] = color;
     if (WTF::areEssentiallyEqual(alpha, 1.0f))
-        return makeString("color(", serialization(color.colorSpace()), ' ', c1, ' ', c2, ' ', c3, ')');
-    return makeString("color(", serialization(color.colorSpace()), ' ', c1, ' ', c2, ' ', c3, " / ", alpha, ')');
+        return makeString("color(", serialization(color.colorSpace), ' ', c1, ' ', c2, ' ', c3, ')');
+    return makeString("color(", serialization(color.colorSpace), ' ', c1, ' ', c2, ' ', c3, " / ", alpha, ')');
 }
 
-String serializationForHTML(const ExtendedColor& color)
+// SRGBA<float> overloads
+
+String serializationForCSS(const SRGBA<float>& color)
 {
-    return serializationForCSS(color);
+    return serialization(color);
 }
 
-String serializationForRenderTreeAsText(const ExtendedColor& color)
+String serializationForHTML(const SRGBA<float>& color)
 {
-    return serializationForCSS(color);
+    return serialization(color);
 }
 
+String serializationForRenderTreeAsText(const SRGBA<float>& color)
+{
+    return serialization(color);
+}
+
+// LinearSRGBA<float> overloads
+
+String serializationForCSS(const LinearSRGBA<float>& color)
+{
+    return serialization(color);
+}
+
+String serializationForHTML(const LinearSRGBA<float>& color)
+{
+    return serialization(color);
+}
+
+String serializationForRenderTreeAsText(const LinearSRGBA<float>& color)
+{
+    return serialization(color);
+}
+
+// DisplayP3<float> overloads
+
+String serializationForCSS(const DisplayP3<float>& color)
+{
+    return serialization(color);
+}
+
+String serializationForHTML(const DisplayP3<float>& color)
+{
+    return serialization(color);
+}
+
+String serializationForRenderTreeAsText(const DisplayP3<float>& color)
+{
+    return serialization(color);
+}
+
+
 // Color overloads
 
 String serializationForCSS(const Color& color)
 {
-    if (color.isExtended())
-        return serializationForCSS(color.asExtended());
-    return serializationForCSS(color.asInline());
+    return color.callOnUnderlyingType([] (auto underlyingColor) {
+        return serializationForCSS(underlyingColor);
+    });
 }
 
 String serializationForHTML(const Color& color)
 {
-    if (color.isExtended())
-        return serializationForHTML(color.asExtended());
-    return serializationForHTML(color.asInline());
+    return color.callOnUnderlyingType([] (auto underlyingColor) {
+        return serializationForHTML(underlyingColor);
+    });
 }
 
 String serializationForRenderTreeAsText(const Color& color)
 {
-    if (color.isExtended())
-        return serializationForRenderTreeAsText(color.asExtended());
-    return serializationForRenderTreeAsText(color.asInline());
+    return color.callOnUnderlyingType([] (auto underlyingColor) {
+        return serializationForRenderTreeAsText(underlyingColor);
+    });
 }
 
 }

Modified: trunk/Source/WebCore/platform/graphics/ColorSerialization.h (264271 => 264272)


--- trunk/Source/WebCore/platform/graphics/ColorSerialization.h	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/platform/graphics/ColorSerialization.h	2020-07-12 01:01:25 UTC (rev 264272)
@@ -28,8 +28,9 @@
 namespace WebCore {
 
 class Color;
-class ExtendedColor;
 
+template<typename> struct DisplayP3;
+template<typename> struct LinearSRGBA;
 template<typename> struct SRGBA;
 
 // serializationForHTML returns the color serialized according to HTML5 <https://html.spec.whatwg.org/multipage/scripting.html#fill-and-stroke-styles> (10 September 2015)
@@ -40,10 +41,18 @@
 WEBCORE_EXPORT String serializationForHTML(SRGBA<uint8_t>);
 WEBCORE_EXPORT String serializationForRenderTreeAsText(SRGBA<uint8_t>);
 
-WEBCORE_EXPORT String serializationForCSS(const ExtendedColor&);
-WEBCORE_EXPORT String serializationForHTML(const ExtendedColor&);
-WEBCORE_EXPORT String serializationForRenderTreeAsText(const ExtendedColor&);
+WEBCORE_EXPORT String serializationForCSS(const SRGBA<float>&);
+WEBCORE_EXPORT String serializationForHTML(const SRGBA<float>&);
+WEBCORE_EXPORT String serializationForRenderTreeAsText(const SRGBA<float>&);
 
+WEBCORE_EXPORT String serializationForCSS(const LinearSRGBA<float>&);
+WEBCORE_EXPORT String serializationForHTML(const LinearSRGBA<float>&);
+WEBCORE_EXPORT String serializationForRenderTreeAsText(const LinearSRGBA<float>&);
+
+WEBCORE_EXPORT String serializationForCSS(const DisplayP3<float>&);
+WEBCORE_EXPORT String serializationForHTML(const DisplayP3<float>&);
+WEBCORE_EXPORT String serializationForRenderTreeAsText(const DisplayP3<float>&);
+
 WEBCORE_EXPORT String serializationForCSS(const Color&);
 WEBCORE_EXPORT String serializationForHTML(const Color&);
 WEBCORE_EXPORT String serializationForRenderTreeAsText(const Color&);

Modified: trunk/Source/WebCore/platform/graphics/ColorTypes.h (264271 => 264272)


--- trunk/Source/WebCore/platform/graphics/ColorTypes.h	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/platform/graphics/ColorTypes.h	2020-07-12 01:01:25 UTC (rev 264272)
@@ -26,14 +26,31 @@
 #pragma once
 
 #include "ColorComponents.h"
+#include "ColorSpace.h"
 
 namespace WebCore {
 
+template<typename> struct ComponentTraits;
+
+template<> struct ComponentTraits<uint8_t> {
+    static constexpr uint8_t minValue = 0;
+    static constexpr uint8_t maxValue = 255;
+};
+
+template<> struct ComponentTraits<float> {
+    static constexpr float minValue = 0.0f;
+    static constexpr float maxValue = 1.0f;
+};
+
+
 template<typename T> struct SRGBA {
     T red;
     T green;
     T blue;
     T alpha;
+
+    using ComponentType = T;
+    static constexpr auto colorSpace = ColorSpace::SRGB;
 };
 
 template<typename T> SRGBA(T, T, T, T) -> SRGBA<T>;
@@ -64,6 +81,9 @@
     T green;
     T blue;
     T alpha;
+
+    using ComponentType = T;
+    static constexpr auto colorSpace = ColorSpace::LinearRGB;
 };
 
 template<typename T> LinearSRGBA(T, T, T, T) -> LinearSRGBA<T>;
@@ -94,6 +114,9 @@
     T green;
     T blue;
     T alpha;
+
+    using ComponentType = T;
+    static constexpr auto colorSpace = ColorSpace::DisplayP3;
 };
 
 template<typename T> DisplayP3(T, T, T, T) -> DisplayP3<T>;
@@ -124,6 +147,8 @@
     T green;
     T blue;
     T alpha;
+
+    using ComponentType = T;
 };
 
 template<typename T> LinearDisplayP3(T, T, T, T) -> LinearDisplayP3<T>;
@@ -154,6 +179,8 @@
     T saturation;
     T lightness;
     T alpha;
+
+    using ComponentType = T;
 };
 
 template<typename T> HSLA(T, T, T, T) -> HSLA<T>;
@@ -186,6 +213,8 @@
     T yellow;
     T black;
     T alpha;
+
+    using ComponentType = T;
 };
 
 template<typename T> CMYKA(T, T, T, T, T) -> CMYKA<T>;
@@ -206,6 +235,8 @@
     T y;
     T z;
     T alpha;
+
+    using ComponentType = T;
 };
 
 template<typename T> XYZA(T, T, T, T) -> XYZA<T>;

Modified: trunk/Source/WebCore/platform/graphics/ColorUtilities.h (264271 => 264272)


--- trunk/Source/WebCore/platform/graphics/ColorUtilities.h	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/platform/graphics/ColorUtilities.h	2020-07-12 01:01:25 UTC (rev 264272)
@@ -69,6 +69,9 @@
 template<typename ColorType> constexpr ColorType invertedColorWithOverridenAlpha(const ColorType&, uint8_t overrideAlpha);
 template<typename ColorType> ColorType invertedColorWithOverridenAlpha(const ColorType&, float overrideAlpha);
 
+template<typename ColorType> constexpr bool isBlack(const ColorType&);
+template<typename ColorType> constexpr bool isWhite(const ColorType&);
+
 constexpr uint16_t fastMultiplyBy255(uint16_t);
 constexpr uint16_t fastDivideBy255(uint16_t);
 
@@ -192,6 +195,23 @@
     return copy;
 }
 
+template<typename ColorType> constexpr bool isBlack(const ColorType& color)
+{
+    constexpr auto min = ComponentTraits<typename ColorType::ComponentType>::minValue;
+    constexpr auto max = ComponentTraits<typename ColorType::ComponentType>::maxValue;
+
+    auto [c1, c2, c3, alpha] = color;
+    return c1 == min && c2 == min && c3 == min && alpha == max;
+}
+
+template<typename ColorType> constexpr bool isWhite(const ColorType& color)
+{
+    constexpr auto max = ComponentTraits<typename ColorType::ComponentType>::maxValue;
+
+    auto [c1, c2, c3, alpha] = color;
+    return c1 == max && c2 == max && c3 == max && alpha == max;
+}
+
 constexpr uint16_t fastMultiplyBy255(uint16_t value)
 {
     return (value << 8) - value;

Deleted: trunk/Source/WebCore/platform/graphics/ExtendedColor.cpp (264271 => 264272)


--- trunk/Source/WebCore/platform/graphics/ExtendedColor.cpp	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/platform/graphics/ExtendedColor.cpp	2020-07-12 01:01:25 UTC (rev 264272)
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ExtendedColor.h"
-
-#include "Color.h"
-#include "ColorConversion.h"
-#include "ColorTypes.h"
-#include <wtf/Hasher.h>
-#include <wtf/MathExtras.h>
-
-namespace WebCore {
-
-Ref<ExtendedColor> ExtendedColor::create(float c1, float c2, float c3, float alpha, ColorSpace colorSpace)
-{
-    return adoptRef(*new ExtendedColor(c1, c2, c3, alpha, colorSpace));
-}
-
-unsigned ExtendedColor::hash() const
-{
-    auto [c1, c2, c3, alpha] = components();
-    return computeHash(c1, c2, c3, alpha, m_colorSpace);
-}
-
-Ref<ExtendedColor> ExtendedColor::colorWithAlpha(float overrideAlpha) const
-{
-    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] = components();
-    return ExtendedColor::create(1.0f - c1, 1.0f - c2, 1.0f - c3, overrideAlpha, colorSpace());
-}
-
-SRGBA<float> ExtendedColor::toSRGBAFloatComponentsLossy() const
-{
-    switch (m_colorSpace) {
-    case ColorSpace::SRGB:
-        return asSRGBA(m_components);
-    case ColorSpace::LinearRGB:
-        return toSRGBA(asLinearSRGBA(m_components));
-    case ColorSpace::DisplayP3:
-        return toSRGBA(asDisplayP3(m_components));
-    }
-    ASSERT_NOT_REACHED();
-    return { 0, 0, 0, 0 };
-}
-
-bool ExtendedColor::isWhite() const
-{
-    auto [c1, c2, c3, alpha] = components();
-    return c1 == 1 && c2 == 1 && c3 == 1 && alpha == 1;
-}
-
-bool ExtendedColor::isBlack() const
-{
-    auto [c1, c2, c3, alpha] = components();
-    return !c1 && !c2 && !c3 && alpha == 1;
-}
-
-Color makeExtendedColor(float c1, float c2, float c3, float alpha, ColorSpace colorSpace)
-{
-    return ExtendedColor::create(c1, c2, c3, alpha, colorSpace);
-}
-
-}

Modified: trunk/Source/WebCore/platform/graphics/ExtendedColor.h (264271 => 264272)


--- trunk/Source/WebCore/platform/graphics/ExtendedColor.h	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/platform/graphics/ExtendedColor.h	2020-07-12 01:01:25 UTC (rev 264272)
@@ -26,52 +26,29 @@
 #pragma once
 
 #include "ColorComponents.h"
+#include "ColorConversion.h"
 #include "ColorSpace.h"
 #include "ColorTypes.h"
-#include "ColorUtilities.h"
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
 
 namespace WebCore {
 
-class Color;
-template<typename> struct SRGBA;
-
 class ExtendedColor : public RefCounted<ExtendedColor> {
 public:
-    WEBCORE_EXPORT static Ref<ExtendedColor> create(float c1, float c2, float c3, float alpha, ColorSpace);
-
+    template<typename ColorType> static Ref<ExtendedColor> create(const ColorType&);
+    static Ref<ExtendedColor> create(ColorComponents<float>, ColorSpace);
+    
     float alpha() const { return m_components[3]; }
 
     const ColorComponents<float>& components() const { return m_components; }
     ColorSpace colorSpace() const { return m_colorSpace; }
 
-    WEBCORE_EXPORT unsigned hash() const;
+    template<typename Functor> decltype(auto) callOnUnderlyingType(Functor&&) const;
 
-    Ref<ExtendedColor> colorWithAlpha(float) const;
-    Ref<ExtendedColor> invertedColorWithAlpha(float) const;
-
-    bool isWhite() const;
-    bool isBlack() const;
-
-    // This will convert non-sRGB colorspace colors into sRGB.
-    template<typename T> constexpr SRGBA<T> toSRGBALossy() const
-    {
-        if constexpr (std::is_same_v<T, float>)
-            return toSRGBAFloatComponentsLossy();
-        else if constexpr (std::is_same_v<T, uint8_t>)
-            return convertToComponentBytes(toSRGBAFloatComponentsLossy());
-    }
-
 private:
-    ExtendedColor(float c1, float c2, float c3, float alpha, ColorSpace colorSpace)
-        : m_components(c1, c2, c3, alpha)
-        , m_colorSpace(colorSpace)
-    {
-    }
+    ExtendedColor(ColorComponents<float>, ColorSpace);
 
-    WEBCORE_EXPORT SRGBA<float> toSRGBAFloatComponentsLossy() const;
-
     ColorComponents<float> m_components;
     ColorSpace m_colorSpace;
 };
@@ -86,8 +63,35 @@
     return !(a == b);
 }
 
-// FIXME: If the ColorSpace is sRGB and the values can all be
-// converted exactly to integers, we should make a SimpleColor.
-WEBCORE_EXPORT Color makeExtendedColor(float c1, float c2, float c3, float alpha, ColorSpace);
+template<typename ColorType> inline Ref<ExtendedColor> ExtendedColor::create(const ColorType& color)
+{
+    return adoptRef(*new ExtendedColor(asColorComponents(color), color.colorSpace));
+}
 
+inline Ref<ExtendedColor> ExtendedColor::create(ColorComponents<float> components, ColorSpace colorSpace)
+{
+    return adoptRef(*new ExtendedColor(components, colorSpace));
 }
+
+inline ExtendedColor::ExtendedColor(ColorComponents<float> components, ColorSpace colorSpace)
+    : m_components(components)
+    , m_colorSpace(colorSpace)
+{
+}
+
+template<typename Functor> decltype(auto) ExtendedColor::callOnUnderlyingType(Functor&& functor) const
+{
+    switch (m_colorSpace) {
+    case ColorSpace::SRGB:
+        return std::invoke(std::forward<Functor>(functor), asSRGBA(m_components));
+    case ColorSpace::LinearRGB:
+        return std::invoke(std::forward<Functor>(functor), asLinearSRGBA(m_components));
+    case ColorSpace::DisplayP3:
+        return std::invoke(std::forward<Functor>(functor), asDisplayP3(m_components));
+    }
+
+    ASSERT_NOT_REACHED();
+    return std::invoke(std::forward<Functor>(functor), asSRGBA(m_components));
+}
+
+}

Modified: trunk/Source/WebCore/platform/graphics/gtk/ColorGtk.cpp (264271 => 264272)


--- trunk/Source/WebCore/platform/graphics/gtk/ColorGtk.cpp	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/platform/graphics/gtk/ColorGtk.cpp	2020-07-12 01:01:25 UTC (rev 264272)
@@ -26,8 +26,8 @@
 namespace WebCore {
 
 Color::Color(const GdkRGBA& color)
+    : Color(convertToComponentBytes(SRGBA { static_cast<float>(color.red), static_cast<float>(color.green), static_cast<float>(color.blue), static_cast<float>(color.alpha) }))
 {
-    setInlineColor(convertToComponentBytes(SRGBA { static_cast<float>(color.red), static_cast<float>(color.green), static_cast<float>(color.blue), static_cast<float>(color.alpha) }));
 }
 
 Color::operator GdkRGBA() const

Modified: trunk/Source/WebCore/platform/graphics/win/ColorDirect2D.cpp (264271 => 264272)


--- trunk/Source/WebCore/platform/graphics/win/ColorDirect2D.cpp	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Source/WebCore/platform/graphics/win/ColorDirect2D.cpp	2020-07-12 01:01:25 UTC (rev 264272)
@@ -34,8 +34,8 @@
 namespace WebCore {
 
 Color::Color(D2D1_COLOR_F color)
+    : Color(convertToComponentBytes(SRGBA { color.r, color.g, color.b, color.a }))
 {
-    setInlineColor(convertToComponentBytes(SRGBA { color.r, color.g, color.b, color.a }));
 }
 
 Color::operator D2D1_COLOR_F() const

Modified: trunk/Tools/ChangeLog (264271 => 264272)


--- trunk/Tools/ChangeLog	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Tools/ChangeLog	2020-07-12 01:01:25 UTC (rev 264272)
@@ -1,5 +1,17 @@
 2020-07-11  Sam Weinig  <[email protected]>
 
+        Reduce surface area of the ExtendedColor class to a bare minimum
+        https://bugs.webkit.org/show_bug.cgi?id=214204
+
+        Reviewed by Darin Adler.
+
+        * TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp:
+        (TestWebKitAPI::TEST):
+        (TestWebKitAPI::makeColor):
+        Update using new Color constructor for extended colors.
+
+2020-07-11  Sam Weinig  <[email protected]>
+
         Make hasher work with tuple-like classes
         https://bugs.webkit.org/show_bug.cgi?id=214224
 

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp (264271 => 264272)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp	2020-07-11 22:38:45 UTC (rev 264271)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ExtendedColorTests.cpp	2020-07-12 01:01:25 UTC (rev 264272)
@@ -37,7 +37,7 @@
 
 TEST(ExtendedColor, Constructor)
 {
-    Color c1 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3) };
+    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     EXPECT_TRUE(c1.isExtended());
 
     auto [r, g, b, alpha] = c1.asExtended().components();
@@ -52,7 +52,7 @@
 
 TEST(ExtendedColor, CopyConstructor)
 {
-    Color c1 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3) };
+    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     EXPECT_TRUE(c1.isExtended());
 
     Color c2(c1);
@@ -70,7 +70,7 @@
 
 TEST(ExtendedColor, Assignment)
 {
-    Color c1 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3) };
+    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     EXPECT_TRUE(c1.isExtended());
 
     Color c2 = c1;
@@ -89,10 +89,10 @@
 TEST(ExtendedColor, Equality)
 {
     {
-        Color c1 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3) };
+        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
         EXPECT_TRUE(c1.isExtended());
 
-        Color c2 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3) };
+        Color c2 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
         EXPECT_TRUE(c1.isExtended());
 
         EXPECT_EQ(c1, c2);
@@ -99,10 +99,10 @@
     }
 
     {
-        Color c1 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3) };
+        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
         EXPECT_TRUE(c1.isExtended());
 
-        Color c2 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::SRGB) };
+        Color c2 { SRGBA<float> { 1.0, 0.5, 0.25, 1.0 } };
         EXPECT_TRUE(c1.isExtended());
 
         EXPECT_NE(c1, c2);
@@ -112,7 +112,7 @@
     int g = 128;
     int b = 63;
     int a = 127;
-    Color rgb1 { makeExtendedColor(r / 255.0, g / 255.0, b / 255.0, a / 255.0, ColorSpace::SRGB) };
+    Color rgb1 { SRGBA<float> { r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f } };
     Color rgb2 = makeSimpleColor(r, g, b, a);
     EXPECT_NE(rgb1, rgb2);
     EXPECT_NE(rgb2, rgb1);
@@ -121,10 +121,10 @@
 TEST(ExtendedColor, Hash)
 {
     {
-        Color c1 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3) };
+        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
         EXPECT_TRUE(c1.isExtended());
 
-        Color c2 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3) };
+        Color c2 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
         EXPECT_TRUE(c1.isExtended());
 
         EXPECT_EQ(c1.hash(), c2.hash());
@@ -131,10 +131,10 @@
     }
 
     {
-        Color c1 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3) };
+        Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
         EXPECT_TRUE(c1.isExtended());
 
-        Color c2 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::SRGB) };
+        Color c2 { SRGBA<float> { 1.0, 0.5, 0.25, 1.0 } };
         EXPECT_TRUE(c1.isExtended());
 
         EXPECT_NE(c1.hash(), c2.hash());
@@ -144,7 +144,7 @@
     int g = 128;
     int b = 63;
     int a = 127;
-    Color rgb1 { makeExtendedColor(r / 255.0, g / 255.0, b / 255.0, a / 255.0, ColorSpace::SRGB) };
+    Color rgb1 { SRGBA<float> { r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f } };
     Color rgb2 = makeSimpleColor(r, g, b, a);
     EXPECT_NE(rgb1.hash(), rgb2.hash());
 }
@@ -151,7 +151,7 @@
 
 TEST(ExtendedColor, MoveConstructor)
 {
-    Color c1 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3) };
+    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     EXPECT_TRUE(c1.isExtended());
 
     Color c2(WTFMove(c1));
@@ -172,7 +172,7 @@
 
 TEST(ExtendedColor, MoveAssignment)
 {
-    Color c1 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3) };
+    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     EXPECT_TRUE(c1.isExtended());
 
     Color c2 = WTFMove(c1);
@@ -194,7 +194,8 @@
 
 TEST(ExtendedColor, BasicReferenceCounting)
 {
-    Color* c1 = new Color { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3) };
+    Color* c1 = new Color { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
+    
     EXPECT_TRUE(c1->isExtended());
 
     Color* c2 = new Color(*c1);
@@ -220,7 +221,7 @@
 
 Color makeColor()
 {
-    Color c1 { makeExtendedColor(1.0, 0.5, 0.25, 1.0, ColorSpace::DisplayP3) };
+    Color c1 { DisplayP3<float> { 1.0, 0.5, 0.25, 1.0 } };
     EXPECT_TRUE(c1.isExtended());
     EXPECT_EQ(1u, c1.asExtended().refCount());
 
@@ -238,7 +239,7 @@
 
 TEST(ExtendedColor, P3ConversionToSRGB)
 {
-    Color p3Color { makeExtendedColor(1.0, 0.5, 0.25, 0.75, ColorSpace::DisplayP3) };
+    Color p3Color { DisplayP3<float> { 1.0, 0.5, 0.25, 0.75 } };
     EXPECT_TRUE(p3Color.isExtended());
 
     auto sRGBAColor = p3Color.toSRGBALossy<float>();
@@ -250,9 +251,10 @@
 
 TEST(ExtendedColor, LinearSRGBConversionToSRGB)
 {
-    Color linearColor { makeExtendedColor(1.0, 0.5, 0.25, 0.75, ColorSpace::LinearRGB) };
-    EXPECT_TRUE(linearColor.isExtended());
-    auto sRGBAColor = linearColor.toSRGBALossy<float>();
+    Color linearSRGBAColor { LinearSRGBA<float> { 1.0, 0.5, 0.25, 0.75 } };
+    EXPECT_TRUE(linearSRGBAColor.isExtended());
+
+    auto sRGBAColor = linearSRGBAColor.toSRGBALossy<float>();
     EXPECT_TRUE(WTF::areEssentiallyEqual(sRGBAColor.red, 1.0f));
     EXPECT_TRUE(WTF::areEssentiallyEqual(sRGBAColor.green, 0.735356927f));
     EXPECT_TRUE(WTF::areEssentiallyEqual(sRGBAColor.blue, 0.537098706f));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to