Diff
Modified: trunk/Source/WebCore/ChangeLog (264279 => 264280)
--- trunk/Source/WebCore/ChangeLog 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/ChangeLog 2020-07-12 17:28:02 UTC (rev 264280)
@@ -1,3 +1,156 @@
+2020-07-12 Darin Adler <da...@apple.com>
+
+ Simplify and improve Gradient, some other small color-related removals
+ https://bugs.webkit.org/show_bug.cgi?id=214221
+
+ Reviewed by Sam Weinig.
+
+ * css/CSSGradientValue.cpp: Removed some unneeded includes.
+
+ * html/ColorInputType.cpp:
+ (WebCore::ColorInputType::currentColor): Deleted.
+ (WebCore::ColorInputType::shouldShowSuggestions const): Deleted.
+ * html/ColorInputType.h: Updated for the above.
+
+ * html/HTMLDocument.cpp: Removed unneeded include of HashTools.h.
+
+ * html/canvas/CanvasGradient.cpp:
+ (WebCore::CanvasGradient::create): Moved these functions out of the
+ header since inlining should be the same or better with them here.
+ (WebCore::CanvasGradient::~CanvasGradient): Moved this out of the
+ header so we don't need to include Gradient.h in the header.
+ (WebCore::CanvasGradient::addColorStop): Updated for change to
+ Gradient::addColorStop and move Color rather than copying it.
+
+ * html/canvas/CanvasGradient.h: Removed include of Gradient.h.
+ Moved things out of the header to make that work.
+
+ * inspector/InspectorCanvas.cpp:
+ (WebCore::InspectorCanvas::buildArrayForCanvasGradient): Removed
+ use of Gradient::type and instead unify the type string code with
+ the code that interprets the data for the different types.
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::recalculateScrollbarOverlayStyle): Refactored
+ to eliminate the multiple redundant code paths, otherwising leaving
+ the logic unchanged.
+
+ * platform/ColorChooserClient.h: Remove unneeded includes and unused
+ currentColor and shouldShowSuggestions functions.
+
+ * platform/graphics/Gradient.cpp:
+ (WebCore::Gradient::create): Replaced create functions that take
+ type-specific data structure with one that takes the variant Data.
+ (WebCore::Gradient::Gradient): Ditto. Also removed platformInit.
+ (WebCore::Gradient::~Gradient): Removed platformDestroy.
+ (WebCore::Gradient::type const): Deleted.
+ (WebCore::Gradient::addColorStop): Take an rvalue reference to cut down
+ a little bit on reference count churn. Replaced the platformDestroy
+ function with a new stopsChanged function. Removed an unneeded overload
+ that takes the two parts of a ColorStop separately.
+ (WebCore::Gradient::setSortedColorStops): Use stopsChanged.
+ (WebCore::Gradient::sortStops const): Simplify a bit, using a lambda.
+ Also gave this a shorter name; it still optimizes by not sorting if
+ the vector is already sorted.
+ (WebCore::Gradient::hasAlpha const): Deleted.
+ (WebCore::Gradient::setSpreadMethod): Removed some slightly overzealous
+ code checking this isn't used after creating the platform-specific gradient.
+ Decided not to bother with this for now.
+ (WebCore::Gradient::setGradientSpaceTransform): Tweaked formatting.
+ (WebCore::add): Added overloads to add(Hasher&) so we can use computeHash.
+ (WebCore::Gradient::hash const): Use computeHash instead of hashMemory.
+
+ * platform/graphics/Gradient.h: Use RetainPtr, COMPtr, and RefPtr instead
+ of manually managing the lifetimes of the platform-specific underlying
+ gradient objects. Also removed the unhelpful PlatformGradient type. This
+ pattern, all too common in our platform library, provides no useful
+ abstraction here. Removed unneeded constructors from ColorStop.
+ Updated for changes above. Added platform-specific functions createBrush,
+ createPattern, and createCGGradient. Simplify encoding and decoding by
+ taking advantage of the support for encoding/decoding variants.
+ Remove the enum Gradient::Type entirely. Removed the invalidateHash
+ function because it's only used in a few setters and setting the hash
+ to 0 is a fine way to write it there.
+
+ * platform/graphics/GraphicsContext.cpp:
+ (WebCore::GraphicsContextState::GraphicsContextState): Moved here from
+ the header so we don't need to include Gradient.h in the header.
+ (WebCore::GraphicsContextState::~GraphicsContextState): Ditto.
+ (WebCore::GraphicsContextState::operator=): Ditto.
+
+ * platform/graphics/GraphicsContext.h: Removed include of Gradient.h.
+ Moved things out of the header to make that work.
+
+ * platform/graphics/cairo/CairoOperations.cpp:
+ (WebCore::Cairo::FillSource::FillSource): Use createPattern instead of
+ createPlatformGradient.
+ (WebCore::Cairo::StrokeSource::StrokeSource): Ditto.
+
+ * platform/graphics/cairo/GradientCairo.cpp:
+ (WebCore::Gradient::stopsChanged): Renamed from platformDestroy.
+ (WebCore::interpolateColorStop): Rewrote to use existing blend functions.
+ (WebCore::createConic): Changed return type to RefPtr. Tweaked to match
+ WebKit coding style a bit better, use auto, use Vector::first/last, and
+ updated for removal of the Gradient::ColorStop constructor.
+ (WebCore::Gradient::createPattern): Renamed from createPlatformGradient.
+ Changed to return a RefPtr instead of a raw pointer the caller needs to
+ adopt at each call site. Refactored so it no longer uses Gradient::type.
+ (WebCore::Gradient::fill): Use createPattern.
+ * platform/graphics/cairo/GraphicsContextImplCairo.cpp:
+ (WebCore::GraphicsContextImplCairo::fillRect): Ditto.
+
+ * platform/graphics/cg/GradientCG.cpp:
+ (WebCore::Gradient::stopsChanged): Renamed from platformDestroy, and
+ simplified implementation now that we use RetainPtr.
+ (WebCore::Gradient::createCGGradient): Renamed from platformGradient,
+ got rid of the return value, and made it caller responsibility to only
+ call this when a gradeitn needs to be allocated.
+ (WebCore::Gradient::paint): Updated to use the above.
+
+ * platform/graphics/cg/GraphicsContextCG.cpp: Add include of Gradient.h.
+
+ * platform/graphics/displaylists/DisplayListItems.h:
+ Added include of Gradient.h since the function templates in this file
+ encode and decode gradients.
+
+ * platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp:
+ (Nicosia::CairoOperationRecorder::fillRect): Use createPattern.
+
+ * platform/graphics/win/Direct2DOperations.cpp:
+ (WebCore::Direct2D::FillSource::FillSource): Use createBrush
+ (WebCore::Direct2D::StrokeSource::StrokeSource): Ditto.
+
+ * platform/graphics/win/GradientDirect2D.cpp:
+ (WebCore::Gradient::stopsChanged): Renamed from platformDestroy and
+ simplified implementation now that we use COMPtr.
+ (WebCore::Gradient::platformGradient): Deleted.
+ (WebCore::Gradient::createPlatformGradientIfNecessary): Deleted.
+ (WebCore::Gradient::createBrush): Renamed from generateGradient and
+ added a return value. Simplified now that we use COMPtr, optimized
+ the code a bit, and added some FIXME about mistakes I noticed.
+ (WebCore::Gradient::fill): Use createBrush and m_brush.
+ * platform/graphics/win/GraphicsContextImplDirect2D.cpp:
+ (WebCore::GraphicsContextImplDirect2D::fillRect): Use createBrush.
+
+ * platform/mac/ScrollAnimatorMac.mm: Added include of Gradient.h.
+
+ * rendering/RenderThemeIOS.mm:
+ (WebCore::RenderThemeIOS::paintProgressBar): Updated for changes to
+ addColorStop. Also remove a lot of unnecessary conversion from float
+ to double and back to float.
+
+ * rendering/svg/RenderSVGResourceGradient.cpp:
+ (WebCore::RenderSVGResourceGradient::addStops): Update to make
+ and move a new color stop instead of copying it, modifying it in
+ place, and then copying it again.
+ * rendering/svg/RenderSVGResourceGradient.cpp: Removed include of
+ Gradient.h.
+
+ * svg/SVGGradientElement.cpp:
+ (WebCore::SVGGradientElement::buildStops): Use std::clamp to convert
+ the offsets into monotonically increasing ones in a more direct way,
+ using variable names instead of comments to clarify what we are doing.
+
2020-07-12 Yusuke Suzuki <ysuz...@apple.com>
Unreviewed, fix GTK debian builds
Modified: trunk/Source/WebCore/css/CSSGradientValue.cpp (264279 => 264280)
--- trunk/Source/WebCore/css/CSSGradientValue.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/css/CSSGradientValue.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -30,8 +30,6 @@
#include "CSSToLengthConversionData.h"
#include "CSSValueKeywords.h"
#include "ColorBlending.h"
-#include "FloatSize.h"
-#include "Gradient.h"
#include "GradientImage.h"
#include "NodeRenderStyle.h"
#include "Pair.h"
Modified: trunk/Source/WebCore/html/ColorInputType.cpp (264279 => 264280)
--- trunk/Source/WebCore/html/ColorInputType.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/html/ColorInputType.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -270,21 +270,6 @@
return element()->document().view()->contentsToRootView(element()->renderer()->absoluteBoundingBoxRect());
}
-Color ColorInputType::currentColor()
-{
- return valueAsColor();
-}
-
-bool ColorInputType::shouldShowSuggestions() const
-{
-#if ENABLE(DATALIST_ELEMENT)
- ASSERT(element());
- return element()->hasAttributeWithoutSynchronization(listAttr);
-#else
- return false;
-#endif
-}
-
Vector<Color> ColorInputType::suggestedColors() const
{
Vector<Color> suggestions;
Modified: trunk/Source/WebCore/html/ColorInputType.h (264279 => 264280)
--- trunk/Source/WebCore/html/ColorInputType.h 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/html/ColorInputType.h 2020-07-12 17:28:02 UTC (rev 264280)
@@ -48,8 +48,6 @@
void didChooseColor(const Color&) final;
void didEndChooser() final;
IntRect elementRectRelativeToRootView() const final;
- Color currentColor() final;
- bool shouldShowSuggestions() const final;
Vector<Color> suggestedColors() const final;
bool isMouseFocusable() const final;
bool isKeyboardFocusable(KeyboardEvent*) const final;
Modified: trunk/Source/WebCore/html/HTMLDocument.cpp (264279 => 264280)
--- trunk/Source/WebCore/html/HTMLDocument.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/html/HTMLDocument.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -74,7 +74,6 @@
#include "HTMLHtmlElement.h"
#include "HTMLIFrameElement.h"
#include "HTMLNames.h"
-#include "HashTools.h"
#include "ScriptController.h"
#include "StyleResolver.h"
#include <wtf/IsoMallocInlines.h>
Modified: trunk/Source/WebCore/html/canvas/CanvasGradient.cpp (264279 => 264280)
--- trunk/Source/WebCore/html/canvas/CanvasGradient.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/html/canvas/CanvasGradient.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -29,6 +29,7 @@
#include "CanvasBase.h"
#include "CanvasStyle.h"
+#include "Gradient.h"
namespace WebCore {
@@ -44,6 +45,18 @@
{
}
+Ref<CanvasGradient> CanvasGradient::create(const FloatPoint& p0, const FloatPoint& p1, CanvasBase& canvasBase)
+{
+ return adoptRef(*new CanvasGradient(p0, p1, canvasBase));
+}
+
+Ref<CanvasGradient> CanvasGradient::create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, CanvasBase& canvasBase)
+{
+ return adoptRef(*new CanvasGradient(p0, r0, p1, r1, canvasBase));
+}
+
+CanvasGradient::~CanvasGradient() = default;
+
ExceptionOr<void> CanvasGradient::addColorStop(float value, const String& colorString)
{
if (!(value >= 0 && value <= 1))
@@ -54,7 +67,7 @@
if (!color.isValid())
return Exception { SyntaxError };
- m_gradient->addColorStop(value, color);
+ m_gradient->addColorStop({ value, WTFMove(color) });
return { };
}
Modified: trunk/Source/WebCore/html/canvas/CanvasGradient.h (264279 => 264280)
--- trunk/Source/WebCore/html/canvas/CanvasGradient.h 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/html/canvas/CanvasGradient.h 2020-07-12 17:28:02 UTC (rev 264280)
@@ -27,22 +27,18 @@
#pragma once
#include "ExceptionOr.h"
-#include "Gradient.h"
+#include "FloatPoint.h"
namespace WebCore {
class CanvasBase;
+class Gradient;
class CanvasGradient : public RefCounted<CanvasGradient> {
public:
- static Ref<CanvasGradient> create(const FloatPoint& p0, const FloatPoint& p1, CanvasBase& canvasBase)
- {
- return adoptRef(*new CanvasGradient(p0, p1, canvasBase));
- }
- static Ref<CanvasGradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, CanvasBase& canvasBase)
- {
- return adoptRef(*new CanvasGradient(p0, r0, p1, r1, canvasBase));
- }
+ static Ref<CanvasGradient> create(const FloatPoint& p0, const FloatPoint& p1, CanvasBase&);
+ static Ref<CanvasGradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, CanvasBase&);
+ ~CanvasGradient();
Gradient& gradient() { return m_gradient; }
const Gradient& gradient() const { return m_gradient; }
@@ -55,7 +51,6 @@
Ref<Gradient> m_gradient;
CanvasBase& m_canvas;
-
};
}
Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (264279 => 264280)
--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -36,6 +36,7 @@
#include "CSSFontSelector.h"
#include "CSSParser.h"
#include "CSSPropertyNames.h"
+#include "Gradient.h"
#include "ImageBuffer.h"
#include "ImageData.h"
#include "InspectorInstrumentation.h"
Modified: trunk/Source/WebCore/inspector/InspectorCanvas.cpp (264279 => 264280)
--- trunk/Source/WebCore/inspector/InspectorCanvas.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/inspector/InspectorCanvas.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -1158,19 +1158,17 @@
Ref<JSON::ArrayOf<JSON::Value>> InspectorCanvas::buildArrayForCanvasGradient(const CanvasGradient& canvasGradient)
{
- const auto& gradient = canvasGradient.gradient();
-
- String type = gradient.type() == Gradient::Type::Radial ? "radial-gradient"_s : gradient.type() == Gradient::Type::Linear ? "linear-gradient"_s : "conic-gradient"_s;
-
+ ASCIILiteral type = "linear-gradient"_s;
auto parameters = JSON::ArrayOf<float>::create();
- WTF::switchOn(gradient.data(),
- [¶meters] (const Gradient::LinearData& data) {
+ WTF::switchOn(canvasGradient.gradient().data(),
+ [&] (const Gradient::LinearData& data) {
parameters->addItem(data.point0.x());
parameters->addItem(data.point0.y());
parameters->addItem(data.point1.x());
parameters->addItem(data.point1.y());
},
- [¶meters] (const Gradient::RadialData& data) {
+ [&] (const Gradient::RadialData& data) {
+ type = "radial-gradient"_s;
parameters->addItem(data.point0.x());
parameters->addItem(data.point0.y());
parameters->addItem(data.startRadius);
@@ -1178,7 +1176,8 @@
parameters->addItem(data.point1.y());
parameters->addItem(data.endRadius);
},
- [¶meters] (const Gradient::ConicData& data) {
+ [&] (const Gradient::ConicData& data) {
+ type = "conic-gradient"_s;
parameters->addItem(data.point0.x());
parameters->addItem(data.point0.y());
parameters->addItem(data.angleRadians);
@@ -1186,7 +1185,7 @@
);
auto stops = JSON::ArrayOf<JSON::Value>::create();
- for (auto& colorStop : gradient.stops()) {
+ for (auto& colorStop : canvasGradient.gradient().stops()) {
auto stop = JSON::ArrayOf<JSON::Value>::create();
stop->addItem(colorStop.offset);
stop->addItem(indexForData(serializationForCSS(colorStop.color)));
Modified: trunk/Source/WebCore/page/FrameView.cpp (264279 => 264280)
--- trunk/Source/WebCore/page/FrameView.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/page/FrameView.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -350,32 +350,27 @@
void FrameView::recalculateScrollbarOverlayStyle()
{
- ScrollbarOverlayStyle oldOverlayStyle = scrollbarOverlayStyle();
- Optional<ScrollbarOverlayStyle> clientOverlayStyle = frame().page() ? frame().page()->chrome().client().preferredScrollbarOverlayStyle() : WTF::nullopt;
- if (clientOverlayStyle) {
- if (clientOverlayStyle.value() != oldOverlayStyle)
- setScrollbarOverlayStyle(clientOverlayStyle.value());
- return;
- }
-
- ScrollbarOverlayStyle computedOverlayStyle = ScrollbarOverlayStyleDefault;
-
- Color backgroundColor = documentBackgroundColor();
- if (backgroundColor.isValid()) {
- // Reduce the background color from RGB to a lightness value
- // and determine which scrollbar style to use based on a lightness
- // heuristic.
- if (backgroundColor.lightness() <= .5f && backgroundColor.isVisible())
- computedOverlayStyle = ScrollbarOverlayStyleLight;
- else if (!backgroundColor.isVisible() && useDarkAppearance())
- computedOverlayStyle = ScrollbarOverlayStyleLight;
- }
-
- if (oldOverlayStyle != computedOverlayStyle)
- setScrollbarOverlayStyle(computedOverlayStyle);
+ auto style = [this] {
+ if (auto page = frame().page()) {
+ if (auto clientStyle = page->chrome().client().preferredScrollbarOverlayStyle())
+ return *clientStyle;
+ }
+ auto background = ""
+ if (background.isVisible()) {
+ if (background.lightness() <= .5f)
+ return ScrollbarOverlayStyleLight;
+ } else {
+ if (useDarkAppearance())
+ return ScrollbarOverlayStyleLight;
+ }
+ return ScrollbarOverlayStyleDefault;
+ }();
+ if (scrollbarOverlayStyle() != style)
+ setScrollbarOverlayStyle(style);
}
#if ENABLE(DARK_MODE_CSS)
+
void FrameView::recalculateBaseBackgroundColor()
{
bool usingDarkAppearance = useDarkAppearance();
@@ -388,6 +383,7 @@
backgroundColor = Color(Color::transparent);
updateBackgroundRecursively(backgroundColor);
}
+
#endif
void FrameView::clear()
Modified: trunk/Source/WebCore/platform/ColorChooserClient.h (264279 => 264280)
--- trunk/Source/WebCore/platform/ColorChooserClient.h 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/ColorChooserClient.h 2020-07-12 17:28:02 UTC (rev 264280)
@@ -27,17 +27,16 @@
*
*/
-#ifndef ColorChooserClient_h
-#define ColorChooserClient_h
+#pragma once
#if ENABLE(INPUT_TYPE_COLOR)
-#include "IntRect.h"
-#include <wtf/Vector.h>
+#include <wtf/Forward.h>
namespace WebCore {
class Color;
+class IntRect;
class ColorChooserClient {
public:
@@ -46,8 +45,6 @@
virtual void didChooseColor(const Color&) = 0;
virtual void didEndChooser() = 0;
virtual IntRect elementRectRelativeToRootView() const = 0;
- virtual Color currentColor() = 0;
- virtual bool shouldShowSuggestions() const = 0;
virtual Vector<Color> suggestedColors() const = 0;
};
@@ -54,5 +51,3 @@
} // namespace WebCore
#endif // ENABLE(INPUT_TYPE_COLOR)
-
-#endif // ColorChooserClient_h
Modified: trunk/Source/WebCore/platform/graphics/Gradient.cpp (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/Gradient.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/Gradient.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -36,59 +36,18 @@
namespace WebCore {
-Ref<Gradient> Gradient::create(LinearData&& data)
+Ref<Gradient> Gradient::create(Data&& data)
{
return adoptRef(*new Gradient(WTFMove(data)));
}
-Ref<Gradient> Gradient::create(RadialData&& data)
-{
- return adoptRef(*new Gradient(WTFMove(data)));
-}
-
-Ref<Gradient> Gradient::create(ConicData&& data)
-{
- return adoptRef(*new Gradient(WTFMove(data)));
-}
-
-Gradient::Gradient(LinearData&& data)
+Gradient::Gradient(Data&& data)
: m_data(WTFMove(data))
{
- platformInit();
}
-Gradient::Gradient(RadialData&& data)
- : m_data(WTFMove(data))
-{
- platformInit();
-}
-
-Gradient::Gradient(ConicData&& data)
- : m_data(WTFMove(data))
-{
- platformInit();
-}
+Gradient::~Gradient() = default;
-Gradient::~Gradient()
-{
- platformDestroy();
-}
-
-auto Gradient::type() const -> Type
-{
- return WTF::switchOn(m_data,
- [] (const LinearData&) {
- return Type::Linear;
- },
- [] (const RadialData&) {
- return Type::Radial;
- },
- [] (const ConicData&) {
- return Type::Conic;
- }
- );
-}
-
void Gradient::adjustParametersForTiledDrawing(FloatSize& size, FloatRect& srcRect, const FloatSize& spacing)
{
if (srcRect.isEmpty())
@@ -134,71 +93,38 @@
);
}
-void Gradient::addColorStop(float offset, const Color& color)
+void Gradient::addColorStop(Gradient::ColorStop&& stop)
{
- addColorStop({ offset, color });
-}
-
-void Gradient::addColorStop(const Gradient::ColorStop& stop)
-{
- m_stops.append(stop);
-
+ m_stops.append(WTFMove(stop));
m_stopsSorted = false;
-
- platformDestroy();
- invalidateHash();
+ m_cachedHash = 0;
+ stopsChanged();
}
void Gradient::setSortedColorStops(ColorStopVector&& stops)
{
m_stops = WTFMove(stops);
-
m_stopsSorted = true;
-
- platformDestroy();
- invalidateHash();
+ m_cachedHash = 0;
+ stopsChanged();
}
-static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b)
+void Gradient::sortStops() const
{
- return a.offset < b.offset;
-}
-
-void Gradient::sortStopsIfNecessary()
-{
if (m_stopsSorted)
return;
-
m_stopsSorted = true;
-
- if (!m_stops.size())
- return;
-
- std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
- invalidateHash();
+ std::stable_sort(m_stops.begin(), m_stops.end(), [] (auto& a, auto& b) {
+ return a.offset < b.offset;
+ });
}
-bool Gradient::hasAlpha() const
-{
- for (const auto& stop : m_stops) {
- if (!stop.color.isOpaque())
- return true;
- }
-
- return false;
-}
-
void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod)
{
- // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set.
- ASSERT(m_gradient == 0);
-
if (m_spreadMethod == spreadMethod)
return;
-
m_spreadMethod = spreadMethod;
-
- invalidateHash();
+ m_cachedHash = 0;
}
void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation)
@@ -205,75 +131,54 @@
{
if (m_gradientSpaceTransformation == gradientSpaceTransformation)
return;
-
m_gradientSpaceTransformation = gradientSpaceTransformation;
+ m_cachedHash = 0;
+}
- invalidateHash();
+// FIXME: Instead of these add(Hasher) functions, consider using encode functions to compute the hash.
+
+static void add(Hasher& hasher, const Color& color)
+{
+ // FIXME: We don't want to hash a hash; do better.
+ add(hasher, color.hash());
}
-unsigned Gradient::hash() const
+static void add(Hasher& hasher, const FloatPoint& point)
{
- if (m_cachedHash)
- return m_cachedHash;
+ add(hasher, point.x(), point.y());
+}
- struct {
- Type type;
- FloatPoint point0;
- FloatPoint point1;
- float startRadius;
- float endRadius;
- float aspectRatio;
- float angleRadians;
- GradientSpreadMethod spreadMethod;
- AffineTransform gradientSpaceTransformation;
- } parameters;
+static void add(Hasher& hasher, const AffineTransform& transform)
+{
+ add(hasher, transform.a(), transform.b(), transform.c(), transform.d(), transform.e(), transform.f());
+}
- // StringHasher requires that the memory it hashes be a multiple of two in size.
- COMPILE_ASSERT(!(sizeof(parameters) % 2), Gradient_parameters_size_should_be_multiple_of_two);
- COMPILE_ASSERT(!(sizeof(ColorStop) % 2), Color_stop_size_should_be_multiple_of_two);
-
- // Ensure that any padding in the struct is zero-filled, so it will not affect the hash value.
- // FIXME: This is asking for trouble, because it is a nontrivial type.
- memset(static_cast<void*>(¶meters), 0, sizeof(parameters));
-
- WTF::switchOn(m_data,
- [¶meters] (const LinearData& data) {
- parameters.point0 = data.point0;
- parameters.point1 = data.point1;
- parameters.startRadius = 0;
- parameters.endRadius = 0;
- parameters.aspectRatio = 0;
- parameters.angleRadians = 0;
- parameters.type = Type::Linear;
- },
- [¶meters] (const RadialData& data) {
- parameters.point0 = data.point0;
- parameters.point1 = data.point1;
- parameters.startRadius = data.startRadius;
- parameters.endRadius = data.endRadius;
- parameters.aspectRatio = data.aspectRatio;
- parameters.angleRadians = 0;
- parameters.type = Type::Radial;
- },
- [¶meters] (const ConicData& data) {
- parameters.point0 = data.point0;
- parameters.point1 = {0, 0};
- parameters.startRadius = 0;
- parameters.endRadius = 0;
- parameters.aspectRatio = 0;
- parameters.angleRadians = data.angleRadians;
- parameters.type = Type::Conic;
- }
- );
+static void add(Hasher& hasher, const Gradient::ColorStop& stop)
+{
+ add(hasher, stop.offset, stop.color);
+}
- parameters.spreadMethod = m_spreadMethod;
- parameters.gradientSpaceTransformation = m_gradientSpaceTransformation;
+static void add(Hasher& hasher, const Gradient::LinearData& data)
+{
+ add(hasher, data.point0, data.point1);
+}
- unsigned parametersHash = StringHasher::hashMemory(¶meters, sizeof(parameters));
- unsigned stopHash = StringHasher::hashMemory(m_stops.data(), m_stops.size() * sizeof(ColorStop));
+static void add(Hasher& hasher, const Gradient::RadialData& data)
+{
+ add(hasher, data.point0, data.point1, data.startRadius, data.endRadius, data.aspectRatio);
+}
- m_cachedHash = pairIntHash(parametersHash, stopHash);
+static void add(Hasher& hasher, const Gradient::ConicData& data)
+{
+ add(hasher, data.point0, data.angleRadians);
+}
+unsigned Gradient::hash() const
+{
+ if (!m_cachedHash) {
+ sortStops();
+ m_cachedHash = computeHash(m_data, m_spreadMethod, m_gradientSpaceTransformation, m_stops);
+ }
return m_cachedHash;
}
Modified: trunk/Source/WebCore/platform/graphics/Gradient.h (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/Gradient.h 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/Gradient.h 2020-07-12 17:28:02 UTC (rev 264280)
@@ -31,48 +31,44 @@
#include "Color.h"
#include "FloatPoint.h"
#include "GraphicsTypes.h"
-#include <wtf/EnumTraits.h>
-#include <wtf/RefCounted.h>
#include <wtf/Variant.h>
#include <wtf/Vector.h>
#if USE(CG)
+#include <wtf/RetainPtr.h>
+#endif
+
+#if USE(DIRECT2D)
+#include "COMPtr.h"
+#endif
+
+#if USE(CG)
typedef struct CGContext* CGContextRef;
typedef struct CGGradient* CGGradientRef;
-typedef CGGradientRef PlatformGradient;
-#elif USE(DIRECT2D)
+#endif
+
+#if USE(DIRECT2D)
interface ID2D1Brush;
interface ID2D1RenderTarget;
-typedef ID2D1Brush* PlatformGradient;
-#elif USE(CAIRO)
+#endif
+
+#if USE(CAIRO)
typedef struct _cairo_pattern cairo_pattern_t;
-typedef cairo_pattern_t* PlatformGradient;
-#else
-typedef void* PlatformGradient;
#endif
namespace WebCore {
-class Color;
class FloatRect;
class GraphicsContext;
class Gradient : public RefCounted<Gradient> {
public:
- // FIXME: ExtendedColor - A color stop needs a notion of color space.
struct ColorStop {
float offset { 0 };
Color color;
- ColorStop() = default;
- ColorStop(float offset, const Color& color)
- : offset(offset)
- , color(color)
- {
- }
-
- template<class Encoder> void encode(Encoder&) const;
- template<class Decoder> static Optional<ColorStop> decode(Decoder&);
+ template<typename Encoder> void encode(Encoder&) const;
+ template<typename Decoder> static Optional<ColorStop> decode(Decoder&);
};
using ColorStopVector = Vector<ColorStop, 2>;
@@ -81,8 +77,8 @@
FloatPoint point0;
FloatPoint point1;
- template<class Encoder> void encode(Encoder&) const;
- template<class Decoder> static Optional<LinearData> decode(Decoder&);
+ template<typename Encoder> void encode(Encoder&) const;
+ template<typename Decoder> static Optional<LinearData> decode(Decoder&);
};
struct RadialData {
@@ -92,37 +88,29 @@
float endRadius;
float aspectRatio; // For elliptical gradient, width / height.
- template<class Encoder> void encode(Encoder&) const;
- template<class Decoder> static Optional<RadialData> decode(Decoder&);
+ template<typename Encoder> void encode(Encoder&) const;
+ template<typename Decoder> static Optional<RadialData> decode(Decoder&);
};
-
+
struct ConicData {
FloatPoint point0;
float angleRadians;
- template<class Encoder> void encode(Encoder&) const;
- template<class Decoder> static Optional<ConicData> decode(Decoder&);
+ template<typename Encoder> void encode(Encoder&) const;
+ template<typename Decoder> static Optional<ConicData> decode(Decoder&);
};
using Data = "" RadialData, ConicData>;
- enum class Type { Linear, Radial, Conic };
+ WEBCORE_EXPORT static Ref<Gradient> create(Data&&);
- WEBCORE_EXPORT static Ref<Gradient> create(LinearData&&);
- WEBCORE_EXPORT static Ref<Gradient> create(RadialData&&);
- WEBCORE_EXPORT static Ref<Gradient> create(ConicData&&);
-
WEBCORE_EXPORT ~Gradient();
- WEBCORE_EXPORT Type type() const;
-
- bool hasAlpha() const;
bool isZeroSize() const;
const Data& data() const { return m_data; }
- WEBCORE_EXPORT void addColorStop(const ColorStop&);
- WEBCORE_EXPORT void addColorStop(float, const Color&);
+ WEBCORE_EXPORT void addColorStop(ColorStop&&);
WEBCORE_EXPORT void setSortedColorStops(ColorStopVector&&);
const ColorStopVector& stops() const { return m_stops; }
@@ -130,7 +118,6 @@
WEBCORE_EXPORT void setSpreadMethod(GradientSpreadMethod);
GradientSpreadMethod spreadMethod() const { return m_spreadMethod; }
- // CG needs to transform the gradient at draw time.
WEBCORE_EXPORT void setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation);
const AffineTransform& gradientSpaceTransform() const { return m_gradientSpaceTransformation; }
@@ -138,56 +125,56 @@
void adjustParametersForTiledDrawing(FloatSize&, FloatRect&, const FloatSize& spacing);
unsigned hash() const;
- void invalidateHash() { m_cachedHash = 0; }
+#if USE(CAIRO)
+ RefPtr<cairo_pattern_t> createPattern(float globalAlpha);
+#endif
+
#if USE(CG)
void paint(GraphicsContext&);
void paint(CGContextRef);
-#elif USE(DIRECT2D)
- PlatformGradient createPlatformGradientIfNecessary(ID2D1RenderTarget*);
-#elif USE(CAIRO)
- PlatformGradient createPlatformGradient(float globalAlpha);
#endif
- template<class Encoder> void encode(Encoder&) const;
- template<class Decoder> static Optional<Ref<Gradient>> decode(Decoder&);
+#if USE(DIRECT2D)
+ ID2D1Brush* createBrush(ID2D1RenderTarget*);
+#endif
+ template<typename Encoder> void encode(Encoder&) const;
+ template<typename Decoder> static Optional<Ref<Gradient>> decode(Decoder&);
+
private:
- Gradient(LinearData&&);
- Gradient(RadialData&&);
- Gradient(ConicData&&);
+ explicit Gradient(Data&&);
- PlatformGradient platformGradient();
- void platformInit() { m_gradient = nullptr; }
- void platformDestroy();
+ void sortStops() const;
+ void stopsChanged();
- void sortStopsIfNecessary();
-
-#if USE(DIRECT2D)
- void generateGradient(ID2D1RenderTarget*);
+#if USE(CG)
+ void createCGGradient();
#endif
Data m_data;
-
mutable ColorStopVector m_stops;
mutable bool m_stopsSorted { false };
GradientSpreadMethod m_spreadMethod { GradientSpreadMethod::Pad };
+ mutable unsigned m_cachedHash { 0 };
AffineTransform m_gradientSpaceTransformation;
- mutable unsigned m_cachedHash { 0 };
+#if USE(CG)
+ RetainPtr<CGGradientRef> m_gradient;
+#endif
- PlatformGradient m_gradient;
+#if USE(DIRECT2D)
+ COMPtr<ID2D1Brush> m_brush;
+#endif
};
-template<class Encoder>
-void Gradient::ColorStop::encode(Encoder& encoder) const
+template<typename Encoder> void Gradient::ColorStop::encode(Encoder& encoder) const
{
encoder << offset;
encoder << color;
}
-template<class Decoder>
-Optional<Gradient::ColorStop> Gradient::ColorStop::decode(Decoder& decoder)
+template<typename Decoder> Optional<Gradient::ColorStop> Gradient::ColorStop::decode(Decoder& decoder)
{
Optional<float> offset;
decoder >> offset;
@@ -202,15 +189,13 @@
return {{ *offset, *color }};
}
-template<class Encoder>
-void Gradient::LinearData::encode(Encoder& encoder) const
+template<typename Encoder> void Gradient::LinearData::encode(Encoder& encoder) const
{
encoder << point0;
encoder << point1;
}
-template<class Decoder>
-Optional<Gradient::LinearData> Gradient::LinearData::decode(Decoder& decoder)
+template<typename Decoder> Optional<Gradient::LinearData> Gradient::LinearData::decode(Decoder& decoder)
{
Optional<FloatPoint> point0;
decoder >> point0;
@@ -225,8 +210,7 @@
return {{ *point0, *point1 }};
}
-template<class Encoder>
-void Gradient::RadialData::encode(Encoder& encoder) const
+template<typename Encoder> void Gradient::RadialData::encode(Encoder& encoder) const
{
encoder << point0;
encoder << point1;
@@ -235,8 +219,7 @@
encoder << aspectRatio;
}
-template<class Decoder>
-Optional<Gradient::RadialData> Gradient::RadialData::decode(Decoder& decoder)
+template<typename Decoder> Optional<Gradient::RadialData> Gradient::RadialData::decode(Decoder& decoder)
{
Optional<FloatPoint> point0;
decoder >> point0;
@@ -266,15 +249,13 @@
return {{ *point0, *point1, *startRadius, *endRadius, *aspectRatio }};
}
-template<class Encoder>
-void Gradient::ConicData::encode(Encoder& encoder) const
+template<typename Encoder> void Gradient::ConicData::encode(Encoder& encoder) const
{
encoder << point0;
encoder << angleRadians;
}
-template<class Decoder>
-Optional<Gradient::ConicData> Gradient::ConicData::decode(Decoder& decoder)
+template<typename Decoder> Optional<Gradient::ConicData> Gradient::ConicData::decode(Decoder& decoder)
{
Optional<FloatPoint> point0;
decoder >> point0;
@@ -289,22 +270,9 @@
return {{ *point0, *angleRadians }};
}
-template<class Encoder>
-void Gradient::encode(Encoder& encoder) const
+template<typename Encoder> void Gradient::encode(Encoder& encoder) const
{
- auto type = this->type();
- encoder << type;
- switch (type) {
- case Type::Linear:
- encoder << WTF::get<Gradient::LinearData>(m_data);
- break;
- case Type::Radial:
- encoder << WTF::get<Gradient::RadialData>(m_data);
- break;
- case Type::Conic:
- encoder << WTF::get<Gradient::ConicData>(m_data);
- break;
- }
+ encoder << m_data;
encoder << m_stops;
encoder << m_stopsSorted;
encoder << m_spreadMethod;
@@ -311,71 +279,32 @@
encoder << m_gradientSpaceTransformation;
}
-template<class Decoder>
-Optional<Ref<Gradient>> Gradient::decode(Decoder& decoder)
+template<typename Decoder> Optional<Ref<Gradient>> Gradient::decode(Decoder& decoder)
{
- Optional<Gradient::Type> type;
- decoder >> type;
- if (!type)
+ Optional<Data> data;
+ decoder >> data;
+ if (!data)
return WTF::nullopt;
+ auto gradient = Gradient::create(WTFMove(*data));
- RefPtr<Gradient> gradient;
- switch (*type) {
- case Type::Linear: {
- Optional<LinearData> linearData;
- decoder >> linearData;
- if (!linearData)
- return WTF::nullopt;
-
- gradient = Gradient::create(WTFMove(*linearData));
- break;
- }
- case Type::Radial: {
- Optional<RadialData> radialData;
- decoder >> radialData;
- if (!radialData)
- return WTF::nullopt;
-
- gradient = Gradient::create(WTFMove(*radialData));
- break;
- }
- case Type::Conic: {
- Optional<ConicData> conicData;
- decoder >> conicData;
- if (!conicData)
- return WTF::nullopt;
-
- gradient = Gradient::create(WTFMove(*conicData));
- break;
- }
- }
-
- if (!gradient) {
- ASSERT_NOT_REACHED();
- return WTF::nullopt;
- }
-
Optional<ColorStopVector> stops;
decoder >> stops;
if (!stops)
return WTF::nullopt;
-
Optional<bool> stopsSorted;
decoder >> stopsSorted;
if (!stopsSorted.hasValue())
return WTF::nullopt;
-
- if (stopsSorted.value())
+ if (*stopsSorted)
gradient->setSortedColorStops(WTFMove(*stops));
else {
for (auto& stop : *stops)
- gradient->addColorStop(stop);
+ gradient->addColorStop(WTFMove(stop));
}
GradientSpreadMethod spreadMethod;
if (!decoder.decode(spreadMethod))
return WTF::nullopt;
-
gradient->setSpreadMethod(spreadMethod);
Optional<AffineTransform> gradientSpaceTransformation;
@@ -382,22 +311,9 @@
decoder >> gradientSpaceTransformation;
if (!gradientSpaceTransformation)
return WTF::nullopt;
+ gradient->setGradientSpaceTransform(WTFMove(*gradientSpaceTransformation));
- gradient->setGradientSpaceTransform(WTFMove(*gradientSpaceTransformation));
- return gradient.releaseNonNull();
+ return WTFMove(gradient);
}
} // namespace WebCore
-
-namespace WTF {
-
-template<> struct EnumTraits<WebCore::Gradient::Type> {
- using values = EnumValues<
- WebCore::Gradient::Type,
- WebCore::Gradient::Type::Linear,
- WebCore::Gradient::Type::Radial,
- WebCore::Gradient::Type::Conic
- >;
-};
-
-} // namespace WTF
Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -75,6 +75,26 @@
if (m_changeFlags.contains(GraphicsContextState::flag) && (m_state.property != state.property)) \
changeFlags.add(GraphicsContextState::flag);
+GraphicsContextState::GraphicsContextState()
+ : shouldAntialias(true)
+ , shouldSmoothFonts(true)
+ , shouldSubpixelQuantizeFonts(true)
+ , shadowsIgnoreTransforms(false)
+#if USE(CG)
+ // Core Graphics incorrectly renders shadows with radius > 8px (<rdar://problem/8103442>),
+ // but we need to preserve this buggy behavior for canvas and -webkit-box-shadow.
+ , shadowsUseLegacyRadius(false)
+#endif
+ , drawLuminanceMask(false)
+{
+}
+
+GraphicsContextState::~GraphicsContextState() = default;
+GraphicsContextState::GraphicsContextState(const GraphicsContextState&) = default;
+GraphicsContextState::GraphicsContextState(GraphicsContextState&&) = default;
+GraphicsContextState& GraphicsContextState::operator=(const GraphicsContextState&) = default;
+GraphicsContextState& GraphicsContextState::operator=(GraphicsContextState&&) = default;
+
GraphicsContextState::StateChangeFlags GraphicsContextStateChange::changesFromState(const GraphicsContextState& state) const
{
GraphicsContextState::StateChangeFlags changeFlags;
Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h 2020-07-12 17:28:02 UTC (rev 264280)
@@ -29,7 +29,6 @@
#include "DashArray.h"
#include "FloatRect.h"
#include "FontCascade.h"
-#include "Gradient.h"
#include "GraphicsTypes.h"
#include "Image.h"
#include "ImageOrientation.h"
@@ -98,6 +97,10 @@
class TextRun;
class TransformationMatrix;
+namespace DisplayList {
+class Recorder;
+}
+
enum class TextDrawingMode : uint8_t {
Fill = 1 << 0,
Stroke = 1 << 1,
@@ -153,25 +156,16 @@
return {{ *mode, *shouldUseDarkAppearance }};
}
-namespace DisplayList {
-class Recorder;
-}
-
struct GraphicsContextState {
- GraphicsContextState()
- : shouldAntialias(true)
- , shouldSmoothFonts(true)
- , shouldSubpixelQuantizeFonts(true)
- , shadowsIgnoreTransforms(false)
-#if USE(CG)
- // Core Graphics incorrectly renders shadows with radius > 8px (<rdar://problem/8103442>),
- // but we need to preserve this buggy behavior for canvas and -webkit-box-shadow.
- , shadowsUseLegacyRadius(false)
-#endif
- , drawLuminanceMask(false)
- {
- }
+ WEBCORE_EXPORT GraphicsContextState();
+ WEBCORE_EXPORT ~GraphicsContextState();
+ GraphicsContextState(const GraphicsContextState&);
+ GraphicsContextState(GraphicsContextState&&);
+
+ GraphicsContextState& operator=(const GraphicsContextState&);
+ GraphicsContextState& operator=(GraphicsContextState&&);
+
enum Change : uint32_t {
StrokeGradientChange = 1 << 0,
StrokePatternChange = 1 << 1,
@@ -197,7 +191,7 @@
UseDarkAppearanceChange = 1 << 20,
#endif
};
- typedef OptionSet<Change> StateChangeFlags;
+ using StateChangeFlags = OptionSet<Change>;
RefPtr<Gradient> strokeGradient;
RefPtr<Pattern> strokePattern;
@@ -308,7 +302,7 @@
Pattern* strokePattern() const { return m_state.strokePattern.get(); }
void setStrokeGradient(Ref<Gradient>&&);
- RefPtr<Gradient> strokeGradient() const { return m_state.strokeGradient; }
+ Gradient* strokeGradient() const { return m_state.strokeGradient.get(); }
void setFillRule(WindRule);
WindRule fillRule() const { return m_state.fillRule; }
@@ -320,7 +314,7 @@
Pattern* fillPattern() const { return m_state.fillPattern.get(); }
WEBCORE_EXPORT void setFillGradient(Ref<Gradient>&&);
- RefPtr<Gradient> fillGradient() const { return m_state.fillGradient; }
+ Gradient* fillGradient() const { return m_state.fillGradient.get(); }
void setShadowsIgnoreTransforms(bool);
bool shadowsIgnoreTransforms() const { return m_state.shadowsIgnoreTransforms; }
Modified: trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -40,6 +40,7 @@
#include "DrawErrorUnderline.h"
#include "FloatConversion.h"
#include "FloatRect.h"
+#include "Gradient.h"
#include "GraphicsContext.h"
#include "GraphicsContextPlatformPrivateCairo.h"
#include "Image.h"
@@ -568,9 +569,9 @@
pattern.repeatX = state.fillPattern->repeatX();
pattern.repeatY = state.fillPattern->repeatY();
} else if (state.fillGradient) {
- gradient.base = adoptRef(state.fillGradient->createPlatformGradient(1));
+ gradient.base = state.fillGradient->createPattern(1);
if (state.alpha != 1)
- gradient.alphaAdjusted = adoptRef(state.fillGradient->createPlatformGradient(state.alpha));
+ gradient.alphaAdjusted = state.fillGradient->createPattern(state.alpha);
} else
color = state.fillColor;
}
@@ -581,9 +582,9 @@
if (state.strokePattern)
pattern = adoptRef(state.strokePattern->createPlatformPattern(AffineTransform()));
else if (state.strokeGradient) {
- gradient.base = adoptRef(state.strokeGradient->createPlatformGradient(1));
+ gradient.base = state.strokeGradient->createPattern(1);
if (state.alpha != 1)
- gradient.alphaAdjusted = adoptRef(state.strokeGradient->createPlatformGradient(state.alpha));
+ gradient.alphaAdjusted = state.strokeGradient->createPattern(state.alpha);
} else
color = state.strokeColor;
}
Modified: trunk/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -30,8 +30,10 @@
#if USE(CAIRO)
+#include "AnimationUtilities.h"
#include "CairoOperations.h"
#include "CairoUtilities.h"
+#include "ColorBlending.h"
#include "GraphicsContext.h"
#include "PlatformContextCairo.h"
#include <wtf/MathExtras.h>
@@ -38,7 +40,7 @@
namespace WebCore {
-void Gradient::platformDestroy()
+void Gradient::stopsChanged()
{
}
@@ -132,66 +134,54 @@
cairo_mesh_pattern_end_patch(gradient);
}
-static Gradient::ColorStop interpolateColorStop(Gradient::ColorStop from, Gradient::ColorStop to)
+static Gradient::ColorStop interpolateColorStop(const Gradient::ColorStop& from, const Gradient::ColorStop& to)
{
- auto [r1, g1, b1, a1] = from.color.toSRGBALossy<float>();
- auto [r2, g2, b2, a2] = to.color.toSRGBALossy<float>();
-
- float offset = from.offset + (to.offset - from.offset) * 0.5f;
- float r = r1 + (r2 - r1) * 0.5f;
- float g = g1 + (g2 - g1) * 0.5f;
- float b = b1 + (b2 - b1) * 0.5f;
- float a = a1 + (a2 - a1) * 0.5f;
-
- return Gradient::ColorStop(offset, makeSimpleColor(SRGBA { r, g, b, a }));
+ return { blend(from.offset, to.offset, 0.5), blend(from.color, to.color, 0.5) };
}
-static cairo_pattern_t* createConic(float xo, float yo, float r, float angleRadians,
+static RefPtr<cairo_pattern_t> createConic(float xo, float yo, float r, float angleRadians,
Gradient::ColorStopVector stops, float globalAlpha)
{
- cairo_pattern_t* gradient = cairo_pattern_create_mesh();
- Gradient::ColorStop from, to;
-
- /* It's not possible to paint an entire circle with a single Bezier curve.
- * To have a good approximation to a circle it's necessary to use at least
- * four Bezier curves. So three additional stops with interpolated colors
- * are added to force painting of four Bezier curves. */
+ // It's not possible to paint an entire circle with a single Bezier curve.
+ // To have a good approximation to a circle it's necessary to use at least
+ // four Bezier curves. So three additional stops with interpolated colors
+ // are added to force painting of four Bezier curves.
if (stops.size() == 2) {
- Gradient::ColorStop first = stops.at(0);
- Gradient::ColorStop last = stops.at(1);
- Gradient::ColorStop third = interpolateColorStop(first, last);
- Gradient::ColorStop second = interpolateColorStop(first, third);
- Gradient::ColorStop fourth = interpolateColorStop(third, last);
- stops.insert(1, fourth);
- stops.insert(1, third);
- stops.insert(1, second);
+ auto third = interpolateColorStop(stops.first(), stops.last());
+ auto second = interpolateColorStop(stops.first(), third);
+ auto fourth = interpolateColorStop(third, stops.last());
+ stops.insert(1, WTFMove(fourth));
+ stops.insert(1, WTFMove(third));
+ stops.insert(1, WTFMove(second));
}
- // Add extra color stop at the beginning if first element offset is not zero.
- if (stops.at(0).offset > 0)
- stops.insert(0, Gradient::ColorStop(0, stops.at(0).color));
- // Add extra color stop at the end if last element offset is not zero.
- if (stops.at(stops.size() - 1).offset < 1)
- stops.append(Gradient::ColorStop(1, stops.at(stops.size() - 1).color));
+ if (stops.first().offset > 0.0f)
+ stops.insert(0, Gradient::ColorStop { 0.0f, stops.first().color });
+ if (stops.last().offset < 1.0f)
+ stops.append({ 1.0f, stops.last().color });
- for (size_t i = 0; i < stops.size() - 1; i++) {
- from = stops.at(i), to = stops.at(i + 1);
- addConicSector(gradient, xo, yo, r, angleRadians, from, to, globalAlpha);
- }
-
+ auto gradient = adoptRef(cairo_pattern_create_mesh());
+ for (size_t i = 0; i < stops.size() - 1; i++)
+ addConicSector(gradient.get(), xo, yo, r, angleRadians, stops[i], stops[i + 1], globalAlpha);
return gradient;
}
-cairo_pattern_t* Gradient::createPlatformGradient(float globalAlpha)
+RefPtr<cairo_pattern_t> Gradient::createPattern(float globalAlpha)
{
- cairo_pattern_t* gradient = WTF::switchOn(m_data,
- [&] (const LinearData& data) -> cairo_pattern_t* {
- return cairo_pattern_create_linear(data.point0.x(), data.point0.y(), data.point1.x(), data.point1.y());
+ auto gradient = WTF::switchOn(m_data,
+ [&] (const LinearData& data) {
+ auto gradient = adoptRef(cairo_pattern_create_linear(data.point0.x(), data.point0.y(), data.point1.x(), data.point1.y()));
+ for (auto& stop : stops())
+ addColorStopRGBA(gradient.get(), stop, globalAlpha);
+ return gradient;
},
- [&] (const RadialData& data) -> cairo_pattern_t* {
- return cairo_pattern_create_radial(data.point0.x(), data.point0.y(), data.startRadius, data.point1.x(), data.point1.y(), data.endRadius);
+ [&] (const RadialData& data) {
+ auto gradient = adoptRef(cairo_pattern_create_radial(data.point0.x(), data.point0.y(), data.startRadius, data.point1.x(), data.point1.y(), data.endRadius));
+ for (auto& stop : stops())
+ addColorStopRGBA(gradient.get(), stop, globalAlpha);
+ return gradient;
},
- [&] (const ConicData& data) -> cairo_pattern_t* {
+ [&] (const ConicData& data) {
// FIXME: data passed for a Conic gradient doesn't contain a radius. That's apparently correct because the W3C spec
// (https://www.w3.org/TR/css-images-4/#conic-gradients) states a conic gradient is only defined by its position and angle.
// Thus, here I give the radius an extremely large value. The resulting gradient will be later clipped by fillRect.
@@ -201,27 +191,21 @@
}
);
- if (type() != Type::Conic) {
- for (const auto& stop : stops()) {
- addColorStopRGBA(gradient, stop, globalAlpha);
- }
- }
-
switch (m_spreadMethod) {
case GradientSpreadMethod::Pad:
- cairo_pattern_set_extend(gradient, CAIRO_EXTEND_PAD);
+ cairo_pattern_set_extend(gradient.get(), CAIRO_EXTEND_PAD);
break;
case GradientSpreadMethod::Reflect:
- cairo_pattern_set_extend(gradient, CAIRO_EXTEND_REFLECT);
+ cairo_pattern_set_extend(gradient.get(), CAIRO_EXTEND_REFLECT);
break;
case GradientSpreadMethod::Repeat:
- cairo_pattern_set_extend(gradient, CAIRO_EXTEND_REPEAT);
+ cairo_pattern_set_extend(gradient.get(), CAIRO_EXTEND_REPEAT);
break;
}
cairo_matrix_t matrix = toCairoMatrix(m_gradientSpaceTransformation);
cairo_matrix_invert(&matrix);
- cairo_pattern_set_matrix(gradient, &matrix);
+ cairo_pattern_set_matrix(gradient.get(), &matrix);
return gradient;
}
@@ -228,8 +212,8 @@
void Gradient::fill(GraphicsContext& context, const FloatRect& rect)
{
- RefPtr<cairo_pattern_t> platformGradient = adoptRef(createPlatformGradient(1.0));
- if (!platformGradient)
+ auto pattern = createPattern(1.0);
+ if (!pattern)
return;
ASSERT(context.hasPlatformContext());
@@ -236,7 +220,7 @@
auto& platformContext = *context.platformContext();
Cairo::save(platformContext);
- Cairo::fillRect(platformContext, rect, platformGradient.get());
+ Cairo::fillRect(platformContext, rect, pattern.get());
Cairo::restore(platformContext);
}
Modified: trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextImplCairo.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -33,11 +33,11 @@
#include "FloatRoundedRect.h"
#include "Font.h"
#include "GlyphBuffer.h"
+#include "Gradient.h"
#include "GraphicsContextPlatformPrivateCairo.h"
#include "ImageBuffer.h"
#include "IntRect.h"
-
namespace WebCore {
GraphicsContext::GraphicsContextImplFactory GraphicsContextImplCairo::createFactory(PlatformContextCairo& platformContext)
@@ -154,12 +154,12 @@
void GraphicsContextImplCairo::fillRect(const FloatRect& rect, Gradient& gradient)
{
- RefPtr<cairo_pattern_t> platformGradient = adoptRef(gradient.createPlatformGradient(1.0));
- if (!platformGradient)
+ auto pattern = gradient.createPattern(1.0);
+ if (!pattern)
return;
Cairo::save(m_platformContext);
- Cairo::fillRect(m_platformContext, rect, platformGradient.get());
+ Cairo::fillRect(m_platformContext, rect, pattern.get());
Cairo::restore(m_platformContext);
}
Modified: trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -35,19 +35,15 @@
namespace WebCore {
-void Gradient::platformDestroy()
+void Gradient::stopsChanged()
{
- CGGradientRelease(m_gradient);
m_gradient = nullptr;
}
-CGGradientRef Gradient::platformGradient()
+void Gradient::createCGGradient()
{
- if (m_gradient)
- return m_gradient;
+ sortStops();
- sortStopsIfNecessary();
-
auto colorsArray = adoptCF(CFArrayCreateMutable(0, m_stops.size(), &kCFTypeArrayCallBacks));
unsigned numStops = m_stops.size();
@@ -82,11 +78,9 @@
}
if (hasExtendedColors)
- m_gradient = CGGradientCreateWithColors(extendedSRGBColorSpaceRef(), colorsArray.get(), locations.data());
+ m_gradient = adoptCF(CGGradientCreateWithColors(extendedSRGBColorSpaceRef(), colorsArray.get(), locations.data()));
else
- m_gradient = CGGradientCreateWithColorComponents(sRGBColorSpaceRef(), colorComponents.data(), locations.data(), numStops);
-
- return m_gradient;
+ m_gradient = adoptCF(CGGradientCreateWithColorComponents(sRGBColorSpaceRef(), colorComponents.data(), locations.data(), numStops));
}
void Gradient::fill(GraphicsContext& context, const FloatRect& rect)
@@ -103,8 +97,10 @@
void Gradient::paint(CGContextRef platformContext)
{
CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
- CGGradientRef gradient = platformGradient();
+ if (!m_gradient)
+ createCGGradient();
+
WTF::switchOn(m_data,
[&] (const LinearData& data) {
switch (m_spreadMethod) {
@@ -146,7 +142,7 @@
CGPoint left = CGPointMake(flip ? start + width : start, boundingBox.origin.y);
CGPoint right = CGPointMake(flip ? start : start + width, boundingBox.origin.y);
- CGContextDrawLinearGradient(platformContext, gradient, left, right, extendOptions);
+ CGContextDrawLinearGradient(platformContext, m_gradient.get(), left, right, extendOptions);
if (m_spreadMethod == GradientSpreadMethod::Reflect)
flip = !flip;
@@ -158,7 +154,7 @@
FALLTHROUGH;
}
case GradientSpreadMethod::Pad:
- CGContextDrawLinearGradient(platformContext, gradient, data.point0, data.point1, extendOptions);
+ CGContextDrawLinearGradient(platformContext, m_gradient.get(), data.point0, data.point1, extendOptions);
}
},
[&] (const RadialData& data) {
@@ -173,7 +169,7 @@
CGContextTranslateCTM(platformContext, -data.point0.x(), -data.point0.y());
}
- CGContextDrawRadialGradient(platformContext, gradient, data.point0, data.startRadius, data.point1, data.endRadius, extendOptions);
+ CGContextDrawRadialGradient(platformContext, m_gradient.get(), data.point0, data.startRadius, data.point1, data.endRadius, extendOptions);
if (needScaling)
CGContextRestoreGState(platformContext);
@@ -186,7 +182,7 @@
CGContextTranslateCTM(platformContext, data.point0.x(), data.point0.y());
CGContextRotateCTM(platformContext, (CGFloat)-M_PI_2);
CGContextTranslateCTM(platformContext, -data.point0.x(), -data.point0.y());
- CGContextDrawConicGradient(platformContext, platformGradient(), data.point0, data.angleRadians);
+ CGContextDrawConicGradient(platformContext, m_gradient.get(), data.point0, data.angleRadians);
CGContextRestoreGState(platformContext);
#else
UNUSED_PARAM(data);
Modified: trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -32,6 +32,7 @@
#include "AffineTransform.h"
#include "DisplayListRecorder.h"
#include "FloatConversion.h"
+#include "Gradient.h"
#include "GraphicsContextPlatformPrivateCG.h"
#include "ImageBuffer.h"
#include "ImageOrientation.h"
Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h 2020-07-12 17:28:02 UTC (rev 264280)
@@ -27,15 +27,14 @@
#include "AlphaPremultiplication.h"
#include "DisplayList.h"
-#include "FloatPoint.h"
#include "FloatRoundedRect.h"
#include "Font.h"
#include "GlyphBuffer.h"
+#include "Gradient.h"
#include "Image.h"
#include "ImageData.h"
#include "Pattern.h"
#include "SharedBuffer.h"
-#include <wtf/RefCounted.h>
#include <wtf/TypeCasts.h>
namespace WTF {
Modified: trunk/Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/nicosia/cairo/NicosiaCairoOperationRecorder.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -31,6 +31,7 @@
#include "CairoOperations.h"
#include "FloatRoundedRect.h"
+#include "Gradient.h"
#include "ImageBuffer.h"
#include "NicosiaPaintingOperationReplayCairo.h"
#include <type_traits>
@@ -291,7 +292,7 @@
}
};
- append(createCommand<FillRect>(rect, adoptRef(gradient.createPlatformGradient(1.0))));
+ append(createCommand<FillRect>(rect, gradient.createPattern(1.0)));
}
void CairoOperationRecorder::fillRect(const FloatRect& rect, const Color& color, CompositeOperator compositeOperator, BlendMode blendMode)
Modified: trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.cpp (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/win/Direct2DOperations.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -301,7 +301,7 @@
AffineTransform userToBaseCTM; // FIXME: This isn't really needed on Windows
brush = state.fillPattern->createPlatformPattern(context, state.alpha, userToBaseCTM);
} else if (state.fillGradient && !state.fillGradient->stops().isEmpty())
- brush = state.fillGradient->createPlatformGradientIfNecessary(platformContext.renderTarget());
+ brush = state.fillGradient->createBrush(platformContext.renderTarget());
else
brush = platformContext.brushWithColor(color);
}
@@ -318,7 +318,7 @@
AffineTransform userToBaseCTM; // FIXME: This isn't really needed on Windows
brush = state.strokePattern->createPlatformPattern(context, state.alpha, userToBaseCTM);
} else if (state.strokeGradient)
- brush = state.strokeGradient->createPlatformGradientIfNecessary(platformContext.renderTarget());
+ brush = state.strokeGradient->createBrush(platformContext.renderTarget());
else
brush = platformContext.brushWithColor(color);
}
Modified: trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -31,31 +31,16 @@
#include "PlatformContextDirect2D.h"
#include <d2d1.h>
#include <wtf/MathExtras.h>
-#include <wtf/RetainPtr.h>
#define GRADIENT_DRAWING 3
namespace WebCore {
-void Gradient::platformDestroy()
+void Gradient::stopsChanged()
{
- if (m_gradient)
- m_gradient->Release();
- m_gradient = nullptr;
+ m_brush = nullptr;
}
-ID2D1Brush* Gradient::platformGradient()
-{
- ASSERT(m_gradient);
- return m_gradient;
-}
-
-ID2D1Brush* Gradient::createPlatformGradientIfNecessary(ID2D1RenderTarget* context)
-{
- generateGradient(context);
- return m_gradient;
-}
-
static bool circleIsEntirelyContained(const FloatPoint& centerA, float radiusA, const FloatPoint& centerB, float radiusB)
{
double deltaX = centerB.x() - centerA.x();
@@ -65,15 +50,16 @@
return deltaX * deltaX + deltaY * deltaY < deltaRadius * deltaRadius && radiusA < radiusB;
}
-void Gradient::generateGradient(ID2D1RenderTarget* renderTarget)
+ID2D1Brush* Gradient::createBrush(ID2D1RenderTarget* renderTarget)
{
- sortStopsIfNecessary();
+ sortStops();
Vector<D2D1_GRADIENT_STOP> gradientStops;
- // FIXME: Add support for ExtendedColor.
- for (auto stop : m_stops) {
+ gradientStops.reserveInitialCapacity(m_stops.size());
+ for (auto& stop : m_stops) {
+ // FIXME: Add support for non-sRGBA color spaces.
auto [r, g, b, a] stop.color.toSRGBALossy<float>();
- gradientStops.append(D2D1::GradientStop(stop.offset, D2D1::ColorF(r, g, b, a)));
+ gradientStops.gradientStops.uncheckedAppend(D2D1::GradientStop(stop.offset, D2D1::ColorF(r, g, b, a)));
}
WTF::switchOn(m_data,
@@ -122,11 +108,6 @@
HRESULT hr = renderTarget->CreateGradientStopCollection(gradientStops.data(), gradientStops.size(), &gradientStopCollection);
RELEASE_ASSERT(SUCCEEDED(hr));
- if (m_gradient) {
- m_gradient->Release();
- m_gradient = nullptr;
- }
-
WTF::switchOn(m_data,
[&] (const LinearData& data) {
ID2D1LinearGradientBrush* linearGradient = nullptr;
@@ -135,7 +116,7 @@
D2D1::BrushProperties(), gradientStopCollection.get(),
&linearGradient);
RELEASE_ASSERT(SUCCEEDED(hr));
- m_gradient = linearGradient;
+ m_brush = adoptCOM(linearGradient);
},
[&] (const RadialData& data) {
FloatSize offset;
@@ -154,14 +135,15 @@
D2D1::BrushProperties(), gradientStopCollection.get(),
&radialGradient);
RELEASE_ASSERT(SUCCEEDED(hr));
- m_gradient = radialGradient;
+ m_brush = adoptCOM(radialGradient);
},
[&] (const ConicData&) {
// FIXME: implement conic gradient rendering.
+ m_brush = nullptr;
}
);
- hash();
+ return m_brush.get();
}
void Gradient::fill(GraphicsContext& context, const FloatRect& rect)
@@ -170,8 +152,9 @@
WTF::switchOn(m_data,
[&] (const LinearData& data) {
- if (!m_cachedHash || !m_gradient)
- generateGradient(d2dContext);
+ // FIXME: If we have a brush, why can we re-use it? What guarantees it's right for this context?
+ if (!m_brush)
+ createBrush(d2dContext);
#if ASSERT_ENABLED
d2dContext->SetTags(GRADIENT_DRAWING, __LINE__);
@@ -178,7 +161,7 @@
#endif
const D2D1_RECT_F d2dRect = rect;
- d2dContext->FillRectangle(&d2dRect, m_gradient);
+ d2dContext->FillRectangle(&d2dRect, m_brush.get());
},
[&] (const RadialData& data) {
bool needScaling = data.aspectRatio != 1;
@@ -199,8 +182,9 @@
d2dContext->SetTransform(ctm);
}
- if (!m_cachedHash || !m_gradient)
- generateGradient(d2dContext);
+ // FIXME: If we have a brush, why can we re-use it? What guarantees it's right for this context?
+ if (!m_brush)
+ createBrush(d2dContext);
#if ASSERT_ENABLED
d2dContext->SetTags(GRADIENT_DRAWING, __LINE__);
@@ -207,7 +191,7 @@
#endif
const D2D1_RECT_F d2dRect = rect;
- d2dContext->FillRectangle(&d2dRect, m_gradient);
+ d2dContext->FillRectangle(&d2dRect, m_brush.get());
if (needScaling)
context.restore();
Modified: trunk/Source/WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp (264279 => 264280)
--- trunk/Source/WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/graphics/win/GraphicsContextImplDirect2D.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -155,11 +155,11 @@
void GraphicsContextImplDirect2D::fillRect(const FloatRect& rect, Gradient& gradient)
{
- COMPtr<ID2D1Brush> platformGradient = gradient.createPlatformGradientIfNecessary(m_platformContext.renderTarget());
- if (!platformGradient)
+ auto brush = gradient.createBrush(m_platformContext.renderTarget());
+ if (!brush)
return;
- Direct2D::fillRectWithGradient(m_platformContext, rect, platformGradient.get());
+ Direct2D::fillRectWithGradient(m_platformContext, rect, brush.get());
}
void GraphicsContextImplDirect2D::fillRect(const FloatRect& rect, const Color& color, CompositeOperator compositeOperator, BlendMode blendMode)
Modified: trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm (264279 => 264280)
--- trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm 2020-07-12 17:28:02 UTC (rev 264280)
@@ -28,7 +28,7 @@
#if ENABLE(SMOOTH_SCROLLING)
-#import "FloatPoint.h"
+#import "Gradient.h"
#import "GraphicsLayer.h"
#import "Logging.h"
#import "NSScrollerImpDetails.h"
Modified: trunk/Source/WebCore/rendering/RenderThemeIOS.mm (264279 => 264280)
--- trunk/Source/WebCore/rendering/RenderThemeIOS.mm 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/rendering/RenderThemeIOS.mm 2020-07-12 17:28:02 UTC (rev 264280)
@@ -900,7 +900,7 @@
return true;
const int progressBarHeight = 9;
- const float verticalOffset = (rect.height() - progressBarHeight) / 2.0;
+ const float verticalOffset = (rect.height() - progressBarHeight) / 2.0f;
GraphicsContextStateSaver stateSaver(paintInfo.context());
if (rect.width() < 10 || rect.height() < 9) {
@@ -912,21 +912,21 @@
// 1) Draw the progress bar track.
// 1.1) Draw the white background with grey gradient border.
GraphicsContext& context = paintInfo.context();
- context.setStrokeThickness(0.68);
+ context.setStrokeThickness(0.68f);
context.setStrokeStyle(SolidStroke);
const float verticalRenderingPosition = rect.y() + verticalOffset;
auto strokeGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) });
- strokeGradient->addColorStop(0.0, makeSimpleColor(141, 141, 141));
- strokeGradient->addColorStop(0.45, makeSimpleColor(238, 238, 238));
- strokeGradient->addColorStop(0.55, makeSimpleColor(238, 238, 238));
- strokeGradient->addColorStop(1.0, makeSimpleColor(141, 141, 141));
+ strokeGradient->addColorStop({ 0.0f, makeSimpleColor(141, 141, 141) });
+ strokeGradient->addColorStop({ 0.45f, makeSimpleColor(238, 238, 238) });
+ strokeGradient->addColorStop({ 0.55f, makeSimpleColor(238, 238, 238) });
+ strokeGradient->addColorStop({ 1.0f, makeSimpleColor(141, 141, 141) });
context.setStrokeGradient(WTFMove(strokeGradient));
context.setFillColor(Color::black);
Path trackPath;
- FloatRect trackRect(rect.x() + 0.25, verticalRenderingPosition + 0.25, rect.width() - 0.5, progressBarHeight - 0.5);
+ FloatRect trackRect(rect.x() + 0.25f, verticalRenderingPosition + 0.25f, rect.width() - 0.5f, progressBarHeight - 0.5f);
FloatSize roundedCornerRadius(5, 4);
trackPath.addRoundedRect(trackRect, roundedCornerRadius);
context.drawPath(trackPath);
@@ -936,9 +936,9 @@
paintInfo.context().clipRoundedRect(FloatRoundedRect(border, roundedCornerRadius, roundedCornerRadius, roundedCornerRadius, roundedCornerRadius));
float upperGradientHeight = progressBarHeight / 2.;
- auto upperGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5), FloatPoint(rect.x(), verticalRenderingPosition + upperGradientHeight - 1.5) });
- upperGradient->addColorStop(0.0, makeSimpleColor(133, 133, 133, 188));
- upperGradient->addColorStop(1.0, makeSimpleColor(18, 18, 18, 51));
+ auto upperGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5f), FloatPoint(rect.x(), verticalRenderingPosition + upperGradientHeight - 1.5) });
+ upperGradient->addColorStop({ 0.0f, makeSimpleColor(133, 133, 133, 188) });
+ upperGradient->addColorStop({ 1.0f, makeSimpleColor(18, 18, 18, 51) });
context.setFillGradient(WTFMove(upperGradient));
context.fillRect(FloatRect(rect.x(), verticalRenderingPosition, rect.width(), upperGradientHeight));
@@ -947,20 +947,20 @@
if (renderProgress.isDeterminate()) {
// 2) Draw the progress bar.
double position = clampTo(renderProgress.position(), 0.0, 1.0);
- double barWidth = position * rect.width();
- auto barGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) });
- barGradient->addColorStop(0.0, makeSimpleColor(195, 217, 247));
- barGradient->addColorStop(0.45, makeSimpleColor(118, 164, 228));
- barGradient->addColorStop(0.49, makeSimpleColor(118, 164, 228));
- barGradient->addColorStop(0.51, makeSimpleColor(36, 114, 210));
- barGradient->addColorStop(0.55, makeSimpleColor(36, 114, 210));
- barGradient->addColorStop(1.0, makeSimpleColor(57, 142, 244));
+ float barWidth = position * rect.width();
+ auto barGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5f), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) });
+ barGradient->addColorStop({ 0.0f, makeSimpleColor(195, 217, 247) });
+ barGradient->addColorStop({ 0.45f, makeSimpleColor(118, 164, 228) });
+ barGradient->addColorStop({ 0.49f, makeSimpleColor(118, 164, 228) });
+ barGradient->addColorStop({ 0.51f, makeSimpleColor(36, 114, 210) });
+ barGradient->addColorStop({ 0.55f, makeSimpleColor(36, 114, 210) });
+ barGradient->addColorStop({ 1.0f, makeSimpleColor(57, 142, 244) });
context.setFillGradient(WTFMove(barGradient));
auto barStrokeGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) });
- barStrokeGradient->addColorStop(0.0, makeSimpleColor(95, 107, 183));
- barStrokeGradient->addColorStop(0.5, makeSimpleColor(66, 106, 174, 240));
- barStrokeGradient->addColorStop(1.0, makeSimpleColor(38, 104, 166));
+ barStrokeGradient->addColorStop({ 0.0f, makeSimpleColor(95, 107, 183) });
+ barStrokeGradient->addColorStop({ 0.5f, makeSimpleColor(66, 106, 174, 240) });
+ barStrokeGradient->addColorStop({ 1.0f, makeSimpleColor(38, 104, 166) });
context.setStrokeGradient(WTFMove(barStrokeGradient));
Path barPath;
@@ -967,7 +967,7 @@
int left = rect.x();
if (!renderProgress.style().isLeftToRightDirection())
left = rect.maxX() - barWidth;
- FloatRect barRect(left + 0.25, verticalRenderingPosition + 0.25, std::max(barWidth - 0.5, 0.0), progressBarHeight - 0.5);
+ FloatRect barRect(left + 0.25f, verticalRenderingPosition + 0.25f, std::max(barWidth - 0.5f, 0.0f), progressBarHeight - 0.5f);
barPath.addRoundedRect(barRect, roundedCornerRadius);
context.drawPath(barPath);
}
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp (264279 => 264280)
--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -234,12 +234,10 @@
void RenderSVGResourceGradient::addStops(GradientData* gradientData, const Vector<Gradient::ColorStop>& stops, const RenderStyle& style) const
{
+ ASSERT(gradientData);
ASSERT(gradientData->gradient);
-
- for (Gradient::ColorStop stop : stops) {
- stop.color = style.colorByApplyingColorFilter(stop.color);
- gradientData->gradient->addColorStop(stop);
- }
+ for (auto& stop : stops)
+ gradientData->gradient->addColorStop({ stop.offset, style.colorByApplyingColorFilter(stop.color) });
}
GradientSpreadMethod RenderSVGResourceGradient::platformSpreadMethodFromSVGType(SVGSpreadMethodType method) const
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h (264279 => 264280)
--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h 2020-07-12 17:28:02 UTC (rev 264280)
@@ -21,7 +21,6 @@
#pragma once
-#include "Gradient.h"
#include "ImageBuffer.h"
#include "RenderSVGResourceContainer.h"
#include "SVGGradientElement.h"
Modified: trunk/Source/WebCore/svg/SVGGradientElement.cpp (264279 => 264280)
--- trunk/Source/WebCore/svg/SVGGradientElement.cpp 2020-07-12 11:25:21 UTC (rev 264279)
+++ trunk/Source/WebCore/svg/SVGGradientElement.cpp 2020-07-12 17:28:02 UTC (rev 264280)
@@ -102,18 +102,11 @@
{
Vector<Gradient::ColorStop> stops;
float previousOffset = 0.0f;
-
for (auto& stop : childrenOfType<SVGStopElement>(*this)) {
- const Color& color = stop.stopColorIncludingOpacity();
-
- // Figure out right monotonic offset.
- float offset = stop.offset();
- offset = std::min(std::max(previousOffset, offset), 1.0f);
- previousOffset = offset;
-
- stops.append(Gradient::ColorStop(offset, color));
+ auto monotonicallyIncreasingOffset = std::clamp(stop.offset(), previousOffset, 1.0f);
+ previousOffset = monotonicallyIncreasingOffset;
+ stops.append({ monotonicallyIncreasingOffset, stop.stopColorIncludingOpacity() });
}
-
return stops;
}