Diff
Modified: trunk/Source/WebCore/ChangeLog (225035 => 225036)
--- trunk/Source/WebCore/ChangeLog 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/ChangeLog 2017-11-19 23:06:03 UTC (rev 225036)
@@ -1,3 +1,155 @@
+2017-11-19 Sam Weinig <[email protected]>
+
+ Clean up gradient code in preparation for conic gradients
+ https://bugs.webkit.org/show_bug.cgi?id=179595
+
+ Reviewed by Darin Adler.
+
+ - Switches Gradient to use a Varient with type specific data structs and makes the
+ points / radii immutable.
+ - Replaces CSSGradientValue::addStops with template function CSSGradientValue::computeStops
+ which dispatches to a helper adoptor struct which is passed in for gradient type specific
+ values, rather than switching on type in the function itself. In addition, the function no
+ longer mutates a Gradient, but rather mutates type specific the data struct (e.g. Linear or
+ Radial for now).
+
+ * css/CSSGradientValue.cpp:
+ (WebCore::LinearGradientAdaptor::LinearGradientAdaptor):
+ (WebCore::RadialGradientAdaptor::RadialGradientAdaptor):
+
+ Add helper structs for the now templatized CSSGradientValue::computeStops that
+ implement type specific functionality.
+
+ (WebCore::CSSGradientValue::computeStops):
+
+ Renamed from addStops. Now takes a GradientAdaptor wrapper which abstracts out
+ the gradient type specific functionlity.
+
+ (WebCore::CSSLinearGradientValue::createGradient):
+ (WebCore::CSSRadialGradientValue::createGradient):
+ (WebCore::CSSConicGradientValue::createGradient):
+
+ Update to call computeStops and use new Gradient create function.
+
+ * css/CSSGradientValue.h:
+
+ Update for new signature for computeStops.
+
+ * html/canvas/CanvasGradient.cpp:
+ (WebCore::CanvasGradient::CanvasGradient):
+
+ Update to use new Gradient create function.
+
+ * inspector/InspectorCanvas.cpp:
+ (WebCore::InspectorCanvas::buildArrayForCanvasGradient):
+
+ Update to get gradient point / radii information from the data accessor.
+
+ * platform/graphics/Gradient.cpp:
+ (WebCore::Gradient::Gradient):
+
+ Update constructors to the new data structs.
+
+ (WebCore::Gradient::type const):
+
+ Add helper to get the type of the varient, need for inspector code.
+
+ (WebCore::Gradient::adjustParametersForTiledDrawing):
+ (WebCore::Gradient::isZeroSize const):
+ (WebCore::Gradient::hash const):
+
+ Update to switch on the underlying variant to get data values.
+
+ (WebCore::Gradient::addColorStop):
+
+ Simplify by having one addColorStop call the other.
+
+ (WebCore::Gradient::setSortedColorStops):
+
+ Added. Replaces setStopsSorted. Used now that CSSGradientValue computes and sorts
+ its color stops before creating the gradient.
+
+ * platform/graphics/Gradient.h:
+ (WebCore::Gradient::create):
+
+ Replace create functions with ones that take data structs.
+
+ (WebCore::Gradient::data const):
+
+ Add accessor for the underlying variant.
+
+ (WebCore::Gradient::isRadial const): Deleted.
+
+ Replaced by type accessor.
+
+ (WebCore::Gradient::p0 const): Deleted.
+ (WebCore::Gradient::p1 const): Deleted.
+ (WebCore::Gradient::setP0): Deleted.
+ (WebCore::Gradient::setP1): Deleted.
+ (WebCore::Gradient::startRadius const): Deleted.
+ (WebCore::Gradient::endRadius const): Deleted.
+ (WebCore::Gradient::setStartRadius): Deleted.
+ (WebCore::Gradient::setEndRadius): Deleted.
+
+ Point and radii are now immutable.
+
+ (WebCore::Gradient::setStopsSorted): Deleted.
+
+ Replaced by setSortedColorStops function.
+
+ * platform/graphics/GraphicsContext.cpp:
+ (WebCore::GraphicsContext::fillRect):
+
+ Pass the GraphicsContext by reference.
+
+ * platform/graphics/cairo/GradientCairo.cpp:
+ (WebCore::Gradient::createPlatformGradient):
+
+ Update to switch on the underlying variant to get data values.
+
+ (WebCore::Gradient::fill):
+
+ Pass the GraphicsContext by reference.
+
+ * platform/graphics/cg/GradientCG.cpp:
+ (WebCore::Gradient::platformDestroy):
+
+ Use nullptr.
+
+ (WebCore::Gradient::fill):
+
+ Pass the GraphicsContext by reference.
+
+ (WebCore::Gradient::paint):
+
+ Update to switch on the underlying variant to get data values.
+
+ * platform/graphics/cg/GraphicsContextCG.cpp:
+ (WebCore::GraphicsContext::fillPath):
+ (WebCore::GraphicsContext::strokePath):
+ (WebCore::GraphicsContext::fillRect):
+ (WebCore::GraphicsContext::strokeRect):
+
+ Pass the GraphicsContext by reference.
+
+ * platform/graphics/win/GradientDirect2D.cpp:
+ (WebCore::Gradient::generateGradient):
+
+ Update to switch on the underlying variant to get data values.
+
+ (WebCore::Gradient::fill):
+
+ Pass the GraphicsContext by reference.
+
+ * rendering/RenderThemeIOS.mm:
+ (WebCore::RenderThemeIOS::paintProgressBar):
+ * rendering/svg/RenderSVGResourceLinearGradient.cpp:
+ (WebCore::RenderSVGResourceLinearGradient::buildGradient const):
+ * rendering/svg/RenderSVGResourceRadialGradient.cpp:
+ (WebCore::RenderSVGResourceRadialGradient::buildGradient const):
+
+ Update for new Gradient create function signature.
+
2017-11-19 Simon Fraser <[email protected]>
Use TypedArrayView's setRange() in FETurbulence
Modified: trunk/Source/WebCore/css/CSSGradientValue.cpp (225035 => 225036)
--- trunk/Source/WebCore/css/CSSGradientValue.cpp 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/css/CSSGradientValue.cpp 2017-11-19 23:06:03 UTC (rev 225036)
@@ -135,14 +135,121 @@
return Color(red, green, blue, alpha);
}
-void CSSGradientValue::addStops(Gradient& gradient, const CSSToLengthConversionData& conversionData, float maxLengthForRepeat)
+class LinearGradientAdapter {
+public:
+ explicit LinearGradientAdapter(Gradient::LinearData& data)
+ : m_data(data)
+ {
+ }
+
+ FloatPoint startPoint() const { return m_data.point0; }
+ FloatPoint endPoint() const { return m_data.point1; }
+ float maxExtent(float, float) const { return 1; }
+
+ void normalizeStopsAndEndpointsOutsideRange(Vector<GradientStop>& stops)
+ {
+ float firstOffset = stops.first().offset;
+ float lastOffset = stops.last().offset;
+ if (firstOffset != lastOffset) {
+ float scale = lastOffset - firstOffset;
+
+ for (auto& stop : stops)
+ stop.offset = (stop.offset - firstOffset) / scale;
+
+ auto p0 = m_data.point0;
+ auto p1 = m_data.point1;
+ m_data.point0 = { p0.x() + firstOffset * (p1.x() - p0.x()), p0.y() + firstOffset * (p1.y() - p0.y()) };
+ m_data.point1 = { p1.x() + (lastOffset - 1) * (p1.x() - p0.x()), p1.y() + (lastOffset - 1) * (p1.y() - p0.y()) };
+ } else {
+ // There's a single position that is outside the scale, clamp the positions to 1.
+ for (auto& stop : stops)
+ stop.offset = 1;
+ }
+ }
+
+private:
+ Gradient::LinearData& m_data;
+};
+
+class RadialGradientAdapter {
+public:
+ explicit RadialGradientAdapter(Gradient::RadialData& data)
+ : m_data(data)
+ {
+ }
+
+ FloatPoint startPoint() const { return m_data.point0; }
+ FloatPoint endPoint() const { return m_data.point0 + FloatSize { m_data.endRadius, 0 }; }
+
+ // Radial gradients may need to extend further than the endpoints, because they have
+ // to repeat out to the corners of the box.
+ float maxExtent(float maxLengthForRepeat, float gradientLength) const
+ {
+ if (maxLengthForRepeat > gradientLength)
+ return gradientLength > 0 ? maxLengthForRepeat / gradientLength : 0;
+ return 1;
+ }
+
+ void normalizeStopsAndEndpointsOutsideRange(Vector<GradientStop>& stops)
+ {
+ auto numStops = stops.size();
+
+ // Rather than scaling the points < 0, we truncate them, so only scale according to the largest point.
+ float firstOffset = 0;
+ float lastOffset = stops.last().offset;
+ float scale = lastOffset - firstOffset;
+
+ // Reset points below 0 to the first visible color.
+ size_t firstZeroOrGreaterIndex = numStops;
+ for (size_t i = 0; i < numStops; ++i) {
+ if (stops[i].offset >= 0) {
+ firstZeroOrGreaterIndex = i;
+ break;
+ }
+ }
+
+ if (firstZeroOrGreaterIndex > 0) {
+ if (firstZeroOrGreaterIndex < numStops && stops[firstZeroOrGreaterIndex].offset > 0) {
+ float prevOffset = stops[firstZeroOrGreaterIndex - 1].offset;
+ float nextOffset = stops[firstZeroOrGreaterIndex].offset;
+
+ float interStopProportion = -prevOffset / (nextOffset - prevOffset);
+ // FIXME: when we interpolate gradients using premultiplied colors, this should do premultiplication.
+ Color blendedColor = blend(stops[firstZeroOrGreaterIndex - 1].color, stops[firstZeroOrGreaterIndex].color, interStopProportion);
+
+ // Clamp the positions to 0 and set the color.
+ for (size_t i = 0; i < firstZeroOrGreaterIndex; ++i) {
+ stops[i].offset = 0;
+ stops[i].color = blendedColor;
+ }
+ } else {
+ // All stops are below 0; just clamp them.
+ for (size_t i = 0; i < firstZeroOrGreaterIndex; ++i)
+ stops[i].offset = 0;
+ }
+ }
+
+ for (auto& stop : stops)
+ stop.offset /= scale;
+
+ m_data.startRadius *= scale;
+ m_data.endRadius *= scale;
+ }
+
+private:
+ Gradient::RadialData& m_data;
+};
+
+template<typename GradientAdapter>
+Gradient::ColorStopVector CSSGradientValue::computeStops(GradientAdapter& gradient, const CSSToLengthConversionData& conversionData, float maxLengthForRepeat)
{
if (m_gradientType == CSSDeprecatedLinearGradient || m_gradientType == CSSDeprecatedRadialGradient) {
sortStopsIfNeeded();
- for (unsigned i = 0; i < m_stops.size(); i++) {
- const CSSGradientColorStop& stop = m_stops[i];
+ Gradient::ColorStopVector result;
+ result.reserveInitialCapacity(m_stops.size());
+ for (auto& stop : m_stops) {
float offset;
if (stop.m_position->isPercentage())
offset = stop.m_position->floatValue(CSSPrimitiveValue::CSS_PERCENTAGE) / 100;
@@ -149,43 +256,32 @@
else
offset = stop.m_position->floatValue(CSSPrimitiveValue::CSS_NUMBER);
- gradient.addColorStop(offset, stop.m_resolvedColor);
+ result.uncheckedAppend({ offset, stop.m_resolvedColor });
}
- // The back end already sorted the stops.
- gradient.setStopsSorted(true);
- return;
+ return result;
}
size_t numStops = m_stops.size();
-
Vector<GradientStop> stops(numStops);
- float gradientLength = 0;
- bool computedGradientLength = false;
+ auto gradientStart = gradient.startPoint();
+ auto gradientEnd = gradient.endPoint();
- FloatPoint gradientStart = gradient.p0();
- FloatPoint gradientEnd;
- if (isLinearGradientValue())
- gradientEnd = gradient.p1();
- else if (isRadialGradientValue())
- gradientEnd = gradientStart + FloatSize(gradient.endRadius(), 0);
+ auto gradientSize = gradientStart - gradientEnd;
+ float gradientLength = gradientSize.diagonalLength();
for (size_t i = 0; i < numStops; ++i) {
- const CSSGradientColorStop& stop = m_stops[i];
+ auto& stop = m_stops[i];
stops[i].isMidpoint = stop.isMidpoint;
stops[i].color = stop.m_resolvedColor;
if (stop.m_position) {
- const CSSPrimitiveValue& positionValue = *stop.m_position;
+ auto& positionValue = *stop.m_position;
if (positionValue.isPercentage())
stops[i].offset = positionValue.floatValue(CSSPrimitiveValue::CSS_PERCENTAGE) / 100;
else if (positionValue.isLength() || positionValue.isViewportPercentageLength() || positionValue.isCalculatedPercentageWithLength()) {
- if (!computedGradientLength) {
- FloatSize gradientSize(gradientStart - gradientEnd);
- gradientLength = gradientSize.diagonalLength();
- }
float length;
if (positionValue.isLength())
length = positionValue.computeLength<float>(conversionData);
@@ -342,7 +438,7 @@
if (m_repeating && numStops > 1) {
// If the difference in the positions of the first and last color-stops is 0,
// the gradient defines a solid-color image with the color of the last color-stop in the rule.
- float gradientRange = stops[numStops - 1].offset - stops[0].offset;
+ float gradientRange = stops.last().offset - stops.first().offset;
if (!gradientRange) {
stops.first().offset = 0;
stops.first().color = stops.last().color;
@@ -349,20 +445,8 @@
stops.shrink(1);
numStops = 1;
} else {
- float maxExtent = 1;
+ float maxExtent = gradient.maxExtent(maxLengthForRepeat, gradientLength);
- // Radial gradients may need to extend further than the endpoints, because they have
- // to repeat out to the corners of the box.
- if (isRadialGradientValue()) {
- if (!computedGradientLength) {
- FloatSize gradientSize(gradientStart - gradientEnd);
- gradientLength = gradientSize.diagonalLength();
- }
-
- if (maxLengthForRepeat > gradientLength)
- maxExtent = gradientLength > 0 ? maxLengthForRepeat / gradientLength : 0;
- }
-
size_t originalNumStops = numStops;
size_t originalFirstStopIndex = 0;
@@ -407,76 +491,16 @@
}
}
- numStops = stops.size();
-
// If the gradient goes outside the 0-1 range, normalize it by moving the endpoints, and adjusting the stops.
- if (numStops > 1 && (stops[0].offset < 0 || stops[numStops - 1].offset > 1)) {
- if (isLinearGradientValue()) {
- float firstOffset = stops[0].offset;
- float lastOffset = stops[numStops - 1].offset;
- if (firstOffset != lastOffset) {
- float scale = lastOffset - firstOffset;
+ if (stops.size() > 1 && (stops.first().offset < 0 || stops.last().offset > 1))
+ gradient.normalizeStopsAndEndpointsOutsideRange(stops);
+
+ Gradient::ColorStopVector result;
+ result.reserveInitialCapacity(stops.size());
+ for (auto& stop : stops)
+ result.uncheckedAppend({ stop.offset, stop.color });
- for (size_t i = 0; i < numStops; ++i)
- stops[i].offset = (stops[i].offset - firstOffset) / scale;
-
- FloatPoint p0 = gradient.p0();
- FloatPoint p1 = gradient.p1();
- gradient.setP0(FloatPoint(p0.x() + firstOffset * (p1.x() - p0.x()), p0.y() + firstOffset * (p1.y() - p0.y())));
- gradient.setP1(FloatPoint(p1.x() + (lastOffset - 1) * (p1.x() - p0.x()), p1.y() + (lastOffset - 1) * (p1.y() - p0.y())));
- } else {
- // There's a single position that is outside the scale, clamp the positions to 1.
- for (size_t i = 0; i < numStops; ++i)
- stops[i].offset = 1;
- }
- } else if (isRadialGradientValue()) {
- // Rather than scaling the points < 0, we truncate them, so only scale according to the largest point.
- float firstOffset = 0;
- float lastOffset = stops[numStops - 1].offset;
- float scale = lastOffset - firstOffset;
-
- // Reset points below 0 to the first visible color.
- size_t firstZeroOrGreaterIndex = numStops;
- for (size_t i = 0; i < numStops; ++i) {
- if (stops[i].offset >= 0) {
- firstZeroOrGreaterIndex = i;
- break;
- }
- }
-
- if (firstZeroOrGreaterIndex > 0) {
- if (firstZeroOrGreaterIndex < numStops && stops[firstZeroOrGreaterIndex].offset > 0) {
- float prevOffset = stops[firstZeroOrGreaterIndex - 1].offset;
- float nextOffset = stops[firstZeroOrGreaterIndex].offset;
-
- float interStopProportion = -prevOffset / (nextOffset - prevOffset);
- // FIXME: when we interpolate gradients using premultiplied colors, this should do premultiplication.
- Color blendedColor = blend(stops[firstZeroOrGreaterIndex - 1].color, stops[firstZeroOrGreaterIndex].color, interStopProportion);
-
- // Clamp the positions to 0 and set the color.
- for (size_t i = 0; i < firstZeroOrGreaterIndex; ++i) {
- stops[i].offset = 0;
- stops[i].color = blendedColor;
- }
- } else {
- // All stops are below 0; just clamp them.
- for (size_t i = 0; i < firstZeroOrGreaterIndex; ++i)
- stops[i].offset = 0;
- }
- }
-
- for (size_t i = 0; i < numStops; ++i)
- stops[i].offset /= scale;
-
- gradient.setStartRadius(gradient.startRadius() * scale);
- gradient.setEndRadius(gradient.endRadius() * scale);
- }
- }
-
- for (unsigned i = 0; i < numStops; i++)
- gradient.addColorStop(stops[i].offset, stops[i].color);
-
- gradient.setStopsSorted(true);
+ return result;
}
static float positionFromValue(const CSSPrimitiveValue* value, const CSSToLengthConversionData& conversionData, const FloatSize& size, bool isHorizontal)
@@ -624,7 +648,7 @@
}
for (unsigned i = 0; i < m_stops.size(); i++) {
- const CSSGradientColorStop& stop = m_stops[i];
+ auto& stop = m_stops[i];
result.appendLiteral(", ");
result.append(stop.m_color->cssText());
if (stop.m_position) {
@@ -801,14 +825,14 @@
default:
ASSERT_NOT_REACHED();
}
-
}
- Ref<Gradient> gradient = Gradient::create(firstPoint, secondPoint);
+ Gradient::LinearData data { firstPoint, secondPoint };
+ LinearGradientAdapter adapter { data };
+ auto stops = computeStops(adapter, conversionData, 1);
- // Now add the stops.
- addStops(gradient, conversionData, 1);
-
+ auto gradient = Gradient::create(WTFMove(data));
+ gradient->setSortedColorStops(WTFMove(stops));
return gradient;
}
@@ -1213,9 +1237,7 @@
}
}
- Ref<Gradient> gradient = Gradient::create(firstPoint, firstRadius, secondPoint, secondRadius, aspectRatio);
-
- // addStops() only uses maxExtent for repeating gradients.
+ // computeStops() only uses maxExtent for repeating gradients.
float maxExtent = 0;
if (m_repeating) {
FloatPoint corner;
@@ -1222,9 +1244,12 @@
maxExtent = distanceToFarthestCorner(secondPoint, size, corner);
}
- // Now add the stops.
- addStops(gradient, conversionData, maxExtent);
+ Gradient::RadialData data { firstPoint, secondPoint, firstRadius, secondRadius, aspectRatio };
+ RadialGradientAdapter adapter { data };
+ auto stops = computeStops(adapter, conversionData, maxExtent);
+ auto gradient = Gradient::create(WTFMove(data));
+ gradient->setSortedColorStops(WTFMove(stops));
return gradient;
}
@@ -1326,7 +1351,7 @@
Ref<Gradient> CSSConicGradientValue::createGradient(RenderElement&, const FloatSize&)
{
// FIXME: Implement.
- return Gradient::create(FloatPoint { }, FloatPoint { });
+ return Gradient::create(Gradient::LinearData { });
}
bool CSSConicGradientValue::equals(const CSSConicGradientValue& other) const
Modified: trunk/Source/WebCore/css/CSSGradientValue.h (225035 => 225036)
--- trunk/Source/WebCore/css/CSSGradientValue.h 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/css/CSSGradientValue.h 2017-11-19 23:06:03 UTC (rev 225036)
@@ -27,12 +27,12 @@
#include "CSSImageGeneratorValue.h"
#include "CSSPrimitiveValue.h"
+#include "Gradient.h"
#include <wtf/Vector.h>
namespace WebCore {
class FloatPoint;
-class Gradient;
class StyleResolver;
enum CSSGradientType {
@@ -109,7 +109,8 @@
{
}
- void addStops(Gradient&, const CSSToLengthConversionData&, float maxLengthForRepeat = 0);
+ template<typename GradientAdapter>
+ Gradient::ColorStopVector computeStops(GradientAdapter&, const CSSToLengthConversionData&, float maxLengthForRepeat);
// Resolve points/radii to front end values.
FloatPoint computeEndPoint(CSSPrimitiveValue*, CSSPrimitiveValue*, const CSSToLengthConversionData&, const FloatSize&);
Modified: trunk/Source/WebCore/html/canvas/CanvasGradient.cpp (225035 => 225036)
--- trunk/Source/WebCore/html/canvas/CanvasGradient.cpp 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/html/canvas/CanvasGradient.cpp 2017-11-19 23:06:03 UTC (rev 225036)
@@ -32,12 +32,12 @@
namespace WebCore {
CanvasGradient::CanvasGradient(const FloatPoint& p0, const FloatPoint& p1)
- : m_gradient(Gradient::create(p0, p1))
+ : m_gradient(Gradient::create(Gradient::LinearData { p0, p1 }))
{
}
CanvasGradient::CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1)
- : m_gradient(Gradient::create(p0, r0, p1, r1))
+ : m_gradient(Gradient::create(Gradient::RadialData { p0, p1, r0, r1, 1 }))
{
}
Modified: trunk/Source/WebCore/inspector/InspectorCanvas.cpp (225035 => 225036)
--- trunk/Source/WebCore/inspector/InspectorCanvas.cpp 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/inspector/InspectorCanvas.cpp 2017-11-19 23:06:03 UTC (rev 225036)
@@ -591,23 +591,30 @@
RefPtr<Inspector::Protocol::Array<InspectorValue>> InspectorCanvas::buildArrayForCanvasGradient(const CanvasGradient& canvasGradient)
{
- const Gradient& gradient = canvasGradient.gradient();
- bool isRadial = gradient.isRadial();
+ const auto& gradient = canvasGradient.gradient();
- String type = isRadial ? ASCIILiteral("radial-gradient") : ASCIILiteral("linear-gradient");
+ String type = gradient.type() == Gradient::Type::Radial ? ASCIILiteral("radial-gradient") : ASCIILiteral("linear-gradient");
RefPtr<Inspector::Protocol::Array<float>> parameters = Inspector::Protocol::Array<float>::create();
- parameters->addItem(gradient.p0().x());
- parameters->addItem(gradient.p0().y());
- if (isRadial)
- parameters->addItem(gradient.startRadius());
- parameters->addItem(gradient.p1().x());
- parameters->addItem(gradient.p1().y());
- if (isRadial)
- parameters->addItem(gradient.endRadius());
+ WTF::switchOn(gradient.data(),
+ [¶meters] (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) {
+ parameters->addItem(data.point0.x());
+ parameters->addItem(data.point0.y());
+ parameters->addItem(data.startRadius);
+ parameters->addItem(data.point1.x());
+ parameters->addItem(data.point1.y());
+ parameters->addItem(data.endRadius);
+ }
+ );
RefPtr<Inspector::Protocol::Array<InspectorValue>> stops = Inspector::Protocol::Array<InspectorValue>::create();
- for (const Gradient::ColorStop& colorStop : gradient.stops()) {
+ for (auto& colorStop : gradient.stops()) {
RefPtr<Inspector::Protocol::Array<InspectorValue>> stop = Inspector::Protocol::Array<InspectorValue>::create();
stop->addItem(colorStop.offset);
stop->addItem(indexForData(colorStop.color.cssText()));
Modified: trunk/Source/WebCore/platform/graphics/Gradient.cpp (225035 => 225036)
--- trunk/Source/WebCore/platform/graphics/Gradient.cpp 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/platform/graphics/Gradient.cpp 2017-11-19 23:06:03 UTC (rev 225036)
@@ -36,30 +36,24 @@
namespace WebCore {
-Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1)
- : m_radial(false)
- , m_p0(p0)
- , m_p1(p1)
- , m_r0(0)
- , m_r1(0)
- , m_aspectRatio(1)
- , m_stopsSorted(false)
- , m_spreadMethod(SpreadMethodPad)
- , m_cachedHash(0)
+Ref<Gradient> Gradient::create(LinearData&& data)
{
+ return adoptRef(*new Gradient(WTFMove(data)));
+}
+
+Ref<Gradient> Gradient::create(RadialData&& data)
+{
+ return adoptRef(*new Gradient(WTFMove(data)));
+}
+
+Gradient::Gradient(LinearData&& data)
+ : m_data(WTFMove(data))
+{
platformInit();
}
-Gradient::Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio)
- : m_radial(true)
- , m_p0(p0)
- , m_p1(p1)
- , m_r0(r0)
- , m_r1(r1)
- , m_aspectRatio(aspectRatio)
- , m_stopsSorted(false)
- , m_spreadMethod(SpreadMethodPad)
- , m_cachedHash(0)
+Gradient::Gradient(RadialData&& data)
+ : m_data(WTFMove(data))
{
platformInit();
}
@@ -69,11 +63,20 @@
platformDestroy();
}
+auto Gradient::type() const -> Type
+{
+ return WTF::switchOn(m_data,
+ [] (const LinearData&) {
+ return Type::Linear;
+ },
+ [] (const RadialData&) {
+ return Type::Radial;
+ }
+ );
+}
+
void Gradient::adjustParametersForTiledDrawing(FloatSize& size, FloatRect& srcRect, const FloatSize& spacing)
{
- if (m_radial)
- return;
-
if (srcRect.isEmpty())
return;
@@ -80,37 +83,60 @@
if (!spacing.isZero())
return;
- if (m_p0.x() == m_p1.x()) {
- size.setWidth(1);
- srcRect.setWidth(1);
- srcRect.setX(0);
- return;
- }
- if (m_p0.y() != m_p1.y())
- return;
+ WTF::switchOn(m_data,
+ [&] (const LinearData& data) {
+ if (data.point0.x() == data.point1.x()) {
+ size.setWidth(1);
+ srcRect.setWidth(1);
+ srcRect.setX(0);
+ return;
+ }
+ if (data.point0.y() != data.point1.y())
+ return;
- size.setHeight(1);
- srcRect.setHeight(1);
- srcRect.setY(0);
+ size.setHeight(1);
+ srcRect.setHeight(1);
+ srcRect.setY(0);
+ },
+ [] (const RadialData&) {
+ }
+ );
}
+bool Gradient::isZeroSize() const
+{
+ return WTF::switchOn(m_data,
+ [] (const LinearData& data) {
+ return data.point0.x() == data.point1.x() && data.point0.y() == data.point1.y();
+ },
+ [] (const RadialData& data) {
+ return data.point0.x() == data.point1.x() && data.point0.y() == data.point1.y() && data.startRadius == data.endRadius;
+ }
+ );
+}
+
void Gradient::addColorStop(float offset, const Color& color)
{
- m_stops.append(ColorStop(offset, color));
+ addColorStop({ offset, color });
+}
+void Gradient::addColorStop(const Gradient::ColorStop& stop)
+{
+ m_stops.append(stop);
+
m_stopsSorted = false;
+
platformDestroy();
-
invalidateHash();
}
-void Gradient::addColorStop(const Gradient::ColorStop& stop)
+void Gradient::setSortedColorStops(ColorStopVector&& stops)
{
- m_stops.append(stop);
+ m_stops = WTFMove(stops);
- m_stopsSorted = false;
+ m_stopsSorted = true;
+
platformDestroy();
-
invalidateHash();
}
@@ -130,7 +156,6 @@
return;
std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
-
invalidateHash();
}
@@ -173,14 +198,14 @@
return m_cachedHash;
struct {
- AffineTransform gradientSpaceTransformation;
- FloatPoint p0;
- FloatPoint p1;
- float r0;
- float r1;
+ Type type;
+ FloatPoint point0;
+ FloatPoint point1;
+ float startRadius;
+ float endRadius;
float aspectRatio;
GradientSpreadMethod spreadMethod;
- bool radial;
+ AffineTransform gradientSpaceTransformation;
} parameters;
// StringHasher requires that the memory it hashes be a multiple of two in size.
@@ -190,14 +215,27 @@
// Ensure that any padding in the struct is zero-filled, so it will not affect the hash value.
memset(¶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.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.type = Type::Radial;
+ }
+ );
+
+ parameters.spreadMethod = m_spreadMethod;
parameters.gradientSpaceTransformation = m_gradientSpaceTransformation;
- parameters.p0 = m_p0;
- parameters.p1 = m_p1;
- parameters.r0 = m_r0;
- parameters.r1 = m_r1;
- parameters.aspectRatio = m_aspectRatio;
- parameters.spreadMethod = m_spreadMethod;
- parameters.radial = m_radial;
unsigned parametersHash = StringHasher::hashMemory(¶meters, sizeof(parameters));
unsigned stopHash = StringHasher::hashMemory(m_stops.data(), m_stops.size() * sizeof(ColorStop));
@@ -207,4 +245,4 @@
return m_cachedHash;
}
-} //namespace
+}
Modified: trunk/Source/WebCore/platform/graphics/Gradient.h (225035 => 225036)
--- trunk/Source/WebCore/platform/graphics/Gradient.h 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/platform/graphics/Gradient.h 2017-11-19 23:06:03 UTC (rev 225036)
@@ -25,8 +25,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef Gradient_h
-#define Gradient_h
+#pragma once
#include "AffineTransform.h"
#include "Color.h"
@@ -33,15 +32,13 @@
#include "FloatPoint.h"
#include "GraphicsTypes.h"
#include <wtf/RefCounted.h>
+#include <wtf/Variant.h>
#include <wtf/Vector.h>
#if USE(CG)
-
typedef struct CGContext* CGContextRef;
-
typedef struct CGGradient* CGGradientRef;
typedef CGGradientRef PlatformGradient;
-
#elif USE(DIRECT2D)
interface ID2D1Brush;
interface ID2D1RenderTarget;
@@ -55,152 +52,108 @@
namespace WebCore {
- class Color;
- class FloatRect;
- class GraphicsContext;
+class Color;
+class FloatRect;
+class GraphicsContext;
- class Gradient : public RefCounted<Gradient> {
- public:
- static Ref<Gradient> create(const FloatPoint& p0, const FloatPoint& p1)
+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)
{
- return adoptRef(*new Gradient(p0, p1));
}
- static Ref<Gradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio = 1)
- {
- return adoptRef(*new Gradient(p0, r0, p1, r1, aspectRatio));
- }
- WEBCORE_EXPORT ~Gradient();
+ };
- struct ColorStop;
- WEBCORE_EXPORT void addColorStop(const ColorStop&);
- WEBCORE_EXPORT void addColorStop(float, const Color&);
+ using ColorStopVector = Vector<ColorStop, 2>;
- bool hasAlpha() const;
+ struct LinearData {
+ FloatPoint point0;
+ FloatPoint point1;
+ };
- bool isRadial() const { return m_radial; }
- bool isZeroSize() const { return m_p0.x() == m_p1.x() && m_p0.y() == m_p1.y() && (!m_radial || m_r0 == m_r1); }
+ struct RadialData {
+ FloatPoint point0;
+ FloatPoint point1;
+ float startRadius;
+ float endRadius;
+ float aspectRatio; // For elliptical gradient, width / height.
+ };
- const FloatPoint& p0() const { return m_p0; }
- const FloatPoint& p1() const { return m_p1; }
+ using Data = "" RadialData>;
- void setP0(const FloatPoint& p)
- {
- if (m_p0 == p)
- return;
-
- m_p0 = p;
-
- invalidateHash();
- }
-
- void setP1(const FloatPoint& p)
- {
- if (m_p1 == p)
- return;
-
- m_p1 = p;
-
- invalidateHash();
- }
+ enum class Type { Linear, Radial };
- float startRadius() const { return m_r0; }
- float endRadius() const { return m_r1; }
+ static Ref<Gradient> create(LinearData&&);
+ static Ref<Gradient> create(RadialData&&);
- void setStartRadius(float r)
- {
- if (m_r0 == r)
- return;
+ WEBCORE_EXPORT ~Gradient();
- m_r0 = r;
+ Type type() const;
- invalidateHash();
- }
+ bool hasAlpha() const;
+ bool isZeroSize() const;
- void setEndRadius(float r)
- {
- if (m_r1 == r)
- return;
+ const Data& data() const { return m_data; }
- m_r1 = r;
+ WEBCORE_EXPORT void addColorStop(const ColorStop&);
+ WEBCORE_EXPORT void addColorStop(float, const Color&);
+ void setSortedColorStops(ColorStopVector&&);
- invalidateHash();
- }
+ const ColorStopVector& stops() const { return m_stops; }
- float aspectRatio() const { return m_aspectRatio; }
+ void setSpreadMethod(GradientSpreadMethod);
+ GradientSpreadMethod spreadMethod() const { return m_spreadMethod; }
-#if USE(WINGDI)
- const Vector<ColorStop, 2>& getStops() const;
-#else
- PlatformGradient platformGradient();
-#endif
+ // CG needs to transform the gradient at draw time.
+ void setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation);
+ const AffineTransform& gradientSpaceTransform() { return m_gradientSpaceTransformation; }
- // FIXME: ExtendedColor - A color stop needs a notion of color space.
- struct ColorStop {
- float offset { 0 };
- Color color;
+ void fill(GraphicsContext&, const FloatRect&);
+ void adjustParametersForTiledDrawing(FloatSize&, FloatRect&, const FloatSize& spacing);
- ColorStop() { }
- ColorStop(float offset, const Color& color)
- : offset(offset)
- , color(color)
- { }
- };
+ unsigned hash() const;
+ void invalidateHash() { m_cachedHash = 0; }
- const Vector<ColorStop, 2>& stops() const { return m_stops; }
-
- void setStopsSorted(bool s) { m_stopsSorted = s; }
-
- void setSpreadMethod(GradientSpreadMethod);
- GradientSpreadMethod spreadMethod() { return m_spreadMethod; }
- void setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation);
- // Qt and CG transform the gradient at draw time
- AffineTransform gradientSpaceTransform() { return m_gradientSpaceTransformation; }
-
- void fill(GraphicsContext*, const FloatRect&);
- void adjustParametersForTiledDrawing(FloatSize&, FloatRect&, const FloatSize& spacing);
-
- unsigned hash() const;
- void invalidateHash() { m_cachedHash = 0; }
-
#if USE(CG)
- void paint(CGContextRef);
- void paint(GraphicsContext*);
+ void paint(GraphicsContext&);
+ void paint(CGContextRef);
#elif USE(DIRECT2D)
- PlatformGradient createPlatformGradientIfNecessary(ID2D1RenderTarget*);
+ PlatformGradient createPlatformGradientIfNecessary(ID2D1RenderTarget*);
#elif USE(CAIRO)
- PlatformGradient createPlatformGradient(float globalAlpha);
+ PlatformGradient createPlatformGradient(float globalAlpha);
#endif
- private:
- WEBCORE_EXPORT Gradient(const FloatPoint& p0, const FloatPoint& p1);
- Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio);
+private:
+ Gradient(LinearData&&);
+ Gradient(RadialData&&);
- void platformInit() { m_gradient = nullptr; }
- void platformDestroy();
+ PlatformGradient platformGradient();
+ void platformInit() { m_gradient = nullptr; }
+ void platformDestroy();
- void sortStopsIfNecessary();
+ void sortStopsIfNecessary();
#if USE(DIRECT2D)
- void generateGradient(ID2D1RenderTarget*);
+ void generateGradient(ID2D1RenderTarget*);
#endif
- // Keep any parameters relevant to rendering in sync with the structure in Gradient::hash().
- bool m_radial;
- FloatPoint m_p0;
- FloatPoint m_p1;
- float m_r0;
- float m_r1;
- float m_aspectRatio; // For elliptical gradient, width / height.
- mutable Vector<ColorStop, 2> m_stops;
- mutable bool m_stopsSorted;
- GradientSpreadMethod m_spreadMethod;
- AffineTransform m_gradientSpaceTransformation;
+ Data m_data;
- mutable unsigned m_cachedHash;
+ mutable ColorStopVector m_stops;
+ mutable bool m_stopsSorted { false };
+ GradientSpreadMethod m_spreadMethod { SpreadMethodPad };
+ AffineTransform m_gradientSpaceTransformation;
- PlatformGradient m_gradient;
- };
+ mutable unsigned m_cachedHash { 0 };
-} //namespace
+ PlatformGradient m_gradient;
+};
-#endif
+}
Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp (225035 => 225036)
--- trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp 2017-11-19 23:06:03 UTC (rev 225036)
@@ -852,7 +852,7 @@
return;
}
- gradient.fill(this, rect);
+ gradient.fill(*this, rect);
}
void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, CompositeOperator op, BlendMode blendMode)
Modified: trunk/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp (225035 => 225036)
--- trunk/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/platform/graphics/cairo/GradientCairo.cpp 2017-11-19 23:06:03 UTC (rev 225036)
@@ -42,11 +42,14 @@
cairo_pattern_t* Gradient::createPlatformGradient(float globalAlpha)
{
- cairo_pattern_t* gradient;
- if (m_radial)
- gradient = cairo_pattern_create_radial(m_p0.x(), m_p0.y(), m_r0, m_p1.x(), m_p1.y(), m_r1);
- else
- gradient = cairo_pattern_create_linear(m_p0.x(), m_p0.y(), m_p1.x(), m_p1.y());
+ 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());
+ },
+ [&] (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);
+ }
+ );
for (const auto& stop : m_stops) {
if (stop.color.isExtended()) {
@@ -78,14 +81,14 @@
return gradient;
}
-void Gradient::fill(GraphicsContext* context, const FloatRect& rect)
+void Gradient::fill(GraphicsContext& context, const FloatRect& rect)
{
RefPtr<cairo_pattern_t> platformGradient = adoptRef(createPlatformGradient(1.0));
- context->save();
- ASSERT(context->hasPlatformContext());
- Cairo::fillRect(*context->platformContext(), rect, platformGradient.get());
- context->restore();
+ context.save();
+ ASSERT(context.hasPlatformContext());
+ Cairo::fillRect(*context.platformContext(), rect, platformGradient.get());
+ context.restore();
}
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp (225035 => 225036)
--- trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp 2017-11-19 23:06:03 UTC (rev 225036)
@@ -38,7 +38,7 @@
void Gradient::platformDestroy()
{
CGGradientRelease(m_gradient);
- m_gradient = 0;
+ m_gradient = nullptr;
}
CGGradientRef Gradient::platformGradient()
@@ -92,43 +92,45 @@
return m_gradient;
}
-void Gradient::fill(GraphicsContext* context, const FloatRect& rect)
+void Gradient::fill(GraphicsContext& context, const FloatRect& rect)
{
- context->clip(rect);
+ context.clip(rect);
paint(context);
}
-void Gradient::paint(GraphicsContext* context)
+void Gradient::paint(GraphicsContext& context)
{
- CGContextRef ctx = context->platformContext();
- paint(ctx);
+ paint(context.platformContext());
}
-void Gradient::paint(CGContextRef context)
+void Gradient::paint(CGContextRef platformContext)
{
CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
- if (!m_radial) {
- CGContextDrawLinearGradient(context, platformGradient(), m_p0, m_p1, extendOptions);
- return;
- }
- bool needScaling = aspectRatio() != 1;
- if (needScaling) {
- CGContextSaveGState(context);
- // Scale from the center of the gradient. We only ever scale non-deprecated gradients,
- // for which m_p0 == m_p1.
- ASSERT(m_p0 == m_p1);
- CGContextTranslateCTM(context, m_p0.x(), m_p0.y());
- CGContextScaleCTM(context, 1, 1 / aspectRatio());
- CGContextTranslateCTM(context, -m_p0.x(), -m_p0.y());
- }
+ WTF::switchOn(m_data,
+ [&] (const LinearData& data) {
+ CGContextDrawLinearGradient(platformContext, platformGradient(), data.point0, data.point1, extendOptions);
+ },
+ [&] (const RadialData& data) {
+ bool needScaling = data.aspectRatio != 1;
+ if (needScaling) {
+ CGContextSaveGState(platformContext);
+ // Scale from the center of the gradient. We only ever scale non-deprecated gradients,
+ // for which point0 == point1.
+ ASSERT(data.point0 == data.point1);
+ CGContextTranslateCTM(platformContext, data.point0.x(), data.point0.y());
+ CGContextScaleCTM(platformContext, 1, 1 / data.aspectRatio);
+ CGContextTranslateCTM(platformContext, -data.point0.x(), -data.point0.y());
+ }
- CGContextDrawRadialGradient(context, platformGradient(), m_p0, m_r0, m_p1, m_r1, extendOptions);
+ CGContextDrawRadialGradient(platformContext, platformGradient(), data.point0, data.startRadius, data.point1, data.endRadius, extendOptions);
- if (needScaling)
- CGContextRestoreGState(context);
+ if (needScaling)
+ CGContextRestoreGState(platformContext);
+ }
+ );
}
-} //namespace
+}
#endif
Modified: trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp (225035 => 225036)
--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp 2017-11-19 23:06:03 UTC (rev 225036)
@@ -777,7 +777,7 @@
else
CGContextClip(context);
- m_state.fillGradient->paint(this);
+ m_state.fillGradient->paint(*this);
}
return;
@@ -848,7 +848,7 @@
CGContextReplacePathWithStrokedPath(context);
CGContextClip(context);
CGContextConcatCTM(context, m_state.strokeGradient->gradientSpaceTransform());
- m_state.strokeGradient->paint(this);
+ m_state.strokeGradient->paint(*this);
}
return;
}
@@ -896,7 +896,7 @@
} else {
CGContextClipToRect(context, rect);
CGContextConcatCTM(context, m_state.fillGradient->gradientSpaceTransform());
- m_state.fillGradient->paint(this);
+ m_state.fillGradient->paint(*this);
}
return;
}
@@ -1323,7 +1323,7 @@
CGContextReplacePathWithStrokedPath(context);
CGContextClip(context);
CGContextConcatCTM(context, m_state.strokeGradient->gradientSpaceTransform());
- m_state.strokeGradient->paint(this);
+ m_state.strokeGradient->paint(*this);
}
return;
}
Modified: trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp (225035 => 225036)
--- trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/platform/graphics/win/GradientDirect2D.cpp 2017-11-19 23:06:03 UTC (rev 225036)
@@ -78,62 +78,78 @@
m_gradient = nullptr;
}
- if (m_radial) {
- FloatSize offset = p1() - p0();
- ID2D1RadialGradientBrush* radialGradient = nullptr;
- float radiusX = endRadius() + offset.width();
- float radiusY = radiusX / m_aspectRatio;
- hr = renderTarget->CreateRadialGradientBrush(
- D2D1::RadialGradientBrushProperties(p0(), D2D1::Point2F(offset.width(), offset.height()), radiusX, radiusY),
- D2D1::BrushProperties(), gradientStopCollection.get(),
- &radialGradient);
- RELEASE_ASSERT(SUCCEEDED(hr));
- m_gradient = radialGradient;
- } else {
- ID2D1LinearGradientBrush* linearGradient = nullptr;
- hr = renderTarget->CreateLinearGradientBrush(
- D2D1::LinearGradientBrushProperties(p0(), p1()),
- D2D1::BrushProperties(), gradientStopCollection.get(),
- &linearGradient);
- RELEASE_ASSERT(SUCCEEDED(hr));
- m_gradient = linearGradient;
- }
+ WTF::switchOn(m_data,
+ [&] (const LinearData& data) {
+ ID2D1LinearGradientBrush* linearGradient = nullptr;
+ hr = renderTarget->CreateLinearGradientBrush(
+ D2D1::LinearGradientBrushProperties(data.point0, data.point1),
+ D2D1::BrushProperties(), gradientStopCollection.get(),
+ &linearGradient);
+ RELEASE_ASSERT(SUCCEEDED(hr));
+ m_gradient = linearGradient;
+ },
+ [&] (const RadialData& data) {
+ FloatSize offset = data.point1 - data.point0;
+ ID2D1RadialGradientBrush* radialGradient = nullptr;
+ float radiusX = data.endRadius + offset.width();
+ float radiusY = radiusX / data.aspectRatio;
+ hr = renderTarget->CreateRadialGradientBrush(
+ D2D1::RadialGradientBrushProperties(p0(), D2D1::Point2F(offset.width(), offset.height()), radiusX, radiusY),
+ D2D1::BrushProperties(), gradientStopCollection.get(),
+ &radialGradient);
+ RELEASE_ASSERT(SUCCEEDED(hr));
+ m_gradient = radialGradient;
+ }
+ );
hash();
}
-void Gradient::fill(GraphicsContext* context, const FloatRect& rect)
+void Gradient::fill(GraphicsContext& context, const FloatRect& rect)
{
- auto d2dContext = context->platformContext();
+ auto d2dContext = context.platformContext();
- bool needScaling = aspectRatio() != 1;
- if (needScaling) {
- context->save();
- // Scale from the center of the gradient. We only ever scale non-deprecated gradients,
- // for which m_p0 == m_p1.
- ASSERT(m_p0 == m_p1);
+ WTF::switchOn(m_data,
+ [&] (const LinearData& data) {
+ if (!m_cachedHash || !m_gradient)
+ generateGradient(d2dContext);
- D2D1_MATRIX_3X2_F ctm = { };
- d2dContext->GetTransform(&ctm);
+ d2dContext->SetTags(GRADIENT_DRAWING, __LINE__);
- AffineTransform transform(ctm);
- transform.translate(m_p0);
- transform.scaleNonUniform(1.0, 1.0 / aspectRatio());
- transform.translate(-m_p0);
+ const D2D1_RECT_F d2dRect = rect;
+ d2dContext->FillRectangle(&d2dRect, m_gradient);
+ },
+ [&] (const RadialData& data) {
+ bool needScaling = data.aspectRatio != 1;
+ if (needScaling) {
+ context.save();
+ // Scale from the center of the gradient. We only ever scale non-deprecated gradients,
+ // for which m_p0 == m_p1.
+ ASSERT(data.point0 == data.point1);
- d2dContext->SetTransform(ctm);
- }
+ D2D1_MATRIX_3X2_F ctm = { };
+ d2dContext->GetTransform(&ctm);
- if (!m_cachedHash || !m_gradient)
- generateGradient(d2dContext);
+ AffineTransform transform(ctm);
+ transform.translate(data.point0);
+ transform.scaleNonUniform(1.0, 1.0 / data.aspectRatio);
+ transform.translate(-data.point0);
- d2dContext->SetTags(GRADIENT_DRAWING, __LINE__);
+ d2dContext->SetTransform(ctm);
+ }
- const D2D1_RECT_F d2dRect = rect;
- d2dContext->FillRectangle(&d2dRect, m_gradient);
+ if (!m_cachedHash || !m_gradient)
+ generateGradient(d2dContext);
- if (needScaling)
- context->restore();
+ d2dContext->SetTags(GRADIENT_DRAWING, __LINE__);
+
+ const D2D1_RECT_F d2dRect = rect;
+ d2dContext->FillRectangle(&d2dRect, m_gradient);
+
+ if (needScaling)
+ context.restore();
+ }
+ );
}
}
Modified: trunk/Source/WebCore/rendering/RenderThemeIOS.mm (225035 => 225036)
--- trunk/Source/WebCore/rendering/RenderThemeIOS.mm 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/rendering/RenderThemeIOS.mm 2017-11-19 23:06:03 UTC (rev 225036)
@@ -897,7 +897,7 @@
context.setStrokeStyle(SolidStroke);
const float verticalRenderingPosition = rect.y() + verticalOffset;
- RefPtr<Gradient> strokeGradient = Gradient::create(FloatPoint(rect.x(), verticalRenderingPosition), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1));
+ RefPtr<Gradient> strokeGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) });
strokeGradient->addColorStop(0.0, Color(0x8d, 0x8d, 0x8d));
strokeGradient->addColorStop(0.45, Color(0xee, 0xee, 0xee));
strokeGradient->addColorStop(0.55, Color(0xee, 0xee, 0xee));
@@ -917,7 +917,7 @@
paintInfo.context().clipRoundedRect(FloatRoundedRect(border, roundedCornerRadius, roundedCornerRadius, roundedCornerRadius, roundedCornerRadius));
float upperGradientHeight = progressBarHeight / 2.;
- RefPtr<Gradient> upperGradient = Gradient::create(FloatPoint(rect.x(), verticalRenderingPosition + 0.5), FloatPoint(rect.x(), verticalRenderingPosition + upperGradientHeight - 1.5));
+ RefPtr<Gradient> upperGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5), FloatPoint(rect.x(), verticalRenderingPosition + upperGradientHeight - 1.5) });
upperGradient->addColorStop(0.0, Color(133, 133, 133, 188));
upperGradient->addColorStop(1.0, Color(18, 18, 18, 51));
context.setFillGradient(upperGradient.releaseNonNull());
@@ -929,7 +929,7 @@
// 2) Draw the progress bar.
double position = clampTo(renderProgress.position(), 0.0, 1.0);
double barWidth = position * rect.width();
- RefPtr<Gradient> barGradient = Gradient::create(FloatPoint(rect.x(), verticalRenderingPosition + 0.5), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1));
+ RefPtr<Gradient> barGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition + 0.5), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) });
barGradient->addColorStop(0.0, Color(195, 217, 247));
barGradient->addColorStop(0.45, Color(118, 164, 228));
barGradient->addColorStop(0.49, Color(118, 164, 228));
@@ -938,7 +938,7 @@
barGradient->addColorStop(1.0, Color(57, 142, 244));
context.setFillGradient(barGradient.releaseNonNull());
- RefPtr<Gradient> barStrokeGradient = Gradient::create(FloatPoint(rect.x(), verticalRenderingPosition), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1));
+ RefPtr<Gradient> barStrokeGradient = Gradient::create(Gradient::LinearData { FloatPoint(rect.x(), verticalRenderingPosition), FloatPoint(rect.x(), verticalRenderingPosition + progressBarHeight - 1) });
barStrokeGradient->addColorStop(0.0, Color(95, 107, 183));
barStrokeGradient->addColorStop(0.5, Color(66, 106, 174, 240));
barStrokeGradient->addColorStop(1.0, Color(38, 104, 166));
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.cpp (225035 => 225036)
--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.cpp 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.cpp 2017-11-19 23:06:03 UTC (rev 225036)
@@ -52,7 +52,7 @@
void RenderSVGResourceLinearGradient::buildGradient(GradientData* gradientData) const
{
- gradientData->gradient = Gradient::create(startPoint(m_attributes), endPoint(m_attributes));
+ gradientData->gradient = Gradient::create(Gradient::LinearData { startPoint(m_attributes), endPoint(m_attributes) });
gradientData->gradient->setSpreadMethod(platformSpreadMethodFromSVGType(m_attributes.spreadMethod()));
addStops(gradientData, m_attributes.stops());
}
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp (225035 => 225036)
--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp 2017-11-19 21:57:13 UTC (rev 225035)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp 2017-11-19 23:06:03 UTC (rev 225036)
@@ -63,11 +63,7 @@
void RenderSVGResourceRadialGradient::buildGradient(GradientData* gradientData) const
{
- gradientData->gradient = Gradient::create(this->focalPoint(m_attributes),
- this->focalRadius(m_attributes),
- this->centerPoint(m_attributes),
- this->radius(m_attributes));
-
+ gradientData->gradient = Gradient::create(Gradient::RadialData { this->focalPoint(m_attributes), this->centerPoint(m_attributes), this->focalRadius(m_attributes), this->radius(m_attributes), 1 });
gradientData->gradient->setSpreadMethod(platformSpreadMethodFromSVGType(m_attributes.spreadMethod()));
addStops(gradientData, m_attributes.stops());