Diff
Modified: trunk/LayoutTests/ChangeLog (273210 => 273211)
--- trunk/LayoutTests/ChangeLog 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/LayoutTests/ChangeLog 2021-02-21 00:47:59 UTC (rev 273211)
@@ -1,3 +1,14 @@
+2021-02-20 Sam Weinig <wei...@apple.com>
+
+ color(lab ...) should serialize as color(lab ...) not lab() according to latest CSS Color 4 spec
+ https://bugs.webkit.org/show_bug.cgi?id=222110
+
+ Reviewed by Dean Jackson.
+
+ * fast/css/parsing-lab-colors-expected.txt:
+ * fast/css/parsing-lab-colors.html:
+ Update test and results for new serialization of color(lab ...).
+
2021-02-20 Jiewen Tan <jiewen_...@apple.com>
PCM: Store and report source unlinkable tokens
Modified: trunk/LayoutTests/fast/css/parsing-lab-colors-expected.txt (273210 => 273211)
--- trunk/LayoutTests/fast/css/parsing-lab-colors-expected.txt 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/LayoutTests/fast/css/parsing-lab-colors-expected.txt 2021-02-21 00:47:59 UTC (rev 273211)
@@ -1,4 +1,4 @@
-Test the parsing of lab, lch and gray colors.
+Test the parsing of lab(...), lch(...) and color(lab ...) colors.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -40,26 +40,26 @@
PASS computedStyle("background-color", "lch(10% 20 -700)") is "lch(10% 20 20)"
color(lab )
-PASS computedStyle("background-color", "color(lab 0% 0 0)") is "lab(0% 0 0)"
-PASS computedStyle("background-color", "color(lab 0% 0 0 / 1)") is "lab(0% 0 0)"
-PASS computedStyle("background-color", "color(lab 0% 0 0 / 0.5)") is "lab(0% 0 0 / 0.5)"
-PASS computedStyle("background-color", "color(lab 20% 0 10/0.5)") is "lab(20% 0 10 / 0.5)"
-PASS computedStyle("background-color", "color(lab 20% 0 10/50%)") is "lab(20% 0 10 / 0.5)"
-PASS computedStyle("background-color", "color(lab 400% 0 10/50%)") is "lab(400% 0 10 / 0.5)"
-PASS computedStyle("background-color", "color(lab 50% -160 160)") is "lab(50% -160 160)"
-PASS computedStyle("background-color", "color(lab 50% -200 200)") is "lab(50% -200 200)"
-PASS computedStyle("background-color", "color(lab 0% 0 0 / -10%)") is "lab(0% 0 0 / 0)"
-PASS computedStyle("background-color", "color(lab 0% 0 0 / 110%)") is "lab(0% 0 0)"
-PASS computedStyle("background-color", "color(lab 0% 0 0 / 300%)") is "lab(0% 0 0)"
-PASS computedStyle("background-color", "color(lab 50% -200)") is "lab(50% -200 0)"
-PASS computedStyle("background-color", "color(lab 50%)") is "lab(50% 0 0)"
-PASS computedStyle("background-color", "color(lab)") is "lab(0% 0 0)"
-PASS computedStyle("background-color", "color(lab 50% -200 / 0.5)") is "lab(50% -200 0 / 0.5)"
-PASS computedStyle("background-color", "color(lab 50% / 0.5)") is "lab(50% 0 0 / 0.5)"
-PASS computedStyle("background-color", "color(lab / 0.5)") is "lab(0% 0 0 / 0.5)"
-PASS computedStyle("background-color", "color(lab -40% 0 0)") is "lab(0% 0 0)"
-PASS computedStyle("background-color", "color(lab 50% -20 0)") is "lab(50% -20 0)"
-PASS computedStyle("background-color", "color(lab 50% 0 -20)") is "lab(50% 0 -20)"
+PASS computedStyle("background-color", "color(lab 0% 0 0)") is "color(lab 0% 0 0)"
+PASS computedStyle("background-color", "color(lab 0% 0 0 / 1)") is "color(lab 0% 0 0)"
+PASS computedStyle("background-color", "color(lab 0% 0 0 / 0.5)") is "color(lab 0% 0 0 / 0.5)"
+PASS computedStyle("background-color", "color(lab 20% 0 10/0.5)") is "color(lab 20% 0 10 / 0.5)"
+PASS computedStyle("background-color", "color(lab 20% 0 10/50%)") is "color(lab 20% 0 10 / 0.5)"
+PASS computedStyle("background-color", "color(lab 400% 0 10/50%)") is "color(lab 400% 0 10 / 0.5)"
+PASS computedStyle("background-color", "color(lab 50% -160 160)") is "color(lab 50% -160 160)"
+PASS computedStyle("background-color", "color(lab 50% -200 200)") is "color(lab 50% -200 200)"
+PASS computedStyle("background-color", "color(lab 0% 0 0 / -10%)") is "color(lab 0% 0 0 / 0)"
+PASS computedStyle("background-color", "color(lab 0% 0 0 / 110%)") is "color(lab 0% 0 0)"
+PASS computedStyle("background-color", "color(lab 0% 0 0 / 300%)") is "color(lab 0% 0 0)"
+PASS computedStyle("background-color", "color(lab 50% -200)") is "color(lab 50% -200 0)"
+PASS computedStyle("background-color", "color(lab 50%)") is "color(lab 50% 0 0)"
+PASS computedStyle("background-color", "color(lab)") is "color(lab 0% 0 0)"
+PASS computedStyle("background-color", "color(lab 50% -200 / 0.5)") is "color(lab 50% -200 0 / 0.5)"
+PASS computedStyle("background-color", "color(lab 50% / 0.5)") is "color(lab 50% 0 0 / 0.5)"
+PASS computedStyle("background-color", "color(lab / 0.5)") is "color(lab 0% 0 0 / 0.5)"
+PASS computedStyle("background-color", "color(lab -40% 0 0)") is "color(lab 0% 0 0)"
+PASS computedStyle("background-color", "color(lab 50% -20 0)") is "color(lab 50% -20 0)"
+PASS computedStyle("background-color", "color(lab 50% 0 -20)") is "color(lab 50% 0 -20)"
Test invalid values
PASS computedStyle("background-color", "lab(0 0 0)") is "rgba(0, 0, 0, 0)"
Modified: trunk/LayoutTests/fast/css/parsing-lab-colors.html (273210 => 273211)
--- trunk/LayoutTests/fast/css/parsing-lab-colors.html 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/LayoutTests/fast/css/parsing-lab-colors.html 2021-02-21 00:47:59 UTC (rev 273211)
@@ -3,7 +3,7 @@
</head>
<body>
<script>
- description("Test the parsing of lab, lch and gray colors.");
+ description("Test the parsing of lab(...), lch(...) and color(lab ...) colors.");
function computedStyle(property, value)
{
@@ -74,26 +74,26 @@
debug('');
debug('color(lab )');
- testComputed("background-color", "color(lab 0% 0 0)", "lab(0% 0 0)");
- testComputed("background-color", "color(lab 0% 0 0 / 1)", "lab(0% 0 0)");
- testComputed("background-color", "color(lab 0% 0 0 / 0.5)", "lab(0% 0 0 / 0.5)");
- testComputed("background-color", "color(lab 20% 0 10/0.5)", "lab(20% 0 10 / 0.5)");
- testComputed("background-color", "color(lab 20% 0 10/50%)", "lab(20% 0 10 / 0.5)");
- testComputed("background-color", "color(lab 400% 0 10/50%)", "lab(400% 0 10 / 0.5)");
- testComputed("background-color", "color(lab 50% -160 160)", "lab(50% -160 160)");
- testComputed("background-color", "color(lab 50% -200 200)", "lab(50% -200 200)");
- testComputed("background-color", "color(lab 0% 0 0 / -10%)", "lab(0% 0 0 / 0)");
- testComputed("background-color", "color(lab 0% 0 0 / 110%)", "lab(0% 0 0)");
- testComputed("background-color", "color(lab 0% 0 0 / 300%)", "lab(0% 0 0)");
- testComputed("background-color", "color(lab 50% -200)", "lab(50% -200 0)");
- testComputed("background-color", "color(lab 50%)", "lab(50% 0 0)");
- testComputed("background-color", "color(lab)", "lab(0% 0 0)");
- testComputed("background-color", "color(lab 50% -200 / 0.5)", "lab(50% -200 0 / 0.5)");
- testComputed("background-color", "color(lab 50% / 0.5)", "lab(50% 0 0 / 0.5)");
- testComputed("background-color", "color(lab / 0.5)", "lab(0% 0 0 / 0.5)");
- testComputed("background-color", "color(lab -40% 0 0)", "lab(0% 0 0)");
- testComputed("background-color", "color(lab 50% -20 0)", "lab(50% -20 0)");
- testComputed("background-color", "color(lab 50% 0 -20)", "lab(50% 0 -20)");
+ testComputed("background-color", "color(lab 0% 0 0)", "color(lab 0% 0 0)");
+ testComputed("background-color", "color(lab 0% 0 0 / 1)", "color(lab 0% 0 0)");
+ testComputed("background-color", "color(lab 0% 0 0 / 0.5)", "color(lab 0% 0 0 / 0.5)");
+ testComputed("background-color", "color(lab 20% 0 10/0.5)", "color(lab 20% 0 10 / 0.5)");
+ testComputed("background-color", "color(lab 20% 0 10/50%)", "color(lab 20% 0 10 / 0.5)");
+ testComputed("background-color", "color(lab 400% 0 10/50%)", "color(lab 400% 0 10 / 0.5)");
+ testComputed("background-color", "color(lab 50% -160 160)", "color(lab 50% -160 160)");
+ testComputed("background-color", "color(lab 50% -200 200)", "color(lab 50% -200 200)");
+ testComputed("background-color", "color(lab 0% 0 0 / -10%)", "color(lab 0% 0 0 / 0)");
+ testComputed("background-color", "color(lab 0% 0 0 / 110%)", "color(lab 0% 0 0)");
+ testComputed("background-color", "color(lab 0% 0 0 / 300%)", "color(lab 0% 0 0)");
+ testComputed("background-color", "color(lab 50% -200)", "color(lab 50% -200 0)");
+ testComputed("background-color", "color(lab 50%)", "color(lab 50% 0 0)");
+ testComputed("background-color", "color(lab)", "color(lab 0% 0 0)");
+ testComputed("background-color", "color(lab 50% -200 / 0.5)", "color(lab 50% -200 0 / 0.5)");
+ testComputed("background-color", "color(lab 50% / 0.5)", "color(lab 50% 0 0 / 0.5)");
+ testComputed("background-color", "color(lab / 0.5)", "color(lab 0% 0 0 / 0.5)");
+ testComputed("background-color", "color(lab -40% 0 0)", "color(lab 0% 0 0)");
+ testComputed("background-color", "color(lab 50% -20 0)", "color(lab 50% -20 0)");
+ testComputed("background-color", "color(lab 50% 0 -20)", "color(lab 50% 0 -20)");
debug('');
debug('Test invalid values');
Modified: trunk/Source/WebCore/ChangeLog (273210 => 273211)
--- trunk/Source/WebCore/ChangeLog 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/Source/WebCore/ChangeLog 2021-02-21 00:47:59 UTC (rev 273211)
@@ -1,3 +1,95 @@
+2021-02-20 Sam Weinig <wei...@apple.com>
+
+ color(lab ...) should serialize as color(lab ...) not lab() according to latest CSS Color 4 spec
+ https://bugs.webkit.org/show_bug.cgi?id=222110
+
+ Reviewed by Dean Jackson.
+
+ To make this work it was necessary to make it so that extended colors, like Lab,
+ could store an extra bit of data on Color to indicate that it should use the
+ color() function for serialization when parsed using the color() form.
+
+ To do that, Color was reworked to allow extra metadata flags for both inline and
+ extended colors. Previously, only inline colors could make use of the extra bits.
+ Now, we take advantage of the fact that we have the high 16 bits available to us
+ for pointers to also store that metadata for extended colors. Rather than using a
+ union, we encode the pointer / inline color into a uint64_t, and use the extra bits
+ for the flags we need. Currently we only use 6, so there is quite a bit more that
+ could be used here.
+
+ Finally, the color serialization code has been updated to check for the new bit,
+ called UseColorFunctionSerialization, and to serialize using color() notation
+ if it is set.
+
+ We are currently only taking advantage of this for differentiating between lab(...)
+ and color(lab ...), but in the future we should be able to also optimize color(srgb ...)
+ values that can be represented fully by SRGBA<uint8_t>.
+
+ Since we can now add flags for extended colors, the semantic bit is also now usable
+ for extended colors, though none currently exist.
+
+ * css/parser/CSSPropertyParserHelpers.cpp:
+ (WebCore::CSSPropertyParserHelpers::parseColorFunctionForRGBTypes):
+ (WebCore::CSSPropertyParserHelpers::parseColorFunctionForLabParameters):
+ (WebCore::CSSPropertyParserHelpers::parseColorFunctionForXYZParameters):
+ (WebCore::CSSPropertyParserHelpers::parseColorFunctionParameters):
+ * platform/graphics/Color.cpp:
+ (WebCore::Color::Color):
+ (WebCore::Color::operator=):
+ (WebCore::Color::colorWithAlpha const):
+ (WebCore::Color::semanticColor const):
+ * platform/graphics/Color.h:
+ (WebCore::Color::isHashTableDeletedValue const):
+ (WebCore::Color::Color):
+ (WebCore::Color::toAllFlags):
+ (WebCore::Color::setColor):
+ (WebCore::Color::setExtendedColor):
+ (WebCore::operator==):
+ (WebCore::extendedColorsEqual):
+ (WebCore::extendedColorsEqualIgnoringSemanticColor):
+ (WebCore::equalIgnoringSemanticColor):
+ (WebCore::Color::~Color):
+ (WebCore::Color::hash const):
+ (WebCore::Color::isValid const):
+ (WebCore::Color::isSemantic const):
+ (WebCore::Color::usesColorFunctionSerialization const):
+ (WebCore::Color::flags const):
+ (WebCore::Color::isExtended const):
+ (WebCore::Color::isInline const):
+ (WebCore::Color::asExtended const):
+ (WebCore::Color::asExtendedRef const):
+ (WebCore::Color::asInline const):
+ (WebCore::Color::asPackedInline const):
+ (WebCore::Color::encodedFlags):
+ (WebCore::Color::encodedInlineColor):
+ (WebCore::Color::encodedPackedInlineColor):
+ (WebCore::Color::encodedExtendedColor):
+ (WebCore::Color::decodedFlags):
+ (WebCore::Color::decodedInlineColor):
+ (WebCore::Color::decodedPackedInlineColor):
+ (WebCore::Color::decodedExtendedColor):
+ (WebCore::Color::setInvalid):
+ (WebCore::Color::encode const):
+ (WebCore::Color::decode):
+ (WebCore::Color::tagAsSemantic): Deleted.
+ (WebCore::Color::tagAsValid): Deleted.
+ * platform/graphics/ColorBlending.cpp:
+ (WebCore::blendWithWhite):
+ * platform/graphics/ColorSerialization.cpp:
+ (WebCore::serializationForCSS):
+ (WebCore::serializationForHTML):
+ (WebCore::serializationForRenderTreeAsText):
+ (WebCore::serializationUsingColorFunction):
+ * platform/graphics/cg/ColorCG.cpp:
+ (WebCore::Color::Color):
+ * platform/graphics/mac/ColorMac.mm:
+ (WebCore::semanticColorFromNSColor):
+ * rendering/RenderThemeIOS.mm:
+ (WebCore::systemColorFromCSSValueIDSelector):
+ (WebCore::systemColorFromCSSValueID):
+ * rendering/RenderThemeMac.mm:
+ (WebCore::RenderThemeMac::systemColor const):
+
2021-02-20 Simon Fraser <simon.fra...@apple.com>
Fix the build when TREE_DEBUGGING is enabled in release builds
Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (273210 => 273211)
--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp 2021-02-21 00:47:59 UTC (rev 273211)
@@ -1371,7 +1371,7 @@
if (!alpha)
return { };
- return ColorType { clampTo<float>(channels[0], 0.0, 1.0), clampTo<float>(channels[1], 0.0, 1.0), clampTo<float>(channels[2], 0.0, 1.0), static_cast<float>(*alpha) };
+ return { ColorType { clampTo<float>(channels[0], 0.0, 1.0), clampTo<float>(channels[1], 0.0, 1.0), clampTo<float>(channels[2], 0.0, 1.0), static_cast<float>(*alpha) }, Color::Flags::UseColorFunctionSerialization };
}
static Color parseColorFunctionForLabParameters(CSSParserTokenRange& args)
@@ -1403,7 +1403,7 @@
auto normalizedLightness = std::max(0.0, channels[0]);
- return Lab<float> { static_cast<float>(normalizedLightness), static_cast<float>(channels[1]), static_cast<float>(channels[2]), static_cast<float>(*alpha) };
+ return { Lab<float> { static_cast<float>(normalizedLightness), static_cast<float>(channels[1]), static_cast<float>(channels[2]), static_cast<float>(*alpha) }, Color::Flags::UseColorFunctionSerialization };
}
static Color parseColorFunctionForXYZParameters(CSSParserTokenRange& args)
@@ -1433,7 +1433,7 @@
if (!alpha)
return { };
- return XYZA<float, WhitePoint::D50> { static_cast<float>(channels[0]), static_cast<float>(channels[1]), static_cast<float>(channels[2]), static_cast<float>(*alpha) };
+ return { XYZA<float, WhitePoint::D50> { static_cast<float>(channels[0]), static_cast<float>(channels[1]), static_cast<float>(channels[2]), static_cast<float>(*alpha) }, Color::Flags::UseColorFunctionSerialization };
}
static Color parseColorFunctionParameters(CSSParserTokenRange& range)
@@ -1476,6 +1476,7 @@
if (!args.atEnd())
return { };
+ ASSERT(color.usesColorFunctionSerialization());
return color;
}
Modified: trunk/Source/WebCore/platform/graphics/Color.cpp (273210 => 273211)
--- trunk/Source/WebCore/platform/graphics/Color.cpp 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/Source/WebCore/platform/graphics/Color.cpp 2021-02-21 00:47:59 UTC (rev 273211)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2003-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,10 +37,10 @@
static constexpr auto darkenedWhite = SRGBA<uint8_t> { 171, 171, 171 };
Color::Color(const Color& other)
- : m_colorData(other.m_colorData)
+ : m_colorAndFlags(other.m_colorAndFlags)
{
if (isExtended())
- m_colorData.extendedColor->ref();
+ asExtended().ref();
}
Color::Color(Color&& other)
@@ -54,12 +54,13 @@
return *this;
if (isExtended())
- m_colorData.extendedColor->deref();
+ asExtended().deref();
- m_colorData = other.m_colorData;
+ m_colorAndFlags = other.m_colorAndFlags;
if (isExtended())
- m_colorData.extendedColor->ref();
+ asExtended().ref();
+
return *this;
}
@@ -69,10 +70,10 @@
return *this;
if (isExtended())
- m_colorData.extendedColor->deref();
+ asExtended().deref();
- m_colorData = other.m_colorData;
- other.m_colorData.inlineColorAndFlags = invalidInlineColor;
+ m_colorAndFlags = other.m_colorAndFlags;
+ other.m_colorAndFlags = invalidColorAndFlags;
return *this;
}
@@ -123,19 +124,15 @@
Color Color::colorWithAlpha(float alpha) const
{
- return callOnUnderlyingType(WTF::makeVisitor(
- [&] (const SRGBA<uint8_t>& underlyingColor) -> Color {
- Color result = colorWithOverridenAlpha(underlyingColor, alpha);
+ return callOnUnderlyingType([&] (const auto& underlyingColor) -> Color {
+ auto result = colorWithOverriddenAlpha(underlyingColor, alpha);
- // 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);
- }
- ));
+ // FIXME: Why is preserving the semantic bit desired and/or correct here?
+ if (isSemantic())
+ return { result, Flags::Semantic };
+
+ return { result };
+ });
}
Color Color::invertedColorWithAlpha(float alpha) const
@@ -147,9 +144,9 @@
// better for non-invertible color types like Lab or consider removing this in favor
// of alternatives.
if constexpr (ColorType::Model::isInvertible)
- return invertedColorWithOverridenAlpha(underlyingColor, alpha);
+ return invertedcolorWithOverriddenAlpha(underlyingColor, alpha);
else
- return invertedColorWithOverridenAlpha(convertColor<SRGBA<float>>(underlyingColor), alpha);
+ return invertedcolorWithOverriddenAlpha(convertColor<SRGBA<float>>(underlyingColor), alpha);
});
}
@@ -157,8 +154,10 @@
{
if (isSemantic())
return *this;
-
- return { toSRGBALossy<uint8_t>(), Semantic };
+
+ if (isExtended())
+ return { asExtendedRef(), Flags::Semantic };
+ return { asInline(), Flags::Semantic };
}
std::pair<ColorSpace, ColorComponents<float>> Color::colorSpaceAndComponents() const
Modified: trunk/Source/WebCore/platform/graphics/Color.h (273210 => 273211)
--- trunk/Source/WebCore/platform/graphics/Color.h 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/Source/WebCore/platform/graphics/Color.h 2021-02-21 00:47:59 UTC (rev 273211)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2003-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,7 +31,9 @@
#include <wtf/Forward.h>
#include <wtf/HashFunctions.h>
#include <wtf/Hasher.h>
+#include <wtf/OptionSet.h>
#include <wtf/Optional.h>
+#include <wtf/StdLibExtras.h>
#if USE(CG)
typedef struct CGColor* CGColorRef;
@@ -56,32 +58,27 @@
// - Special "invalid color" state, treated as transparent black but distinguishable
// - 4x 8-bit (0-255) sRGBA, stored inline, no allocation
// - 4x float color components + color space, 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:
+ enum class Flags {
+ Semantic = 1 << 0,
+ UseColorFunctionSerialization = 1 << 1,
+ };
+
Color() = default;
- Color(SRGBA<uint8_t>);
- Color(Optional<SRGBA<uint8_t>>);
+ Color(SRGBA<uint8_t>, OptionSet<Flags> = { });
+ Color(Optional<SRGBA<uint8_t>>, OptionSet<Flags> = { });
- enum SemanticTag { Semantic };
- Color(SRGBA<uint8_t>, SemanticTag);
- Color(Optional<SRGBA<uint8_t>>, SemanticTag);
-
- Color(ColorComponents<float>, ColorSpace);
-
+ Color(ColorComponents<float>, ColorSpace, OptionSet<Flags> = { });
template<typename ColorType, typename std::enable_if_t<IsColorTypeWithComponentType<ColorType, float>>* = nullptr>
- Color(const ColorType&);
+ Color(const ColorType&, OptionSet<Flags> = { });
explicit Color(WTF::HashTableEmptyValueType);
explicit Color(WTF::HashTableDeletedValueType);
- bool isHashTableDeletedValue() const { return m_colorData.inlineColorAndFlags == deletedHashValue; }
+ bool isHashTableDeletedValue() const;
WEBCORE_EXPORT Color(const Color&);
WEBCORE_EXPORT Color(Color&&);
@@ -93,8 +90,9 @@
unsigned hash() const;
- bool isValid() const { return isExtended() || (m_colorData.inlineColorAndFlags & validInlineColorBit); }
- bool isSemantic() const { return isInline() && (m_colorData.inlineColorAndFlags & isSemanticInlineColorBit); }
+ bool isValid() const;
+ bool isSemantic() const;
+ bool usesColorFunctionSerialization() const;
bool isOpaque() const { return isExtended() ? asExtended().alpha() == 1.0 : asInline().alpha == 255; }
bool isVisible() const { return isExtended() ? asExtended().alpha() > 0.0 : asInline().alpha > 0; }
@@ -140,7 +138,7 @@
#if USE(CG)
WEBCORE_EXPORT Color(CGColorRef);
- WEBCORE_EXPORT Color(CGColorRef, SemanticTag);
+ WEBCORE_EXPORT Color(CGColorRef, OptionSet<Flags>);
#endif
#if PLATFORM(WIN)
@@ -164,8 +162,8 @@
static constexpr auto darkGreen = SRGBA<uint8_t> { 0, 128, 0 };
static constexpr auto orange = SRGBA<uint8_t> { 255, 128, 0 };
- bool isExtended() const { return !(m_colorData.inlineColorAndFlags & invalidInlineColor); }
- bool isInline() const { return !isExtended(); }
+ bool isExtended() const;
+ bool isInline() const;
const ExtendedColor& asExtended() const;
SRGBA<uint8_t> asInline() const;
@@ -174,6 +172,7 @@
friend bool operator==(const Color& a, const Color& b);
friend bool equalIgnoringSemanticColor(const Color& a, const Color& b);
friend bool extendedColorsEqual(const Color&, const Color&);
+ friend bool extendedColorsEqualIgnoringSemanticColor(const Color&, const Color&);
static bool isBlackColor(const Color&);
static bool isWhiteColor(const Color&);
@@ -182,30 +181,45 @@
template<class Decoder> static Optional<Color> decode(Decoder&);
private:
- Color(Ref<ExtendedColor>&&);
+ Color(Ref<ExtendedColor>&&, OptionSet<Flags> = { });
- void setColor(SRGBA<uint8_t>);
- void setExtendedColor(Ref<ExtendedColor>&&);
+ enum class FlagsIncludingPrivate : uint16_t {
+ Semantic = static_cast<uint16_t>(Flags::Semantic),
+ UseColorFunctionSerialization = static_cast<uint16_t>(Flags::UseColorFunctionSerialization),
+ Valid = 1 << 2,
+ Extended = 1 << 3,
+ HashTableEmptyValue = 1 << 4,
+ HashTableDeletedValue = 1 << 5,
+ };
+ static OptionSet<FlagsIncludingPrivate> toFlagsIncludingPrivate(OptionSet<Flags> flags) { return OptionSet<FlagsIncludingPrivate>::fromRaw(flags.toRaw()); }
- void tagAsSemantic() { m_colorData.inlineColorAndFlags |= isSemanticInlineColorBit; }
- void tagAsValid() { m_colorData.inlineColorAndFlags |= validInlineColor; }
+ OptionSet<FlagsIncludingPrivate> flags() const;
- // 0x_______00 is an ExtendedColor pointer.
- // 0x_______01 is an invalid inline color.
- // 0x_______11 is a valid inline color.
- static const uint64_t extendedColor = 0x0;
- static const uint64_t invalidInlineColor = 0x1;
- static const uint64_t validInlineColorBit = 0x2;
- static const uint64_t validInlineColor = 0x3;
- static const uint64_t isSemanticInlineColorBit = 0x4;
+ void setColor(SRGBA<uint8_t>, OptionSet<FlagsIncludingPrivate> = { });
+ void setExtendedColor(Ref<ExtendedColor>&&, OptionSet<FlagsIncludingPrivate> = { });
- static const uint64_t deletedHashValue = 0xFFFFFFFFFFFFFFFD;
- static const uint64_t emptyHashValue = 0xFFFFFFFFFFFFFFFB;
+ PackedColor::RGBA asPackedInline() const;
+ Ref<ExtendedColor> asExtendedRef() const;
- union {
- uint64_t inlineColorAndFlags { invalidInlineColor };
- ExtendedColor* extendedColor;
- } m_colorData;
+#if CPU(ADDRESS64)
+ static constexpr unsigned maxNumberOfBitsInPointer = 48;
+#else
+ static constexpr unsigned maxNumberOfBitsInPointer = 32;
+#endif
+ static constexpr uint64_t colorValueMask = (1ULL << maxNumberOfBitsInPointer) - 1;
+
+ static uint64_t encodedFlags(OptionSet<FlagsIncludingPrivate>);
+ static uint64_t encodedInlineColor(SRGBA<uint8_t>);
+ static uint64_t encodedPackedInlineColor(PackedColor::RGBA);
+ static uint64_t encodedExtendedColor(Ref<ExtendedColor>&&);
+
+ static OptionSet<FlagsIncludingPrivate> decodedFlags(uint64_t);
+ static SRGBA<uint8_t> decodedInlineColor(uint64_t);
+ static PackedColor::RGBA decodedPackedInlineColor(uint64_t);
+ static ExtendedColor& decodedExtendedColor(uint64_t);
+
+ static constexpr uint64_t invalidColorAndFlags = 0;
+ uint64_t m_colorAndFlags { invalidColorAndFlags };
};
bool operator==(const Color&, const Color&);
@@ -213,6 +227,7 @@
// One or both must be extended colors.
bool extendedColorsEqual(const Color&, const Color&);
+bool extendedColorsEqualIgnoringSemanticColor(const Color&, const Color&);
#if USE(CG)
WEBCORE_EXPORT CGColorRef cachedCGColor(const Color&);
@@ -224,8 +239,7 @@
{
if (a.isExtended() || b.isExtended())
return extendedColorsEqual(a, b);
-
- return a.m_colorData.inlineColorAndFlags == b.m_colorData.inlineColorAndFlags;
+ return a.m_colorAndFlags == b.m_colorAndFlags;
}
inline bool operator!=(const Color& a, const Color& b)
@@ -236,90 +250,104 @@
inline bool extendedColorsEqual(const Color& a, const Color& b)
{
if (a.isExtended() && b.isExtended())
- return a.asExtended() == b.asExtended();
+ return a.asExtended() == b.asExtended() && a.flags() == b.flags();
ASSERT(a.isExtended() || b.isExtended());
return false;
}
+inline bool extendedColorsEqualIgnoringSemanticColor(const Color& a, const Color& b)
+{
+ if (a.isExtended() && b.isExtended()) {
+ auto aFlags = a.flags() - Color::FlagsIncludingPrivate::Semantic;
+ auto bFlags = b.flags() - Color::FlagsIncludingPrivate::Semantic;
+ return a.asExtended() == b.asExtended() && aFlags == bFlags;
+ }
+
+ ASSERT(a.isExtended() || b.isExtended());
+ return false;
+}
+
inline bool equalIgnoringSemanticColor(const Color& a, const Color& b)
{
if (a.isExtended() || b.isExtended())
- return extendedColorsEqual(a, b);
- return (a.m_colorData.inlineColorAndFlags & ~Color::isSemanticInlineColorBit) == (b.m_colorData.inlineColorAndFlags & ~Color::isSemanticInlineColorBit);
+ return extendedColorsEqualIgnoringSemanticColor(a, b);
+
+ auto aFlags = a.flags() - Color::FlagsIncludingPrivate::Semantic;
+ auto bFlags = b.flags() - Color::FlagsIncludingPrivate::Semantic;
+ return a.asPackedInline().value == b.asPackedInline().value && aFlags == bFlags;
}
-inline Color::Color(SRGBA<uint8_t> color)
+inline Color::Color(SRGBA<uint8_t> color, OptionSet<Flags> flags)
{
- setColor(color);
+ setColor(color, toFlagsIncludingPrivate(flags));
}
-inline Color::Color(Optional<SRGBA<uint8_t>> color)
+inline Color::Color(Optional<SRGBA<uint8_t>> color, OptionSet<Flags> flags)
{
if (color)
- setColor(*color);
+ setColor(*color, toFlagsIncludingPrivate(flags));
}
-inline Color::Color(SRGBA<uint8_t> color, SemanticTag)
+inline Color::Color(ColorComponents<float> components, ColorSpace colorSpace, OptionSet<Flags> flags)
{
- setColor(color);
- tagAsSemantic();
+ setExtendedColor(ExtendedColor::create(components, colorSpace), toFlagsIncludingPrivate(flags));
}
-inline Color::Color(Optional<SRGBA<uint8_t>> color, SemanticTag)
+template<typename ColorType, typename std::enable_if_t<IsColorTypeWithComponentType<ColorType, float>>*>
+inline Color::Color(const ColorType& color, OptionSet<Flags> flags)
{
- if (color) {
- setColor(*color);
- tagAsSemantic();
- }
+ setExtendedColor(ExtendedColor::create(color), toFlagsIncludingPrivate(flags));
}
-inline Color::Color(ColorComponents<float> components, ColorSpace colorSpace)
+inline Color::Color(Ref<ExtendedColor>&& extendedColor, OptionSet<Flags> flags)
{
- setExtendedColor(ExtendedColor::create(components, colorSpace));
+ setExtendedColor(WTFMove(extendedColor), toFlagsIncludingPrivate(flags));
}
-template<typename ColorType, typename std::enable_if_t<IsColorTypeWithComponentType<ColorType, float>>*>
-inline Color::Color(const ColorType& color)
+inline Color::Color(WTF::HashTableEmptyValueType)
{
- setExtendedColor(ExtendedColor::create(color));
+ m_colorAndFlags = encodedFlags({ FlagsIncludingPrivate::HashTableEmptyValue });
}
-inline Color::Color(Ref<ExtendedColor>&& extendedColor)
-{
- setExtendedColor(WTFMove(extendedColor));
-}
-
inline Color::Color(WTF::HashTableDeletedValueType)
{
- static_assert(deletedHashValue & invalidInlineColor, "Color's deleted hash value must not look like an ExtendedColor");
- static_assert(!(deletedHashValue & validInlineColorBit), "Color's deleted hash value must not look like a valid InlineColor");
- static_assert(deletedHashValue & (1 << 4), "Color's deleted hash value must have some bits set that an InlineColor wouldn't have");
- m_colorData.inlineColorAndFlags = deletedHashValue;
- ASSERT(!isExtended());
+ m_colorAndFlags = encodedFlags({ FlagsIncludingPrivate::HashTableDeletedValue });
}
-inline Color::Color(WTF::HashTableEmptyValueType)
+inline bool Color::isHashTableDeletedValue() const
{
- static_assert(emptyHashValue & invalidInlineColor, "Color's empty hash value must not look like an ExtendedColor");
- static_assert(emptyHashValue & (1 << 4), "Color's deleted hash value must have some bits set that an InlineColor wouldn't have");
- m_colorData.inlineColorAndFlags = emptyHashValue;
- ASSERT(!isExtended());
+ return flags().contains(FlagsIncludingPrivate::HashTableDeletedValue);
}
inline Color::~Color()
{
if (isExtended())
- m_colorData.extendedColor->deref();
+ asExtended().deref();
}
inline unsigned Color::hash() const
{
if (isExtended())
- return computeHash(asExtended().components(), asExtended().colorSpace());
- return WTF::intHash(m_colorData.inlineColorAndFlags);
+ return computeHash(asExtended().components(), asExtended().colorSpace(), flags().toRaw());
+ return computeHash(asPackedInline().value, flags().toRaw());
}
+inline bool Color::isValid() const
+{
+ return flags().contains(FlagsIncludingPrivate::Valid);
+}
+
+inline bool Color::isSemantic() const
+{
+ return flags().contains(FlagsIncludingPrivate::Semantic);
+}
+
+inline bool Color::usesColorFunctionSerialization() const
+{
+ return flags().contains(FlagsIncludingPrivate::UseColorFunctionSerialization);
+}
+
template<typename Functor> decltype(auto) Color::callOnUnderlyingType(Functor&& functor) const
{
if (isExtended())
@@ -354,30 +382,104 @@
return alpha ? colorWithAlpha(alpha.value()) : *this;
}
+inline OptionSet<Color::FlagsIncludingPrivate> Color::flags() const
+{
+ return decodedFlags(m_colorAndFlags);
+}
+
+inline bool Color::isExtended() const
+{
+ return flags().contains(FlagsIncludingPrivate::Extended);
+}
+
+inline bool Color::isInline() const
+{
+ return !flags().contains(FlagsIncludingPrivate::Extended);
+}
+
inline const ExtendedColor& Color::asExtended() const
{
ASSERT(isExtended());
- return *m_colorData.extendedColor;
+ return decodedExtendedColor(m_colorAndFlags);
}
+inline Ref<ExtendedColor> Color::asExtendedRef() const
+{
+ ASSERT(isExtended());
+ return decodedExtendedColor(m_colorAndFlags);
+}
+
inline SRGBA<uint8_t> Color::asInline() const
{
ASSERT(isInline());
- return asSRGBA(PackedColor::RGBA { static_cast<uint32_t>(m_colorData.inlineColorAndFlags >> 32) });
+ return asSRGBA(asPackedInline());
}
-inline void Color::setColor(SRGBA<uint8_t> color)
+inline PackedColor::RGBA Color::asPackedInline() const
{
- m_colorData.inlineColorAndFlags = static_cast<uint64_t>(PackedColor::RGBA { color }.value) << 32;
- tagAsValid();
+ ASSERT(isInline());
+ return decodedPackedInlineColor(m_colorAndFlags);
}
-inline void Color::setExtendedColor(Ref<ExtendedColor>&& extendedColor)
+inline uint64_t Color::encodedFlags(OptionSet<FlagsIncludingPrivate> flags)
{
- // Zero the union, just in case a 32-bit system only assigns the
- // top 32 bits when copying the ExtendedColor pointer below.
- m_colorData.inlineColorAndFlags = 0;
- m_colorData.extendedColor = &extendedColor.leakRef();
+ return static_cast<uint64_t>(flags.toRaw()) << maxNumberOfBitsInPointer;
+}
+
+inline uint64_t Color::encodedInlineColor(SRGBA<uint8_t> color)
+{
+ return encodedPackedInlineColor(PackedColor::RGBA { color });
+}
+
+inline uint64_t Color::encodedPackedInlineColor(PackedColor::RGBA color)
+{
+ return color.value;
+}
+
+inline uint64_t Color::encodedExtendedColor(Ref<ExtendedColor>&& extendedColor)
+{
+#if CPU(ADDRESS64)
+ return bitwise_cast<uint64_t>(&extendedColor.leakRef());
+#else
+ return bitwise_cast<uint32_t>(&extendedColor.leakRef());
+#endif
+}
+
+inline OptionSet<Color::FlagsIncludingPrivate> Color::decodedFlags(uint64_t value)
+{
+ return OptionSet<Color::FlagsIncludingPrivate>::fromRaw(static_cast<unsigned>(value >> maxNumberOfBitsInPointer));
+}
+
+inline SRGBA<uint8_t> Color::decodedInlineColor(uint64_t value)
+{
+ return asSRGBA(decodedPackedInlineColor(value));
+}
+
+inline PackedColor::RGBA Color::decodedPackedInlineColor(uint64_t value)
+{
+ return PackedColor::RGBA { static_cast<uint32_t>(value & colorValueMask) };
+}
+
+inline ExtendedColor& Color::decodedExtendedColor(uint64_t value)
+{
+#if CPU(ADDRESS64)
+ return *bitwise_cast<ExtendedColor*>(value & colorValueMask);
+#else
+ return *bitwise_cast<ExtendedColor*>(static_cast<uint32_t>(value & colorValueMask));
+#endif
+}
+
+inline void Color::setColor(SRGBA<uint8_t> color, OptionSet<FlagsIncludingPrivate> flags)
+{
+ flags.add({ FlagsIncludingPrivate::Valid });
+ m_colorAndFlags = encodedInlineColor(color) | encodedFlags(flags);
+ ASSERT(isInline());
+}
+
+inline void Color::setExtendedColor(Ref<ExtendedColor>&& color, OptionSet<FlagsIncludingPrivate> flags)
+{
+ flags.add({ FlagsIncludingPrivate::Valid, FlagsIncludingPrivate::Extended });
+ m_colorAndFlags = encodedExtendedColor(WTFMove(color)) | encodedFlags(flags);
ASSERT(isExtended());
}
@@ -397,6 +499,15 @@
template<class Encoder> void Color::encode(Encoder& encoder) const
{
+ if (!isValid()) {
+ encoder << false;
+ return;
+ }
+ encoder << true;
+
+ encoder << flags().contains(FlagsIncludingPrivate::Semantic);
+ encoder << flags().contains(FlagsIncludingPrivate::UseColorFunctionSerialization);
+
if (isExtended()) {
encoder << true;
@@ -409,22 +520,36 @@
encoder << extendedColor.colorSpace();
return;
}
-
encoder << false;
- if (!isValid()) {
- encoder << false;
- return;
- }
-
- // FIXME: This should encode whether the color is semantic.
-
- encoder << true;
- encoder << PackedColor::RGBA { asInline() }.value;
+ encoder << asPackedInline().value;
}
template<class Decoder> Optional<Color> Color::decode(Decoder& decoder)
{
+ bool isValid;
+ if (!decoder.decode(isValid))
+ return WTF::nullopt;
+
+ if (!isValid)
+ return Color { };
+
+ OptionSet<Flags> flags;
+
+ bool isSemantic;
+ if (!decoder.decode(isSemantic))
+ return WTF::nullopt;
+
+ if (isSemantic)
+ flags.add(Flags::Semantic);
+
+ bool usesColorFunctionSerialization;
+ if (!decoder.decode(usesColorFunctionSerialization))
+ return WTF::nullopt;
+
+ if (usesColorFunctionSerialization)
+ flags.add(Flags::UseColorFunctionSerialization);
+
bool isExtended;
if (!decoder.decode(isExtended))
return WTF::nullopt;
@@ -445,21 +570,14 @@
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), flags };
}
- bool isValid;
- if (!decoder.decode(isValid))
- return WTF::nullopt;
-
- if (!isValid)
- return Color { };
-
uint32_t value;
if (!decoder.decode(value))
return WTF::nullopt;
- return Color { asSRGBA(PackedColor::RGBA { value }) };
+ return Color { asSRGBA(PackedColor::RGBA { value }), flags };
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/ColorBlending.cpp (273210 => 273211)
--- trunk/Source/WebCore/platform/graphics/ColorBlending.cpp 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/Source/WebCore/platform/graphics/ColorBlending.cpp 2021-02-21 00:47:59 UTC (rev 273211)
@@ -86,7 +86,7 @@
// FIXME: Why is preserving the semantic bit desired and/or correct here?
if (color.isSemantic())
- return Color(result, Color::Semantic);
+ return { result, Color::Flags::Semantic };
return result;
}
Modified: trunk/Source/WebCore/platform/graphics/ColorSerialization.cpp (273210 => 273211)
--- trunk/Source/WebCore/platform/graphics/ColorSerialization.cpp 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/Source/WebCore/platform/graphics/ColorSerialization.cpp 2021-02-21 00:47:59 UTC (rev 273211)
@@ -36,65 +36,65 @@
namespace WebCore {
-static String serializationForCSS(const A98RGB<float>&);
-static String serializationForHTML(const A98RGB<float>&);
-static String serializationForRenderTreeAsText(const A98RGB<float>&);
+static String serializationForCSS(const A98RGB<float>&, bool useColorFunctionSerialization);
+static String serializationForHTML(const A98RGB<float>&, bool useColorFunctionSerialization);
+static String serializationForRenderTreeAsText(const A98RGB<float>&, bool useColorFunctionSerialization);
-static String serializationForCSS(const DisplayP3<float>&);
-static String serializationForHTML(const DisplayP3<float>&);
-static String serializationForRenderTreeAsText(const DisplayP3<float>&);
+static String serializationForCSS(const DisplayP3<float>&, bool useColorFunctionSerialization);
+static String serializationForHTML(const DisplayP3<float>&, bool useColorFunctionSerialization);
+static String serializationForRenderTreeAsText(const DisplayP3<float>&, bool useColorFunctionSerialization);
-static String serializationForCSS(const LCHA<float>&);
-static String serializationForHTML(const LCHA<float>&);
-static String serializationForRenderTreeAsText(const LCHA<float>&);
+static String serializationForCSS(const LCHA<float>&, bool useColorFunctionSerialization);
+static String serializationForHTML(const LCHA<float>&, bool useColorFunctionSerialization);
+static String serializationForRenderTreeAsText(const LCHA<float>&, bool useColorFunctionSerialization);
-static String serializationForCSS(const Lab<float>&);
-static String serializationForHTML(const Lab<float>&);
-static String serializationForRenderTreeAsText(const Lab<float>&);
+static String serializationForCSS(const Lab<float>&, bool useColorFunctionSerialization);
+static String serializationForHTML(const Lab<float>&, bool useColorFunctionSerialization);
+static String serializationForRenderTreeAsText(const Lab<float>&, bool useColorFunctionSerialization);
-static String serializationForCSS(const LinearSRGBA<float>&);
-static String serializationForHTML(const LinearSRGBA<float>&);
-static String serializationForRenderTreeAsText(const LinearSRGBA<float>&);
+static String serializationForCSS(const LinearSRGBA<float>&, bool useColorFunctionSerialization);
+static String serializationForHTML(const LinearSRGBA<float>&, bool useColorFunctionSerialization);
+static String serializationForRenderTreeAsText(const LinearSRGBA<float>&, bool useColorFunctionSerialization);
-static String serializationForCSS(const ProPhotoRGB<float>&);
-static String serializationForHTML(const ProPhotoRGB<float>&);
-static String serializationForRenderTreeAsText(const ProPhotoRGB<float>&);
+static String serializationForCSS(const ProPhotoRGB<float>&, bool useColorFunctionSerialization);
+static String serializationForHTML(const ProPhotoRGB<float>&, bool useColorFunctionSerialization);
+static String serializationForRenderTreeAsText(const ProPhotoRGB<float>&, bool useColorFunctionSerialization);
-static String serializationForCSS(const Rec2020<float>&);
-static String serializationForHTML(const Rec2020<float>&);
-static String serializationForRenderTreeAsText(const Rec2020<float>&);
+static String serializationForCSS(const Rec2020<float>&, bool useColorFunctionSerialization);
+static String serializationForHTML(const Rec2020<float>&, bool useColorFunctionSerialization);
+static String serializationForRenderTreeAsText(const Rec2020<float>&, bool useColorFunctionSerialization);
-static String serializationForCSS(const SRGBA<float>&);
-static String serializationForHTML(const SRGBA<float>&);
-static String serializationForRenderTreeAsText(const SRGBA<float>&);
+static String serializationForCSS(const SRGBA<float>&, bool useColorFunctionSerialization);
+static String serializationForHTML(const SRGBA<float>&, bool useColorFunctionSerialization);
+static String serializationForRenderTreeAsText(const SRGBA<float>&, bool useColorFunctionSerialization);
-static String serializationForCSS(SRGBA<uint8_t>);
-static String serializationForHTML(SRGBA<uint8_t>);
-static String serializationForRenderTreeAsText(SRGBA<uint8_t>);
+static String serializationForCSS(SRGBA<uint8_t>, bool useColorFunctionSerialization);
+static String serializationForHTML(SRGBA<uint8_t>, bool useColorFunctionSerialization);
+static String serializationForRenderTreeAsText(SRGBA<uint8_t>, bool useColorFunctionSerialization);
-static String serializationForCSS(const XYZA<float, WhitePoint::D50>&);
-static String serializationForHTML(const XYZA<float, WhitePoint::D50>&);
-static String serializationForRenderTreeAsText(const XYZA<float, WhitePoint::D50>&);
+static String serializationForCSS(const XYZA<float, WhitePoint::D50>&, bool useColorFunctionSerialization);
+static String serializationForHTML(const XYZA<float, WhitePoint::D50>&, bool useColorFunctionSerialization);
+static String serializationForRenderTreeAsText(const XYZA<float, WhitePoint::D50>&, bool useColorFunctionSerialization);
String serializationForCSS(const Color& color)
{
- return color.callOnUnderlyingType([] (auto underlyingColor) {
- return serializationForCSS(underlyingColor);
+ return color.callOnUnderlyingType([&] (auto underlyingColor) {
+ return serializationForCSS(underlyingColor, color.usesColorFunctionSerialization());
});
}
String serializationForHTML(const Color& color)
{
- return color.callOnUnderlyingType([] (auto underlyingColor) {
- return serializationForHTML(underlyingColor);
+ return color.callOnUnderlyingType([&] (auto underlyingColor) {
+ return serializationForHTML(underlyingColor, color.usesColorFunctionSerialization());
});
}
String serializationForRenderTreeAsText(const Color& color)
{
- return color.callOnUnderlyingType([] (auto underlyingColor) {
- return serializationForRenderTreeAsText(underlyingColor);
+ return color.callOnUnderlyingType([&] (auto underlyingColor) {
+ return serializationForRenderTreeAsText(underlyingColor, color.usesColorFunctionSerialization());
});
}
@@ -125,8 +125,10 @@
return ""_s;
}
-template<typename ColorType> static String serialization(const ColorType& color)
+template<typename ColorType> static String serializationUsingColorFunction(const ColorType& color)
{
+ static_assert(std::is_same_v<typename ColorType::ComponentType, float>);
+
auto [c1, c2, c3, alpha] = color;
if (WTF::areEssentiallyEqual(alpha, 1.0f))
return makeString("color(", serialization(ColorSpaceFor<ColorType>), ' ', c1, ' ', c2, ' ', c3, ')');
@@ -133,45 +135,60 @@
return makeString("color(", serialization(ColorSpaceFor<ColorType>), ' ', c1, ' ', c2, ' ', c3, " / ", alpha, ')');
}
+static String serializationUsingColorFunction(const Lab<float>& color)
+{
+ auto [c1, c2, c3, alpha] = color;
+ if (WTF::areEssentiallyEqual(alpha, 1.0f))
+ return makeString("color(", serialization(ColorSpaceFor<Lab<float>>), ' ', c1, "% ", c2, ' ', c3, ')');
+ return makeString("color(", serialization(ColorSpaceFor<Lab<float>>), ' ', c1, "% ", c2, ' ', c3, " / ", alpha, ')');
+}
+
+static String serializationUsingColorFunction(const SRGBA<uint8_t>& color)
+{
+ return serializationUsingColorFunction(convertColor<SRGBA<float>>(color));
+}
+
// MARK: A98RGB<float> overloads
-String serializationForCSS(const A98RGB<float>& color)
+String serializationForCSS(const A98RGB<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForHTML(const A98RGB<float>& color)
+String serializationForHTML(const A98RGB<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForRenderTreeAsText(const A98RGB<float>& color)
+String serializationForRenderTreeAsText(const A98RGB<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
// MARK: DisplayP3<float> overloads
-String serializationForCSS(const DisplayP3<float>& color)
+String serializationForCSS(const DisplayP3<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForHTML(const DisplayP3<float>& color)
+String serializationForHTML(const DisplayP3<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForRenderTreeAsText(const DisplayP3<float>& color)
+String serializationForRenderTreeAsText(const DisplayP3<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
// MARK: LCHA<float> overloads
-String serializationForCSS(const LCHA<float>& color)
+String serializationForCSS(const LCHA<float>& color, bool useColorFunctionSerialization)
{
// https://www.w3.org/TR/css-color-4/#serializing-lab-lch
+ if (useColorFunctionSerialization)
+ return serializationUsingColorFunction(color);
auto [c1, c2, c3, alpha] = color;
if (WTF::areEssentiallyEqual(alpha, 1.0f))
@@ -179,21 +196,23 @@
return makeString("lch(", c1, "% ", c2, ' ', c3, " / ", alpha, ')');
}
-String serializationForHTML(const LCHA<float>& color)
+String serializationForHTML(const LCHA<float>& color, bool useColorFunctionSerialization)
{
- return serializationForCSS(color);
+ return serializationForCSS(color, useColorFunctionSerialization);
}
-String serializationForRenderTreeAsText(const LCHA<float>& color)
+String serializationForRenderTreeAsText(const LCHA<float>& color, bool useColorFunctionSerialization)
{
- return serializationForCSS(color);
+ return serializationForCSS(color, useColorFunctionSerialization);
}
// MARK: Lab<float> overloads
-String serializationForCSS(const Lab<float>& color)
+String serializationForCSS(const Lab<float>& color, bool useColorFunctionSerialization)
{
// https://www.w3.org/TR/css-color-4/#serializing-lab-lch
+ if (useColorFunctionSerialization)
+ return serializationUsingColorFunction(color);
auto [c1, c2, c3, alpha] = color;
if (WTF::areEssentiallyEqual(alpha, 1.0f))
@@ -201,82 +220,82 @@
return makeString("lab(", c1, "% ", c2, ' ', c3, " / ", alpha, ')');
}
-String serializationForHTML(const Lab<float>& color)
+String serializationForHTML(const Lab<float>& color, bool useColorFunctionSerialization)
{
- return serializationForCSS(color);
+ return serializationForCSS(color, useColorFunctionSerialization);
}
-String serializationForRenderTreeAsText(const Lab<float>& color)
+String serializationForRenderTreeAsText(const Lab<float>& color, bool useColorFunctionSerialization)
{
- return serializationForCSS(color);
+ return serializationForCSS(color, useColorFunctionSerialization);
}
// MARK: LinearSRGBA<float> overloads
-String serializationForCSS(const LinearSRGBA<float>& color)
+String serializationForCSS(const LinearSRGBA<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForHTML(const LinearSRGBA<float>& color)
+String serializationForHTML(const LinearSRGBA<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForRenderTreeAsText(const LinearSRGBA<float>& color)
+String serializationForRenderTreeAsText(const LinearSRGBA<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
// MARK: ProPhotoRGB<float> overloads
-String serializationForCSS(const ProPhotoRGB<float>& color)
+String serializationForCSS(const ProPhotoRGB<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForHTML(const ProPhotoRGB<float>& color)
+String serializationForHTML(const ProPhotoRGB<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForRenderTreeAsText(const ProPhotoRGB<float>& color)
+String serializationForRenderTreeAsText(const ProPhotoRGB<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
// MARK: Rec2020<float> overloads
-String serializationForCSS(const Rec2020<float>& color)
+String serializationForCSS(const Rec2020<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForHTML(const Rec2020<float>& color)
+String serializationForHTML(const Rec2020<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForRenderTreeAsText(const Rec2020<float>& color)
+String serializationForRenderTreeAsText(const Rec2020<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
// MARK: SRGBA<float> overloads
-String serializationForCSS(const SRGBA<float>& color)
+String serializationForCSS(const SRGBA<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForHTML(const SRGBA<float>& color)
+String serializationForHTML(const SRGBA<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForRenderTreeAsText(const SRGBA<float>& color)
+String serializationForRenderTreeAsText(const SRGBA<float>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
// MARK: SRGBA<uint8_t> overloads
@@ -298,8 +317,11 @@
return { { decimalDigit((alpha * 10 + 0x7F) / 0xFF), '\0', '\0', '\0' } };
}
-String serializationForCSS(SRGBA<uint8_t> color)
+String serializationForCSS(SRGBA<uint8_t> color, bool useColorFunctionSerialization)
{
+ if (useColorFunctionSerialization)
+ return serializationUsingColorFunction(color);
+
auto [red, green, blue, alpha] = color;
switch (alpha) {
case 0:
@@ -311,8 +333,11 @@
}
}
-String serializationForHTML(SRGBA<uint8_t> color)
+String serializationForHTML(SRGBA<uint8_t> color, bool useColorFunctionSerialization)
{
+ if (useColorFunctionSerialization)
+ return serializationUsingColorFunction(color);
+
auto [red, green, blue, alpha] = color;
if (alpha == 0xFF)
return makeString('#', hex(red, 2, Lowercase), hex(green, 2, Lowercase), hex(blue, 2, Lowercase));
@@ -319,8 +344,11 @@
return serializationForCSS(color);
}
-String serializationForRenderTreeAsText(SRGBA<uint8_t> color)
+String serializationForRenderTreeAsText(SRGBA<uint8_t> color, bool useColorFunctionSerialization)
{
+ if (useColorFunctionSerialization)
+ return serializationUsingColorFunction(color);
+
auto [red, green, blue, alpha] = color;
if (alpha < 0xFF)
return makeString('#', hex(red, 2), hex(green, 2), hex(blue, 2), hex(alpha, 2));
@@ -329,19 +357,19 @@
// MARK: XYZA<float, WhitePoint::D50> overloads
-String serializationForCSS(const XYZA<float, WhitePoint::D50>& color)
+String serializationForCSS(const XYZA<float, WhitePoint::D50>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForHTML(const XYZA<float, WhitePoint::D50>& color)
+String serializationForHTML(const XYZA<float, WhitePoint::D50>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
-String serializationForRenderTreeAsText(const XYZA<float, WhitePoint::D50>& color)
+String serializationForRenderTreeAsText(const XYZA<float, WhitePoint::D50>& color, bool)
{
- return serialization(color);
+ return serializationUsingColorFunction(color);
}
}
Modified: trunk/Source/WebCore/platform/graphics/ColorUtilities.h (273210 => 273211)
--- trunk/Source/WebCore/platform/graphics/ColorUtilities.h 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/Source/WebCore/platform/graphics/ColorUtilities.h 2021-02-21 00:47:59 UTC (rev 273211)
@@ -52,11 +52,11 @@
template<typename ColorType, typename Functor> ColorType colorByModifingEachNonAlphaComponent(const ColorType&, Functor&&);
-template<typename ColorType> constexpr ColorType colorWithOverridenAlpha(const ColorType&, uint8_t overrideAlpha);
-template<typename ColorType> ColorType colorWithOverridenAlpha(const ColorType&, float overrideAlpha);
+template<typename ColorType> constexpr ColorType colorWithOverriddenAlpha(const ColorType&, uint8_t overrideAlpha);
+template<typename ColorType> ColorType colorWithOverriddenAlpha(const ColorType&, float overrideAlpha);
-template<typename ColorType> constexpr ColorType invertedColorWithOverridenAlpha(const ColorType&, uint8_t overrideAlpha);
-template<typename ColorType> ColorType invertedColorWithOverridenAlpha(const ColorType&, float overrideAlpha);
+template<typename ColorType> constexpr ColorType invertedcolorWithOverriddenAlpha(const ColorType&, uint8_t overrideAlpha);
+template<typename ColorType> ColorType invertedcolorWithOverriddenAlpha(const ColorType&, float overrideAlpha);
template<typename ColorType, typename std::enable_if_t<std::is_same_v<typename ColorType::Model, RGBModel<typename ColorType::ComponentType>>>* = nullptr> constexpr bool isBlack(const ColorType&);
template<WhitePoint W> constexpr bool isBlack(const XYZA<float, W>&);
@@ -107,7 +107,7 @@
return { copy[0], copy[1], copy[2], copy[3] };
}
-template<typename ColorType> constexpr ColorType colorWithOverridenAlpha(const ColorType& color, uint8_t overrideAlpha)
+template<typename ColorType> constexpr ColorType colorWithOverriddenAlpha(const ColorType& color, uint8_t overrideAlpha)
{
auto copy = color;
copy.alpha = convertByteAlphaTo<typename ColorType::ComponentType>(overrideAlpha);
@@ -114,7 +114,7 @@
return copy;
}
-template<typename ColorType> ColorType colorWithOverridenAlpha(const ColorType& color, float overrideAlpha)
+template<typename ColorType> ColorType colorWithOverriddenAlpha(const ColorType& color, float overrideAlpha)
{
auto copy = color;
copy.alpha = convertFloatAlphaTo<typename ColorType::ComponentType>(overrideAlpha);
@@ -121,7 +121,7 @@
return copy;
}
-template<typename ColorType> constexpr ColorType invertedColorWithOverridenAlpha(const ColorType& color, uint8_t overrideAlpha)
+template<typename ColorType> constexpr ColorType invertedcolorWithOverriddenAlpha(const ColorType& color, uint8_t overrideAlpha)
{
static_assert(ColorType::Model::isInvertible);
@@ -135,7 +135,7 @@
return makeFromComponents<ColorType>(copy);
}
-template<typename ColorType> ColorType invertedColorWithOverridenAlpha(const ColorType& color, float overrideAlpha)
+template<typename ColorType> ColorType invertedcolorWithOverriddenAlpha(const ColorType& color, float overrideAlpha)
{
static_assert(ColorType::Model::isInvertible);
Modified: trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp (273210 => 273211)
--- trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/Source/WebCore/platform/graphics/cg/ColorCG.cpp 2021-02-21 00:47:59 UTC (rev 273211)
@@ -89,8 +89,8 @@
{
}
-Color::Color(CGColorRef color, SemanticTag tag)
- : Color(roundAndClampToSRGBALossy(color), tag)
+Color::Color(CGColorRef color, OptionSet<Flags> flags)
+ : Color(roundAndClampToSRGBALossy(color), flags)
{
}
Modified: trunk/Source/WebCore/platform/graphics/mac/ColorMac.mm (273210 => 273211)
--- trunk/Source/WebCore/platform/graphics/mac/ColorMac.mm 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/Source/WebCore/platform/graphics/mac/ColorMac.mm 2021-02-21 00:47:59 UTC (rev 273211)
@@ -108,7 +108,7 @@
Color semanticColorFromNSColor(NSColor *color)
{
- return Color(makeSimpleColorFromNSColor(color), Color::Semantic);
+ return Color(makeSimpleColorFromNSColor(color), Color::Flags::Semantic);
}
NSColor *nsColor(const Color& color)
Modified: trunk/Source/WebCore/rendering/RenderThemeIOS.mm (273210 => 273211)
--- trunk/Source/WebCore/rendering/RenderThemeIOS.mm 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/Source/WebCore/rendering/RenderThemeIOS.mm 2021-02-21 00:47:59 UTC (rev 273211)
@@ -1391,7 +1391,7 @@
static inline Optional<Color> systemColorFromCSSValueIDSelector(CSSValueIDAndSelector idAndSelector)
{
if (auto color = wtfObjCMsgSend<UIColor *>(PAL::getUIColorClass(), idAndSelector.selector))
- return Color { color.CGColor, Color::Semantic };
+ return Color { color.CGColor, Color::Flags::Semantic };
return WTF::nullopt;
}
@@ -1409,7 +1409,7 @@
if (auto selector = cssColorToSelector()) {
if (auto color = wtfObjCMsgSend<UIColor *>(PAL::getUIColorClass(), selector))
- return Color(color.CGColor, Color::Semantic);
+ return Color { color.CGColor, Color::Flags::Semantic };
}
return WTF::nullopt;
}
Modified: trunk/Source/WebCore/rendering/RenderThemeMac.mm (273210 => 273211)
--- trunk/Source/WebCore/rendering/RenderThemeMac.mm 2021-02-21 00:38:20 UTC (rev 273210)
+++ trunk/Source/WebCore/rendering/RenderThemeMac.mm 2021-02-21 00:47:59 UTC (rev 273211)
@@ -729,26 +729,26 @@
case CSSValueActiveborder:
// Hardcoded to avoid exposing a user appearance preference to the web for fingerprinting.
if (localAppearance.usingDarkAppearance())
- return { SRGBA<uint8_t> { 26, 169, 255 }, Color::Semantic };
- return { SRGBA<uint8_t> { 0, 103, 244 }, Color::Semantic };
+ return { SRGBA<uint8_t> { 26, 169, 255 }, Color::Flags::Semantic };
+ return { SRGBA<uint8_t> { 0, 103, 244 }, Color::Flags::Semantic };
case CSSValueAppleSystemControlAccent:
// Hardcoded to avoid exposing a user appearance preference to the web for fingerprinting.
// Same color in light and dark appearances.
- return { SRGBA<uint8_t> { 0, 122, 255 }, Color::Semantic };
+ return { SRGBA<uint8_t> { 0, 122, 255 }, Color::Flags::Semantic };
case CSSValueAppleSystemSelectedContentBackground:
// Hardcoded to avoid exposing a user appearance preference to the web for fingerprinting.
if (localAppearance.usingDarkAppearance())
- return { SRGBA<uint8_t> { 0, 88, 208 }, Color::Semantic };
- return { SRGBA<uint8_t> { 0, 99, 225 }, Color::Semantic };
+ return { SRGBA<uint8_t> { 0, 88, 208 }, Color::Flags::Semantic };
+ return { SRGBA<uint8_t> { 0, 99, 225 }, Color::Flags::Semantic };
case CSSValueHighlight:
case CSSValueAppleSystemSelectedTextBackground:
// Hardcoded to avoid exposing a user appearance preference to the web for fingerprinting.
if (localAppearance.usingDarkAppearance())
- return { SRGBA<uint8_t> { 63, 99, 139, 204 }, Color::Semantic };
- return { SRGBA<uint8_t> { 128, 188, 254, 153 }, Color::Semantic };
+ return { SRGBA<uint8_t> { 63, 99, 139, 204 }, Color::Flags::Semantic };
+ return { SRGBA<uint8_t> { 128, 188, 254, 153 }, Color::Flags::Semantic };
#if !HAVE(OS_DARK_MODE_SUPPORT)
case CSSValueAppleSystemContainerBorder: