Move Color blending related functions to their own files
https://bugs.webkit.org/show_bug.cgi?id=213742
Reviewed by Dean Jackson.
- Moves Color::blend(const Color&), Color::blendWithWhite(), blend(const Color&, const Color&, double)
and blendWithoutPremultiply(const Color&, const Color&, double) to their own files: ColorBlending.h/cpp
- Renames Color::blend(const Color&) to blendSourceOver(const Color&, const Color&)
- Renames Color::blendWithWhite() to blendWithWhite(const Color&).
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
Add new files.
* platform/graphics/Color.cpp:
(WebCore::Color::blend const): Deleted.
(WebCore::Color::blendWithWhite const): Deleted.
(WebCore::blend): Deleted.
(WebCore::blendWithoutPremultiply): Deleted.
* platform/graphics/Color.h:
* platform/graphics/ColorBlending.cpp: Copied from Source/WebCore/platform/graphics/Color.cpp.
* platform/graphics/ColorBlending.h: Added.
Move declarations / implementations from Color.h/cpp to ColorBlending.h/cpp.
* css/CSSGradientValue.cpp:
* editing/FrameSelection.cpp:
(WebCore::CaretBase::computeCaretColor):
* page/FrameView.cpp:
(WebCore::FrameView::documentBackgroundColor const):
* page/TextIndicator.cpp:
(WebCore::estimatedBackgroundColorForRange):
* page/animation/CSSPropertyAnimation.cpp:
* platform/graphics/filters/FilterOperation.cpp:
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::paintFillLayerExtended):
* rendering/RenderMenuList.cpp:
(RenderMenuList::getItemBackgroundColor const):
* rendering/RenderTheme.cpp:
(WebCore::RenderTheme::transformSelectionBackgroundColor const):
Update for new signatures and #include ColorBlending.h as neeeded.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@263753 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 38e0979..79b2326 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,46 @@
+2020-06-30 Sam Weinig <weinig@apple.com>
+
+ Move Color blending related functions to their own files
+ https://bugs.webkit.org/show_bug.cgi?id=213742
+
+ Reviewed by Dean Jackson.
+
+ - Moves Color::blend(const Color&), Color::blendWithWhite(), blend(const Color&, const Color&, double)
+ and blendWithoutPremultiply(const Color&, const Color&, double) to their own files: ColorBlending.h/cpp
+ - Renames Color::blend(const Color&) to blendSourceOver(const Color&, const Color&)
+ - Renames Color::blendWithWhite() to blendWithWhite(const Color&).
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ Add new files.
+
+ * platform/graphics/Color.cpp:
+ (WebCore::Color::blend const): Deleted.
+ (WebCore::Color::blendWithWhite const): Deleted.
+ (WebCore::blend): Deleted.
+ (WebCore::blendWithoutPremultiply): Deleted.
+ * platform/graphics/Color.h:
+ * platform/graphics/ColorBlending.cpp: Copied from Source/WebCore/platform/graphics/Color.cpp.
+ * platform/graphics/ColorBlending.h: Added.
+ Move declarations / implementations from Color.h/cpp to ColorBlending.h/cpp.
+
+ * css/CSSGradientValue.cpp:
+ * editing/FrameSelection.cpp:
+ (WebCore::CaretBase::computeCaretColor):
+ * page/FrameView.cpp:
+ (WebCore::FrameView::documentBackgroundColor const):
+ * page/TextIndicator.cpp:
+ (WebCore::estimatedBackgroundColorForRange):
+ * page/animation/CSSPropertyAnimation.cpp:
+ * platform/graphics/filters/FilterOperation.cpp:
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+ * rendering/RenderMenuList.cpp:
+ (RenderMenuList::getItemBackgroundColor const):
+ * rendering/RenderTheme.cpp:
+ (WebCore::RenderTheme::transformSelectionBackgroundColor const):
+ Update for new signatures and #include ColorBlending.h as neeeded.
+
2020-06-30 Andy Estes <aestes@apple.com>
[Xcode] Enable the "My Mac (Mac Catalyst)" destination in WebKit Xcode projects
diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt
index 95c7698..4a6d1e9 100644
--- a/Source/WebCore/Sources.txt
+++ b/Source/WebCore/Sources.txt
@@ -1907,6 +1907,7 @@
platform/graphics/ANGLEWebKitBridge.cpp
platform/graphics/BitmapImage.cpp
platform/graphics/Color.cpp
+platform/graphics/ColorBlending.cpp
platform/graphics/ColorUtilities.cpp
platform/graphics/ComplexTextController.cpp
platform/graphics/CrossfadeGeneratedImage.cpp
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index fa31908..dc0e586 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -9963,6 +9963,8 @@
7C193BFC1F5E10C50088F3E6 /* JSImageSmoothingQuality.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSImageSmoothingQuality.h; sourceTree = "<group>"; };
7C193BFD1F5E10D60088F3E6 /* JSPath2D.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSPath2D.cpp; sourceTree = "<group>"; };
7C193BFE1F5E10D70088F3E6 /* JSPath2D.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSPath2D.h; sourceTree = "<group>"; };
+ 7C1B4A6524A997590033727F /* ColorBlending.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ColorBlending.cpp; sourceTree = "<group>"; };
+ 7C1B4A6724A997660033727F /* ColorBlending.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ColorBlending.h; sourceTree = "<group>"; };
7C1E8CFF1ED0C2BE00B1D983 /* BeforeUnloadEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BeforeUnloadEvent.idl; sourceTree = "<group>"; };
7C1E8D001ED0C2BE00B1D983 /* CallbackResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallbackResult.h; sourceTree = "<group>"; };
7C1E97251A9F9834007BF0FB /* AutoFillButtonElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AutoFillButtonElement.cpp; sourceTree = "<group>"; };
@@ -25493,6 +25495,8 @@
A89943260B42338700D7C802 /* BitmapImage.h */,
B27535380B053814002CE64F /* Color.cpp */,
B27535390B053814002CE64F /* Color.h */,
+ 7C1B4A6524A997590033727F /* ColorBlending.cpp */,
+ 7C1B4A6724A997660033727F /* ColorBlending.h */,
7CAC6AEC247F1C5100E61D59 /* ColorComponents.h */,
3103B7DE1DB01556008BB890 /* ColorHash.h */,
7CAC6AE8247F082000E61D59 /* ColorMatrix.h */,
diff --git a/Source/WebCore/css/CSSGradientValue.cpp b/Source/WebCore/css/CSSGradientValue.cpp
index 4b99d9b..1042fa3 100644
--- a/Source/WebCore/css/CSSGradientValue.cpp
+++ b/Source/WebCore/css/CSSGradientValue.cpp
@@ -29,6 +29,7 @@
#include "CSSCalculationValue.h"
#include "CSSToLengthConversionData.h"
#include "CSSValueKeywords.h"
+#include "ColorBlending.h"
#include "FloatSize.h"
#include "Gradient.h"
#include "GradientImage.h"
diff --git a/Source/WebCore/editing/FrameSelection.cpp b/Source/WebCore/editing/FrameSelection.cpp
index 873d25d..33a927d 100644
--- a/Source/WebCore/editing/FrameSelection.cpp
+++ b/Source/WebCore/editing/FrameSelection.cpp
@@ -28,6 +28,7 @@
#include "AXObjectCache.h"
#include "CharacterData.h"
+#include "ColorBlending.h"
#include "DeleteSelectionCommand.h"
#include "Document.h"
#include "Editing.h"
@@ -1800,7 +1801,7 @@
if (!elementStyle.caretColor().isValid() && rootEditableStyle) {
auto rootEditableBackgroundColor = rootEditableStyle->visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
auto elementBackgroundColor = elementStyle.visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);
- auto disappearsIntoBackground = rootEditableBackgroundColor.blend(elementBackgroundColor) == rootEditableBackgroundColor;
+ auto disappearsIntoBackground = blendSourceOver(rootEditableBackgroundColor, elementBackgroundColor) == rootEditableBackgroundColor;
if (disappearsIntoBackground)
return rootEditableStyle->visitedDependentColorWithColorFilter(CSSPropertyCaretColor);
}
diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp
index 7ae7299..2e0a891 100644
--- a/Source/WebCore/page/FrameView.cpp
+++ b/Source/WebCore/page/FrameView.cpp
@@ -35,6 +35,7 @@
#include "CachedResourceLoader.h"
#include "Chrome.h"
#include "ChromeClient.h"
+#include "ColorBlending.h"
#include "DOMWindow.h"
#include "DebugPageOverlays.h"
#include "DeprecatedGlobalSettings.h"
@@ -4037,11 +4038,11 @@
if (!bodyBackgroundColor.isValid()) {
if (!htmlBackgroundColor.isValid())
return Color();
- return baseBackgroundColor().blend(htmlBackgroundColor);
+ return blendSourceOver(baseBackgroundColor(), htmlBackgroundColor);
}
if (!htmlBackgroundColor.isValid())
- return baseBackgroundColor().blend(bodyBackgroundColor);
+ return blendSourceOver(baseBackgroundColor(), bodyBackgroundColor);
// We take the aggregate of the base background color
// the <html> background color, and the <body>
@@ -4050,7 +4051,7 @@
// technically part of the document background, but it
// otherwise poses problems when the aggregate is not
// fully opaque.
- return baseBackgroundColor().blend(htmlBackgroundColor).blend(bodyBackgroundColor);
+ return blendSourceOver(blendSourceOver(baseBackgroundColor(), htmlBackgroundColor), bodyBackgroundColor);
}
bool FrameView::hasCustomScrollbars() const
diff --git a/Source/WebCore/page/TextIndicator.cpp b/Source/WebCore/page/TextIndicator.cpp
index 5b6ed5e..863e9ce 100644
--- a/Source/WebCore/page/TextIndicator.cpp
+++ b/Source/WebCore/page/TextIndicator.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "TextIndicator.h"
+#include "ColorBlending.h"
#include "ColorHash.h"
#include "Document.h"
#include "Editor.h"
@@ -249,7 +250,7 @@
}
parentRendererBackgroundColors.reverse();
for (const auto& backgroundColor : parentRendererBackgroundColors)
- estimatedBackgroundColor = estimatedBackgroundColor.blend(backgroundColor);
+ estimatedBackgroundColor = blendSourceOver(estimatedBackgroundColor, backgroundColor);
return estimatedBackgroundColor;
}
diff --git a/Source/WebCore/page/animation/CSSPropertyAnimation.cpp b/Source/WebCore/page/animation/CSSPropertyAnimation.cpp
index 98c3bb9..bc5ed71 100644
--- a/Source/WebCore/page/animation/CSSPropertyAnimation.cpp
+++ b/Source/WebCore/page/animation/CSSPropertyAnimation.cpp
@@ -41,6 +41,7 @@
#include "CachedImage.h"
#include "CalculationValue.h"
#include "ClipPathOperation.h"
+#include "ColorBlending.h"
#include "FloatConversion.h"
#include "FontCascade.h"
#include "FontSelectionAlgorithm.h"
diff --git a/Source/WebCore/platform/graphics/Color.cpp b/Source/WebCore/platform/graphics/Color.cpp
index 63dd040..7b0cf63 100644
--- a/Source/WebCore/platform/graphics/Color.cpp
+++ b/Source/WebCore/platform/graphics/Color.cpp
@@ -144,65 +144,6 @@
return WebCore::luminance(toSRGBALossy());
}
-Color Color::blend(const Color& source) const
-{
- if (!isVisible() || source.isOpaque())
- return source;
-
- if (!source.alpha())
- return *this;
-
- auto [selfR, selfG, selfB, selfA] = toSRGBASimpleColorLossy();
- auto [sourceR, sourceG, sourceB, sourceA] = source.toSRGBASimpleColorLossy();
-
- int d = 0xFF * (selfA + sourceA) - selfA * sourceA;
- int a = d / 0xFF;
- int r = (selfR * selfA * (0xFF - sourceA) + 0xFF * sourceA * sourceR) / d;
- int g = (selfG * selfA * (0xFF - sourceA) + 0xFF * sourceA * sourceG) / d;
- int b = (selfB * selfA * (0xFF - sourceA) + 0xFF * sourceA * sourceB) / d;
-
- return makeSimpleColor(r, g, b, a);
-}
-
-Color Color::blendWithWhite() const
-{
- constexpr int startAlpha = 153; // 60%
- constexpr int endAlpha = 204; // 80%;
- constexpr int alphaIncrement = 17;
-
- auto blendComponent = [](int c, int a) -> int {
- float alpha = a / 255.0f;
- int whiteBlend = 255 - a;
- c -= whiteBlend;
- return static_cast<int>(c / alpha);
- };
-
- // If the color contains alpha already, we leave it alone.
- if (!isOpaque())
- return *this;
-
- auto [existingR, existingG, existingB, existingAlpha] = toSRGBASimpleColorLossy();
-
- Color result;
- for (int alpha = startAlpha; alpha <= endAlpha; alpha += alphaIncrement) {
- // We have a solid color. Convert to an equivalent color that looks the same when blended with white
- // at the current alpha. Try using less transparency if the numbers end up being negative.
- int r = blendComponent(existingR, alpha);
- int g = blendComponent(existingG, alpha);
- int b = blendComponent(existingB, alpha);
-
- result = makeSimpleColor(r, g, b, alpha);
-
- if (r >= 0 && g >= 0 && b >= 0)
- break;
- }
-
- // FIXME: Why is preserving the semantic bit desired and/or correct here?
- if (isSemantic())
- result.tagAsSemantic();
- return result;
-}
-
Color Color::colorWithAlpha(float alpha) const
{
if (isExtended())
diff --git a/Source/WebCore/platform/graphics/Color.h b/Source/WebCore/platform/graphics/Color.h
index f3dbf97..61c998f 100644
--- a/Source/WebCore/platform/graphics/Color.h
+++ b/Source/WebCore/platform/graphics/Color.h
@@ -143,10 +143,6 @@
// FIXME: Replace remaining uses with luminance.
WEBCORE_EXPORT float lightness() const;
- // This is an implementation of Porter-Duff's "source-over" equation
- Color blend(const Color&) const;
- Color blendWithWhite() const;
-
Color invertedColorWithAlpha(Optional<float> alpha) const;
Color invertedColorWithAlpha(float alpha) const;
@@ -238,9 +234,6 @@
// One or both must be extended colors.
bool extendedColorsEqual(const Color&, const Color&);
-Color blend(const Color& from, const Color& to, double progress);
-Color blendWithoutPremultiply(const Color& from, const Color& to, double progress);
-
#if USE(CG)
WEBCORE_EXPORT CGColorRef cachedCGColor(const Color&);
#endif
diff --git a/Source/WebCore/platform/graphics/ColorBlending.cpp b/Source/WebCore/platform/graphics/ColorBlending.cpp
new file mode 100644
index 0000000..1b28373
--- /dev/null
+++ b/Source/WebCore/platform/graphics/ColorBlending.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2020 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 "ColorBlending.h"
+
+#include "AnimationUtilities.h"
+#include "Color.h"
+
+namespace WebCore {
+
+Color blendSourceOver(const Color& backdrop, const Color& source)
+{
+ if (!backdrop.isVisible() || source.isOpaque())
+ return source;
+
+ if (!source.alpha())
+ return *this;
+
+ auto [backdropR, backdropG, backdropB, backdropA] = backdrop.toSRGBASimpleColorLossy();
+ auto [sourceR, sourceG, sourceB, sourceA] = source.toSRGBASimpleColorLossy();
+
+ int d = 0xFF * (backdropA + sourceA) - backdropA * sourceA;
+ int a = d / 0xFF;
+ int r = (backdropR * backdropA * (0xFF - sourceA) + 0xFF * sourceA * sourceR) / d;
+ int g = (backdropG * backdropA * (0xFF - sourceA) + 0xFF * sourceA * sourceG) / d;
+ int b = (backdropB * backdropA * (0xFF - sourceA) + 0xFF * sourceA * sourceB) / d;
+
+ return makeSimpleColor(r, g, b, a);
+}
+
+Color blendWithWhite(const Color& color)
+{
+ constexpr int startAlpha = 153; // 60%
+ constexpr int endAlpha = 204; // 80%;
+ constexpr int alphaIncrement = 17;
+
+ auto blendComponent = [](int c, int a) -> int {
+ float alpha = a / 255.0f;
+ int whiteBlend = 255 - a;
+ c -= whiteBlend;
+ return static_cast<int>(c / alpha);
+ };
+
+ // If the color contains alpha already, we leave it alone.
+ if (!color.isOpaque())
+ return color;
+
+ auto [existingR, existingG, existingB, existingAlpha] = color.toSRGBASimpleColorLossy();
+
+ SimpleColor result;
+ for (int alpha = startAlpha; alpha <= endAlpha; alpha += alphaIncrement) {
+ // We have a solid color. Convert to an equivalent color that looks the same when blended with white
+ // at the current alpha. Try using less transparency if the numbers end up being negative.
+ int r = blendComponent(existingR, alpha);
+ int g = blendComponent(existingG, alpha);
+ int b = blendComponent(existingB, alpha);
+
+ result = makeSimpleColor(r, g, b, alpha);
+
+ if (r >= 0 && g >= 0 && b >= 0)
+ break;
+ }
+
+ // FIXME: Why is preserving the semantic bit desired and/or correct here?
+ if (color.isSemantic())
+ return Color(result, Color::Semantic);
+ return result;
+}
+
+Color blend(const Color& from, const Color& to, double progress)
+{
+ // FIXME: ExtendedColor - needs to handle color spaces.
+ // We need to preserve the state of the valid flag at the end of the animation
+ if (progress == 1 && !to.isValid())
+ return { };
+
+ // Since premultiplyCeiling() bails on zero alpha, special-case that.
+ auto premultipliedFrom = from.alpha() ? premultiplyCeiling(from.toSRGBASimpleColorLossy()) : Color::transparent;
+ auto premultipliedTo = to.alpha() ? premultiplyCeiling(to.toSRGBASimpleColorLossy()) : Color::transparent;
+
+ SimpleColor premultBlended = makeSimpleColor(
+ WebCore::blend(premultipliedFrom.redComponent(), premultipliedTo.redComponent(), progress),
+ WebCore::blend(premultipliedFrom.greenComponent(), premultipliedTo.greenComponent(), progress),
+ WebCore::blend(premultipliedFrom.blueComponent(), premultipliedTo.blueComponent(), progress),
+ WebCore::blend(premultipliedFrom.alphaComponent(), premultipliedTo.alphaComponent(), progress)
+ );
+
+ return unpremultiply(premultBlended);
+}
+
+Color blendWithoutPremultiply(const Color& from, const Color& to, double progress)
+{
+ // FIXME: ExtendedColor - needs to handle color spaces.
+ // We need to preserve the state of the valid flag at the end of the animation
+ if (progress == 1 && !to.isValid())
+ return { };
+
+ auto fromSRGB = from.toSRGBASimpleColorLossy();
+ auto toSRGB = from.toSRGBASimpleColorLossy();
+
+ return makeSimpleColor(
+ WebCore::blend(fromSRGB.redComponent(), toSRGB.redComponent(), progress),
+ WebCore::blend(fromSRGB.greenComponent(), toSRGB.greenComponent(), progress),
+ WebCore::blend(fromSRGB.blueComponent(), toSRGB.blueComponent(), progress),
+ WebCore::blend(fromSRGB.alphaComponent(), toSRGB.alphaComponent(), progress)
+ );
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/ColorBlending.h b/Source/WebCore/platform/graphics/ColorBlending.h
new file mode 100644
index 0000000..ed2b807
--- /dev/null
+++ b/Source/WebCore/platform/graphics/ColorBlending.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#pragma once
+
+namespace WebCore {
+
+class Color;
+
+// This is an implementation of Porter-Duff's "source-over" equation
+Color blendSourceOver(const Color&, const Color&);
+
+// Bespoke "whitening" algorithm used by RenderTheme::transformSelectionBackgroundColor.
+Color blendWithWhite(const Color&);
+
+Color blend(const Color& from, const Color& to, double progress);
+Color blendWithoutPremultiply(const Color& from, const Color& to, double progress);
+
+}
diff --git a/Source/WebCore/platform/graphics/filters/FilterOperation.cpp b/Source/WebCore/platform/graphics/filters/FilterOperation.cpp
index f057c24..69f764c 100644
--- a/Source/WebCore/platform/graphics/filters/FilterOperation.cpp
+++ b/Source/WebCore/platform/graphics/filters/FilterOperation.cpp
@@ -29,6 +29,7 @@
#include "AnimationUtilities.h"
#include "CachedResourceLoader.h"
#include "CachedSVGDocumentReference.h"
+#include "ColorBlending.h"
#include "ColorMatrix.h"
#include "ColorUtilities.h"
#include "FilterEffect.h"
diff --git a/Source/WebCore/rendering/RenderBoxModelObject.cpp b/Source/WebCore/rendering/RenderBoxModelObject.cpp
index 6c31e7d..5ddfc31 100644
--- a/Source/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/Source/WebCore/rendering/RenderBoxModelObject.cpp
@@ -29,6 +29,7 @@
#include "BitmapImage.h"
#include "BorderEdge.h"
#include "CachedImage.h"
+#include "ColorBlending.h"
#include "Document.h"
#include "DocumentTimeline.h"
#include "FloatRoundedRect.h"
@@ -934,7 +935,7 @@
FloatRect backgroundRectForPainting = snapRectToDevicePixels(backgroundRect, deviceScaleFactor);
if (baseColor.isVisible()) {
if (!baseBgColorOnly && bgColor.isVisible())
- baseColor = baseColor.blend(bgColor);
+ baseColor = blendSourceOver(baseColor, bgColor);
context.fillRect(backgroundRectForPainting, baseColor, CompositeOperator::Copy);
} else if (!baseBgColorOnly && bgColor.isVisible()) {
auto operation = context.compositeOperation();
diff --git a/Source/WebCore/rendering/RenderMenuList.cpp b/Source/WebCore/rendering/RenderMenuList.cpp
index 8e09ea5..c02581c 100644
--- a/Source/WebCore/rendering/RenderMenuList.cpp
+++ b/Source/WebCore/rendering/RenderMenuList.cpp
@@ -29,6 +29,7 @@
#include "AccessibilityMenuList.h"
#include "CSSFontSelector.h"
#include "Chrome.h"
+#include "ColorBlending.h"
#include "Frame.h"
#include "FrameView.h"
#include "HTMLNames.h"
@@ -532,14 +533,14 @@
}
// Otherwise, the item's background is overlayed on top of the menu background.
- backgroundColor = style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor).blend(backgroundColor);
+ backgroundColor = blendSourceOver(style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor), backgroundColor);
if (backgroundColor.isOpaque()) {
itemBackgroundColor = backgroundColor;
return;
}
// If the menu background is not opaque, then add an opaque white background behind.
- itemBackgroundColor = Color(Color::white).blend(backgroundColor);
+ itemBackgroundColor = blendSourceOver(Color::white, backgroundColor);
}
PopupMenuStyle RenderMenuList::menuStyle() const
diff --git a/Source/WebCore/rendering/RenderTheme.cpp b/Source/WebCore/rendering/RenderTheme.cpp
index a21d52c..fc80cb7 100644
--- a/Source/WebCore/rendering/RenderTheme.cpp
+++ b/Source/WebCore/rendering/RenderTheme.cpp
@@ -22,6 +22,7 @@
#include "RenderTheme.h"
#include "CSSValueKeywords.h"
+#include "ColorBlending.h"
#include "ControlStates.h"
#include "Document.h"
#include "FileList.h"
@@ -616,7 +617,7 @@
Color RenderTheme::transformSelectionBackgroundColor(const Color& color, OptionSet<StyleColor::Options>) const
{
- return color.blendWithWhite();
+ return blendWithWhite(color);
}
Color RenderTheme::activeSelectionForegroundColor(OptionSet<StyleColor::Options> options) const