Modified: trunk/Source/WebCore/platform/graphics/ColorConversion.h (278069 => 278070)
--- trunk/Source/WebCore/platform/graphics/ColorConversion.h 2021-05-26 00:37:19 UTC (rev 278069)
+++ trunk/Source/WebCore/platform/graphics/ColorConversion.h 2021-05-26 01:10:08 UTC (rev 278070)
@@ -114,16 +114,6 @@
WEBCORE_EXPORT static Lab<float> convert(const XYZA<float, WhitePoint::D50>&);
};
-// MARK: SRGBA<uint8_t>
-// Only sRGB supports non-floating point component types.
-template<> struct ColorConversion<SRGBA<float>, SRGBA<uint8_t>> {
- WEBCORE_EXPORT static SRGBA<float> convert(const SRGBA<uint8_t>&);
-};
-template<> struct ColorConversion<SRGBA<uint8_t>, SRGBA<float>> {
- WEBCORE_EXPORT static SRGBA<uint8_t> convert(const SRGBA<float>&);
-};
-
-
// Identity conversion.
template<typename ColorType> struct ColorConversion<ColorType, ColorType> {
@@ -154,19 +144,21 @@
// │ Lab │ ││ Gamma │ │ GammaExtended ││ │ ││ Gamma │ │ GammaExtended ││ ││ Gamma │ │ GammaExtended ││ ││ Gamma │ │ GammaExtended ││ ││ Gamma │ │ GammaExtended ││
// └─────▲─────┘ │└────────┘ └────────────────┘│ │ │└────▲───┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│
// │ └─────────────────────────────┘ │ └─────┼───────────────────────┘ └─────────────────────────────┘ └─────────────────────────────┘ └─────────────────────────────┘
-// │ │ ┌──┴──────────┬─────────────┐
-// │ │ │ │ │
-// ┌───────────┐ │┌───────────┐ ┌───────────┐┌─────────────┐
-// │ LCH │ ││ HSL │ │ HWB ││SRGB<uint8_t>│
-// └───────────┘ │└───────────┘ └───────────┘└─────────────┘
+// │ │ ┌──┴──────────┐
+// │ │ │ │
+// ┌───────────┐ │┌───────────┐ ┌───────────┐
+// │ LCH │ ││ HSL │ │ HWB │
+// └───────────┘ │└───────────┘ └───────────┘
template<typename Output, typename Input, typename> struct ColorConversion {
public:
static constexpr Output convert(const Input& color)
{
- // 1. Handle the special case SRGBA<uint8_t> for Input and Output.
- if constexpr (std::is_same_v<Input, SRGBA<uint8_t>> || std::is_same_v<Output, SRGBA<uint8_t>>)
- return convertColor<Output>(convertColor<SRGBA<float>>(color));
+ // 1. Handle the special case of Input or Output with a uint8_t component type.
+ if constexpr (std::is_same_v<typename Input::ComponentType, uint8_t>)
+ return handleToFloatConversion(color);
+ else if constexpr (std::is_same_v<typename Output::ComponentType, uint8_t>)
+ return handleToByteConversion(color);
// 2. Handle all color types that are not IsRGBType<T> or IsXYZA<T> for Input and Output. For all
// these other color types, we can uncondtionally convert them to their "reference" color, as
@@ -194,6 +186,28 @@
}
private:
+ static inline constexpr Output handleToFloatConversion(const Input& color)
+ {
+ static_assert(IsRGBBoundedType<Input>, "Only bounded ([0..1]) RGB color types support conversion to/from bytes.");
+
+ using InputWithReplacement = ColorTypeWithReplacementComponent<Input, float>;
+ if constexpr (std::is_same_v<InputWithReplacement, Output>)
+ return makeFromComponents<InputWithReplacement>(asColorComponents(color).map([](uint8_t value) -> float { return value / 255.0f; }));
+ else
+ return convertColor<Output>(convertColor<InputWithReplacement>(color));
+ }
+
+ static inline constexpr Output handleToByteConversion(const Input& color)
+ {
+ static_assert(IsRGBBoundedType<Output>, "Only bounded ([0..1]) RGB color types support conversion to/from bytes.");
+
+ using OutputWithReplacement = ColorTypeWithReplacementComponent<Output, float>;
+ if constexpr (std::is_same_v<OutputWithReplacement, Input>)
+ return makeFromComponents<Output>(asColorComponents(color).map([](float value) -> uint8_t { return std::clamp(std::lround(value * 255.0f), 0l, 255l); }));
+ else
+ return convertColor<Output>(convertColor<OutputWithReplacement>(color));
+ }
+
template<typename ColorType> static inline constexpr auto toLinearEncoded(const ColorType& color) -> typename ColorType::LinearCounterpart
{
auto [c1, c2, c3, alpha] = color;
Modified: trunk/Source/WebCore/platform/graphics/ColorTypes.h (278069 => 278070)
--- trunk/Source/WebCore/platform/graphics/ColorTypes.h 2021-05-26 00:37:19 UTC (rev 278069)
+++ trunk/Source/WebCore/platform/graphics/ColorTypes.h 2021-05-26 01:10:08 UTC (rev 278070)
@@ -158,6 +158,9 @@
template<typename T> inline constexpr bool IsColorType = IsConvertibleToColorComponents<T> && HasComponentTypeMember<T>;
template<typename T, typename U> inline constexpr bool IsColorTypeWithComponentType = IsConvertibleToColorComponents<T> && HasComponentType<T, U>;
+template<template<typename> class ColorType, typename Replacement> struct ColorTypeReplacingComponentTypeHelper { using type = ColorType<Replacement>; };
+template<template<typename> class ColorType, typename Replacement> using ColorTypeReplacingComponentType = typename ColorTypeReplacingComponentTypeHelper<ColorType, Replacement>::type;
+
template<typename Parent> struct ColorWithAlphaHelper {
// Helper to allow convenient syntax for working with color types.
// e.g. auto yellowWith50PercentAlpha = Color::yellow.colorWithAlphaByte(128);
@@ -221,16 +224,18 @@
template<typename T, typename D>
-struct BoundedGammaEncoded : RGBAType<T, D, BoundedGammaEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Clamped>> {
- using RGBAType<T, D, BoundedGammaEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Clamped>>::RGBAType;
+struct BoundedGammaEncoded : RGBAType<T, D, BoundedGammaEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Clamped>> {
+ using RGBAType<T, D, BoundedGammaEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Clamped>>::RGBAType;
using LinearCounterpart = BoundedLinearEncoded<T, D>;
using ExtendedCounterpart = ExtendedGammaEncoded<T, D>;
+
+ template<typename Replacement> using SelfWithReplacementComponent = BoundedGammaEncoded<Replacement, D>;
};
template<typename T, typename D>
-struct BoundedLinearEncoded : RGBAType<T, D, BoundedLinearEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Clamped>> {
- using RGBAType<T, D, BoundedLinearEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Clamped>>::RGBAType;
+struct BoundedLinearEncoded : RGBAType<T, D, BoundedLinearEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Clamped>> {
+ using RGBAType<T, D, BoundedLinearEncoded<T, D>, RGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Clamped>>::RGBAType;
static constexpr auto linearToXYZ = D::linearToXYZ;
static constexpr auto xyzToLinear = D::xyzToLinear;
@@ -237,11 +242,13 @@
using GammaEncodedCounterpart = BoundedGammaEncoded<T, D>;
using ExtendedCounterpart = ExtendedLinearEncoded<T, D>;
+
+ template<typename Replacement> using SelfWithReplacementComponent = BoundedLinearEncoded<Replacement, D>;
};
template<typename T, typename D>
-struct ExtendedGammaEncoded : RGBAType<T, D, ExtendedGammaEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Unclamped>> {
- using RGBAType<T, D, ExtendedGammaEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Unclamped>>::RGBAType;
+struct ExtendedGammaEncoded : RGBAType<T, D, ExtendedGammaEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Unclamped>> {
+ using RGBAType<T, D, ExtendedGammaEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Unclamped>>::RGBAType;
using LinearCounterpart = ExtendedLinearEncoded<T, D>;
using BoundedCounterpart = BoundedGammaEncoded<T, D>;
@@ -249,8 +256,8 @@
};
template<typename T, typename D>
-struct ExtendedLinearEncoded : RGBAType<T, D, ExtendedLinearEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Unclamped>> {
- using RGBAType<T, D, ExtendedLinearEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<TransferFunctionMode::Unclamped>>::RGBAType;
+struct ExtendedLinearEncoded : RGBAType<T, D, ExtendedLinearEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Unclamped>> {
+ using RGBAType<T, D, ExtendedLinearEncoded<T, D>, ExtendedRGBModel<T>, typename D::template TransferFunction<T, TransferFunctionMode::Unclamped>>::RGBAType;
static constexpr auto linearToXYZ = D::linearToXYZ;
static constexpr auto xyzToLinear = D::xyzToLinear;
@@ -275,6 +282,11 @@
template<typename, typename = void> inline constexpr bool HasLinearCounterpartMember = false;
template<typename ColorType> inline constexpr bool HasLinearCounterpartMember<ColorType, std::void_t<typename ColorType::LinearCounterpart>> = true;
+template<typename, typename = void> inline constexpr bool HasSelfWithReplacementComponentMember = false;
+template<typename ColorType> inline constexpr bool HasSelfWithReplacementComponentMember<ColorType, std::void_t<typename ColorType::SelfWithReplacementComponent>> = true;
+
+template<typename ColorType, typename Replacement> using ColorTypeWithReplacementComponent = typename ColorType::template SelfWithReplacementComponent<Replacement>;
+
template<typename ColorType> inline constexpr bool IsRGBType = HasDescriptorMember<ColorType>;
template<typename ColorType> inline constexpr bool IsRGBExtendedType = IsRGBType<ColorType> && HasBoundedCounterpartMember<ColorType>;
template<typename ColorType> inline constexpr bool IsRGBBoundedType = IsRGBType<ColorType> && HasExtendedCounterpartMember<ColorType>;
@@ -285,8 +297,8 @@
template<typename ColorType1, typename ColorType2> inline constexpr bool IsSameRGBTypeFamilyValue<ColorType1, ColorType2, true> = std::is_same_v<typename ColorType1::Descriptor, typename ColorType2::Descriptor>;
template<typename ColorType1, typename ColorType2> inline constexpr bool IsSameRGBTypeFamily = IsSameRGBTypeFamilyValue<ColorType1, ColorType2, IsRGBType<ColorType1> && IsRGBType<ColorType2>>;
-template<typename T> struct SRGBADescriptor {
- template<TransferFunctionMode Mode> using TransferFunction = SRGBTransferFunction<T, Mode>;
+struct SRGBADescriptor {
+ template<typename T, TransferFunctionMode Mode> using TransferFunction = SRGBTransferFunction<T, Mode>;
static constexpr WhitePoint whitePoint = WhitePoint::D65;
// https://drafts.csswg.org/css-color/#color-conversion-code
@@ -302,14 +314,14 @@
};
};
-template<typename T> using SRGBA = BoundedGammaEncoded<T, SRGBADescriptor<T>>;
-template<typename T> using LinearSRGBA = BoundedLinearEncoded<T, SRGBADescriptor<T>>;
-template<typename T> using ExtendedSRGBA = ExtendedGammaEncoded<T, SRGBADescriptor<T>>;
-template<typename T> using LinearExtendedSRGBA = ExtendedLinearEncoded<T, SRGBADescriptor<T>>;
+template<typename T> using SRGBA = BoundedGammaEncoded<T, SRGBADescriptor>;
+template<typename T> using LinearSRGBA = BoundedLinearEncoded<T, SRGBADescriptor>;
+template<typename T> using ExtendedSRGBA = ExtendedGammaEncoded<T, SRGBADescriptor>;
+template<typename T> using LinearExtendedSRGBA = ExtendedLinearEncoded<T, SRGBADescriptor>;
-template<typename T> struct A98RGBDescriptor {
- template<TransferFunctionMode Mode> using TransferFunction = A98RGBTransferFunction<T, Mode>;
+struct A98RGBDescriptor {
+ template<typename T, TransferFunctionMode Mode> using TransferFunction = A98RGBTransferFunction<T, Mode>;
static constexpr WhitePoint whitePoint = WhitePoint::D65;
// https://drafts.csswg.org/css-color/#color-conversion-code
@@ -325,12 +337,12 @@
};
};
-template<typename T> using A98RGB = BoundedGammaEncoded<T, A98RGBDescriptor<T>>;
-template<typename T> using LinearA98RGB = BoundedLinearEncoded<T, A98RGBDescriptor<T>>;
+template<typename T> using A98RGB = BoundedGammaEncoded<T, A98RGBDescriptor>;
+template<typename T> using LinearA98RGB = BoundedLinearEncoded<T, A98RGBDescriptor>;
-template<typename T> struct DisplayP3Descriptor {
- template<TransferFunctionMode Mode> using TransferFunction = SRGBTransferFunction<T, Mode>;
+struct DisplayP3Descriptor {
+ template<typename T, TransferFunctionMode Mode> using TransferFunction = SRGBTransferFunction<T, Mode>;
static constexpr WhitePoint whitePoint = WhitePoint::D65;
// https://drafts.csswg.org/css-color/#color-conversion-code
@@ -346,12 +358,12 @@
};
};
-template<typename T> using DisplayP3 = BoundedGammaEncoded<T, DisplayP3Descriptor<T>>;
-template<typename T> using LinearDisplayP3 = BoundedLinearEncoded<T, DisplayP3Descriptor<T>>;
+template<typename T> using DisplayP3 = BoundedGammaEncoded<T, DisplayP3Descriptor>;
+template<typename T> using LinearDisplayP3 = BoundedLinearEncoded<T, DisplayP3Descriptor>;
-template<typename T> struct ProPhotoRGBDescriptor {
- template<TransferFunctionMode Mode> using TransferFunction = ProPhotoRGBTransferFunction<T, Mode>;
+struct ProPhotoRGBDescriptor {
+ template<typename T, TransferFunctionMode Mode> using TransferFunction = ProPhotoRGBTransferFunction<T, Mode>;
static constexpr WhitePoint whitePoint = WhitePoint::D50;
// https://drafts.csswg.org/css-color/#color-conversion-code
@@ -367,12 +379,12 @@
};
};
-template<typename T> using ProPhotoRGB = BoundedGammaEncoded<T, ProPhotoRGBDescriptor<T>>;
-template<typename T> using LinearProPhotoRGB = BoundedLinearEncoded<T, ProPhotoRGBDescriptor<T>>;
+template<typename T> using ProPhotoRGB = BoundedGammaEncoded<T, ProPhotoRGBDescriptor>;
+template<typename T> using LinearProPhotoRGB = BoundedLinearEncoded<T, ProPhotoRGBDescriptor>;
-template<typename T> struct Rec2020Descriptor {
- template<TransferFunctionMode Mode> using TransferFunction = Rec2020TransferFunction<T, Mode>;
+struct Rec2020Descriptor {
+ template<typename T, TransferFunctionMode Mode> using TransferFunction = Rec2020TransferFunction<T, Mode>;
static constexpr WhitePoint whitePoint = WhitePoint::D65;
// https://drafts.csswg.org/css-color/#color-conversion-code
@@ -388,8 +400,8 @@
};
};
-template<typename T> using Rec2020 = BoundedGammaEncoded<T, Rec2020Descriptor<T>>;
-template<typename T> using LinearRec2020 = BoundedLinearEncoded<T, Rec2020Descriptor<T>>;
+template<typename T> using Rec2020 = BoundedGammaEncoded<T, Rec2020Descriptor>;
+template<typename T> using LinearRec2020 = BoundedLinearEncoded<T, Rec2020Descriptor>;
// MARK: - Lab Color Type.