Title: [235772] trunk
Revision
235772
Author
[email protected]
Date
2018-09-06 18:36:36 -0700 (Thu, 06 Sep 2018)

Log Message

Add Support for Conic Gradients
https://bugs.webkit.org/show_bug.cgi?id=189329
<rdar://problem/21444701>

Reviewed by Simon Fraser.

Source/WebCore:

Add support for rendering CSS conic gradients.
The parsing work was already done, this just hooks up the data we have
with the CG functionality for conic gradients. Add the needed plumbing
to allow for this additional type and fill in the creation of
a conic gradient.

Tests: fast/gradients/conic-repeating.html
       fast/gradients/conic.html

* css/CSSGradientValue.cpp:
(WebCore::createGradient):
(WebCore::LinearGradientAdapter::gradientLength const):
(WebCore::RadialGradientAdapter::gradientLength const):
(WebCore::ConicGradientAdapter::ConicGradientAdapter):
(WebCore::ConicGradientAdapter::gradientLength const):
(WebCore::ConicGradientAdapter::maxExtent const):
(WebCore::ConicGradientAdapter::normalizeStopsAndEndpointsOutsideRange):

Compute what the color stops should be if they extend past 0-1

(WebCore::CSSGradientValue::computeStops):
(WebCore::CSSConicGradientValue::createGradient):
(WebCore::LinearGradientAdapter::startPoint const): Deleted.
(WebCore::LinearGradientAdapter::endPoint const): Deleted.
(WebCore::RadialGradientAdapter::startPoint const): Deleted.
(WebCore::RadialGradientAdapter::endPoint const): Deleted.

Start and End points weren't very universal. All we really need from these
gradientAdapters is their length, so just ask for that instead.

* inspector/InspectorCanvas.cpp:
(WebCore::InspectorCanvas::buildArrayForCanvasGradient):
* platform/graphics/Gradient.cpp:
(WebCore::Gradient::create):
(WebCore::Gradient::Gradient):
(WebCore::Gradient::type const):
(WebCore::Gradient::adjustParametersForTiledDrawing):
(WebCore::Gradient::isZeroSize const):
(WebCore::Gradient::hash const):
* platform/graphics/Gradient.h:
* platform/graphics/cg/GradientCG.cpp:
(WebCore::Gradient::paint):

Source/WebCore/PAL:

Define the CG functionality for conic gradients.

* pal/spi/cg/CoreGraphicsSPI.h:

Source/WebKit:

Connect up web preferences to allow conic gradients to be turned on in the
experimental features menu.

* Shared/WebPreferences.yaml:

LayoutTests:

Simple tests to see if conic gradients are rendered properly.

* fast/gradients/conic-expected.html: Added.
* fast/gradients/conic-repeating-expected.html: Added.
* fast/gradients/conic-repeating.html: Added.
* fast/gradients/conic.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (235771 => 235772)


--- trunk/LayoutTests/ChangeLog	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/LayoutTests/ChangeLog	2018-09-07 01:36:36 UTC (rev 235772)
@@ -1,3 +1,18 @@
+2018-09-06  Megan Gardner  <[email protected]>
+
+        Add Support for Conic Gradients
+        https://bugs.webkit.org/show_bug.cgi?id=189329
+        <rdar://problem/21444701>
+
+        Reviewed by Simon Fraser.
+
+        Simple tests to see if conic gradients are rendered properly.
+
+        * fast/gradients/conic-expected.html: Added.
+        * fast/gradients/conic-repeating-expected.html: Added.
+        * fast/gradients/conic-repeating.html: Added.
+        * fast/gradients/conic.html: Added.
+
 2018-09-06  Zalan Bujtas  <[email protected]>
 
         [LFC][BFC] Add support for min(max)-height

Modified: trunk/LayoutTests/TestExpectations (235771 => 235772)


--- trunk/LayoutTests/TestExpectations	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/LayoutTests/TestExpectations	2018-09-07 01:36:36 UTC (rev 235772)
@@ -2239,3 +2239,9 @@
 webkit.org/b/187269 [ Debug ] imported/w3c/web-platform-tests/FileAPI/reading-data-section/filereader_abort.html [ Skip ]
 
 webkit.org/b/185308 legacy-animation-engine/animations/combo-transform-translate+scale.html [ Pass Failure ]
+
+fast/gradients/conic-repeating.html [ Skip ]
+fast/gradients/conic.html [ Skip ]
+fast/gradients/conic-off-center.html [ Skip ]
+fast/gradients/conic-center-outside-box.html [ Skip ]
+fast/gradients/conic-extended-stops.html [ Skip ]

Added: trunk/LayoutTests/fast/gradients/conic-center-outside-box-expected.html (0 => 235772)


--- trunk/LayoutTests/fast/gradients/conic-center-outside-box-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/gradients/conic-center-outside-box-expected.html	2018-09-07 01:36:36 UTC (rev 235772)
@@ -0,0 +1,14 @@
+<html>
+<head>
+    <style>
+        #box1 {
+            height: 50px;
+            width: 50px;
+            background-color: orange;
+        }
+    </style>
+</head>
+<body>
+    <div id="box1"></div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/gradients/conic-center-outside-box.html (0 => 235772)


--- trunk/LayoutTests/fast/gradients/conic-center-outside-box.html	                        (rev 0)
+++ trunk/LayoutTests/fast/gradients/conic-center-outside-box.html	2018-09-07 01:36:36 UTC (rev 235772)
@@ -0,0 +1,14 @@
+<html>
+<head>
+    <style>
+        #grad {
+            height: 50px;
+            width: 50px;
+            background: conic-gradient(at -10px -10px, blue 0deg, blue 90deg, orange 90deg, orange 180deg, green 180deg, green 270deg, blue 270deg, blue 360deg);
+        }
+    </style>
+</head>
+<body>
+    <div id="grad"></div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/gradients/conic-expected.html (0 => 235772)


--- trunk/LayoutTests/fast/gradients/conic-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/gradients/conic-expected.html	2018-09-07 01:36:36 UTC (rev 235772)
@@ -0,0 +1,24 @@
+<html>
+<head>
+    <style>
+        #box1 {
+            height: 50px;
+            width: 25px;
+            float: left;
+            background-color: orange;
+        }
+        #box2 {
+            height: 50px;
+            width: 25px;
+            float: left;
+            background-color: blue;
+        }
+    </style>
+</head>
+<body>
+    <div id="container">
+        <div id="box1"></div>
+        <div id="box2"></div>
+    </div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/gradients/conic-extended-stops-expected.html (0 => 235772)


--- trunk/LayoutTests/fast/gradients/conic-extended-stops-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/gradients/conic-extended-stops-expected.html	2018-09-07 01:36:36 UTC (rev 235772)
@@ -0,0 +1,31 @@
+<html>
+<head>
+    <style>
+        div {
+            float: left;
+        }
+        #box1 {
+            height: 25px;
+            width: 50px;
+            float: left;
+            background-color: blue;
+        }
+        #box2 {
+            height: 25px;
+            width: 25px;
+            clear: left;
+            background-color: green;
+        }
+        #box3 {
+            height: 25px;
+            width: 25px;
+            background-color: orange;
+        }
+    </style>
+</head>
+<body>
+    <div id="box1"></div>
+    <div id="box2"></div>
+    <div id="box3"></div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/gradients/conic-extended-stops.html (0 => 235772)


--- trunk/LayoutTests/fast/gradients/conic-extended-stops.html	                        (rev 0)
+++ trunk/LayoutTests/fast/gradients/conic-extended-stops.html	2018-09-07 01:36:36 UTC (rev 235772)
@@ -0,0 +1,14 @@
+<html>
+<head>
+    <style>
+        #grad {
+            height: 50px;
+            width: 50px;
+            background: conic-gradient(blue -50deg, blue 90deg, orange 90deg, orange 180deg, green 180deg, green 270deg, blue 270deg, blue 540deg);
+        }
+    </style>
+</head>
+<body>
+    <div id="grad"></div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/gradients/conic-off-center-expected.html (0 => 235772)


--- trunk/LayoutTests/fast/gradients/conic-off-center-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/gradients/conic-off-center-expected.html	2018-09-07 01:36:36 UTC (rev 235772)
@@ -0,0 +1,31 @@
+<html>
+<head>
+    <style>
+        div {
+            float: left;
+        }
+        #box1 {
+            height: 10px;
+            width: 50px;
+            float: left;
+            background-color: blue;
+        }
+        #box2 {
+            height: 40px;
+            width: 10px;
+            clear: left;
+            background-color: green;
+        }
+        #box3 {
+            height: 40px;
+            width: 40px;
+            background-color: orange;
+        }
+    </style>
+</head>
+<body>
+    <div id="box1"></div>
+    <div id="box2"></div>
+    <div id="box3"></div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/gradients/conic-off-center.html (0 => 235772)


--- trunk/LayoutTests/fast/gradients/conic-off-center.html	                        (rev 0)
+++ trunk/LayoutTests/fast/gradients/conic-off-center.html	2018-09-07 01:36:36 UTC (rev 235772)
@@ -0,0 +1,14 @@
+<html>
+<head>
+    <style>
+        #grad {
+            height: 50px;
+            width: 50px;
+            background: conic-gradient(at 10px 10px, blue 0deg, blue 90deg, orange 90deg, orange 180deg, green 180deg, green 270deg, blue 270deg, blue 360deg);
+        }
+    </style>
+</head>
+<body>
+    <div id="grad"></div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/gradients/conic-repeating-expected.html (0 => 235772)


--- trunk/LayoutTests/fast/gradients/conic-repeating-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/gradients/conic-repeating-expected.html	2018-09-07 01:36:36 UTC (rev 235772)
@@ -0,0 +1,32 @@
+<html>
+<head>
+    <style>
+        div {
+            width: 50px;
+            height: 50px;
+            float: left;
+        }
+
+        #box1 {
+            background-color: orange;
+        }
+        #box2 {
+            background-color: blue;
+        }
+        #box3 {
+            clear: left;
+            background-color: blue;
+        }
+        #box4 {
+            background-color: orange;
+        }
+        
+    </style>
+</head>
+<body>
+    <div id="box1"></div>
+    <div id="box2"></div>
+    <div id="box3"></div>
+    <div id="box4"></div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/gradients/conic-repeating.html (0 => 235772)


--- trunk/LayoutTests/fast/gradients/conic-repeating.html	                        (rev 0)
+++ trunk/LayoutTests/fast/gradients/conic-repeating.html	2018-09-07 01:36:36 UTC (rev 235772)
@@ -0,0 +1,17 @@
+<html>
+<head>
+    <style>
+        #grad {
+            height: 100px;
+            width: 100px;
+            background: repeating-conic-gradient(
+                  blue 0deg, blue 90deg,
+                  orange 0deg, orange 180deg
+              );
+        }
+    </style>
+</head>
+<body>
+    <div id="grad"></div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/gradients/conic.html (0 => 235772)


--- trunk/LayoutTests/fast/gradients/conic.html	                        (rev 0)
+++ trunk/LayoutTests/fast/gradients/conic.html	2018-09-07 01:36:36 UTC (rev 235772)
@@ -0,0 +1,14 @@
+<html>
+<head>
+    <style>
+        #grad {
+            height: 50px;
+            width: 50px;
+            background: conic-gradient(blue 0deg, blue 180deg, orange 180deg, orange 360deg);
+        }
+    </style>
+</head>
+<body>
+    <div id="grad"></div>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/ios-12/TestExpectations (235771 => 235772)


--- trunk/LayoutTests/platform/ios-12/TestExpectations	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/LayoutTests/platform/ios-12/TestExpectations	2018-09-07 01:36:36 UTC (rev 235772)
@@ -25,3 +25,10 @@
 
 # <rdar://problem/41546970> REGRESSION: LayoutTest media/media-fullscreen-loop-inline.html is a flaky timeout
 media/media-fullscreen-loop-inline.html [ Pass Timeout ]
+
+# < iOS12 doesn't support the CG needed for Conic Gradients
+fast/gradients/conic-repeating.html [ Pass ]
+fast/gradients/conic.html [ Pass ]
+fast/gradients/conic-off-center.html [ Pass ]
+fast/gradients/conic-center-outside-box.html [ Pass ]
+fast/gradients/conic-extended-stops.html [ Pass ]
\ No newline at end of file

Modified: trunk/LayoutTests/platform/mac/TestExpectations (235771 => 235772)


--- trunk/LayoutTests/platform/mac/TestExpectations	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/LayoutTests/platform/mac/TestExpectations	2018-09-07 01:36:36 UTC (rev 235772)
@@ -1756,3 +1756,11 @@
 [ Mojave+ ] fast/inline/break-between-nobr.html [ ImageOnlyFailure ]
 [ Mojave+ ] imported/blink/fast/text/international/text-shaping-arabic.html [ ImageOnlyFailure ]
 [ Mojave+ ] imported/blink/fast/text/international/vertical-positioning-with-combining-marks.html [ ImageOnlyFailure ]
+
+# < Mojave doesn't support the CG needed for Conic Gradients
+[ Mojave+ ] fast/gradients/conic-repeating.html [ Pass ]
+[ Mojave+ ] fast/gradients/conic.html [ Pass ]
+[ Mojave+ ] fast/gradients/conic-off-center.html [ Pass ]
+[ Mojave+ ] fast/gradients/conic-center-outside-box.html [ Pass ]
+[ Mojave+ ] fast/gradients/conic-extended-stops.html [ Pass ]
+

Modified: trunk/Source/WebCore/ChangeLog (235771 => 235772)


--- trunk/Source/WebCore/ChangeLog	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/Source/WebCore/ChangeLog	2018-09-07 01:36:36 UTC (rev 235772)
@@ -1,3 +1,54 @@
+2018-09-06  Megan Gardner  <[email protected]>
+
+        Add Support for Conic Gradients
+        https://bugs.webkit.org/show_bug.cgi?id=189329
+        <rdar://problem/21444701>
+
+        Reviewed by Simon Fraser.
+
+        Add support for rendering CSS conic gradients.
+        The parsing work was already done, this just hooks up the data we have
+        with the CG functionality for conic gradients. Add the needed plumbing
+        to allow for this additional type and fill in the creation of 
+        a conic gradient.
+
+        Tests: fast/gradients/conic-repeating.html
+               fast/gradients/conic.html
+
+        * css/CSSGradientValue.cpp:
+        (WebCore::createGradient):
+        (WebCore::LinearGradientAdapter::gradientLength const):
+        (WebCore::RadialGradientAdapter::gradientLength const):
+        (WebCore::ConicGradientAdapter::ConicGradientAdapter):
+        (WebCore::ConicGradientAdapter::gradientLength const):
+        (WebCore::ConicGradientAdapter::maxExtent const):
+        (WebCore::ConicGradientAdapter::normalizeStopsAndEndpointsOutsideRange):
+
+        Compute what the color stops should be if they extend past 0-1
+
+        (WebCore::CSSGradientValue::computeStops):
+        (WebCore::CSSConicGradientValue::createGradient):
+        (WebCore::LinearGradientAdapter::startPoint const): Deleted.
+        (WebCore::LinearGradientAdapter::endPoint const): Deleted.
+        (WebCore::RadialGradientAdapter::startPoint const): Deleted.
+        (WebCore::RadialGradientAdapter::endPoint const): Deleted.
+
+        Start and End points weren't very universal. All we really need from these
+        gradientAdapters is their length, so just ask for that instead.
+
+        * inspector/InspectorCanvas.cpp:
+        (WebCore::InspectorCanvas::buildArrayForCanvasGradient):
+        * platform/graphics/Gradient.cpp:
+        (WebCore::Gradient::create):
+        (WebCore::Gradient::Gradient):
+        (WebCore::Gradient::type const):
+        (WebCore::Gradient::adjustParametersForTiledDrawing):
+        (WebCore::Gradient::isZeroSize const):
+        (WebCore::Gradient::hash const):
+        * platform/graphics/Gradient.h:
+        * platform/graphics/cg/GradientCG.cpp:
+        (WebCore::Gradient::paint):
+
 2018-09-06  Wenson Hsieh  <[email protected]>
 
         [macOS] [WK2] Support changing attributes for selected text (text shadow, underline, strike-through)

Modified: trunk/Source/WebCore/PAL/ChangeLog (235771 => 235772)


--- trunk/Source/WebCore/PAL/ChangeLog	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/Source/WebCore/PAL/ChangeLog	2018-09-07 01:36:36 UTC (rev 235772)
@@ -1,3 +1,15 @@
+2018-09-06  Megan Gardner  <[email protected]>
+
+        Add Support for Conic Gradients
+        https://bugs.webkit.org/show_bug.cgi?id=189329
+        <rdar://problem/21444701>
+
+        Reviewed by Simon Fraser.
+
+        Define the CG functionality for conic gradients. 
+
+        * pal/spi/cg/CoreGraphicsSPI.h:
+
 2018-09-04  Ryan Haddad  <[email protected]>
 
         Unreviewed, attempt to fix an internal build after r235585.

Modified: trunk/Source/WebCore/PAL/pal/spi/cg/CoreGraphicsSPI.h (235771 => 235772)


--- trunk/Source/WebCore/PAL/pal/spi/cg/CoreGraphicsSPI.h	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/Source/WebCore/PAL/pal/spi/cg/CoreGraphicsSPI.h	2018-09-07 01:36:36 UTC (rev 235772)
@@ -279,6 +279,8 @@
 CGSRegionEnumeratorObj CGSRegionEnumerator(CGRegionRef);
 CGStyleRef CGStyleCreateFocusRingWithColor(const CGFocusRingStyle*, CGColorRef);
 void CGContextSetStyle(CGContextRef, CGStyleRef);
+
+void CGContextDrawConicGradient(CGContextRef, CGGradientRef, CGPoint center, CGFloat angle);
 #endif
 
 #if PLATFORM(WIN)

Modified: trunk/Source/WebCore/css/CSSGradientValue.cpp (235771 => 235772)


--- trunk/Source/WebCore/css/CSSGradientValue.cpp	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/Source/WebCore/css/CSSGradientValue.cpp	2018-09-07 01:36:36 UTC (rev 235772)
@@ -45,7 +45,9 @@
 {
     if (is<CSSLinearGradientValue>(value))
         return downcast<CSSLinearGradientValue>(value).createGradient(renderer, size);
-    return downcast<CSSRadialGradientValue>(value).createGradient(renderer, size);
+    if (is<CSSRadialGradientValue>(value))
+        return downcast<CSSRadialGradientValue>(value).createGradient(renderer, size);
+    return downcast<CSSConicGradientValue>(value).createGradient(renderer, size);
 }
 
 RefPtr<Image> CSSGradientValue::image(RenderElement& renderer, const FloatSize& size)
@@ -125,9 +127,12 @@
         : m_data(data)
     {
     }
-
-    FloatPoint startPoint() const { return m_data.point0; }
-    FloatPoint endPoint() const { return m_data.point1; }
+    
+    float gradientLength() const
+    {
+        auto gradientSize = m_data.point0 - m_data.point1;
+        return gradientSize.diagonalLength();
+    }
     float maxExtent(float, float) const { return 1; }
 
     void normalizeStopsAndEndpointsOutsideRange(Vector<GradientStop>& stops)
@@ -162,8 +167,7 @@
     {
     }
 
-    FloatPoint startPoint() const { return m_data.point0; }
-    FloatPoint endPoint() const { return m_data.point0 + FloatSize { m_data.endRadius, 0 }; }
+    float gradientLength() const { return m_data.endRadius; }
 
     // Radial gradients may need to extend further than the endpoints, because they have
     // to repeat out to the corners of the box.
@@ -224,8 +228,78 @@
     Gradient::RadialData& m_data;
 };
 
+class ConicGradientAdapter {
+public:
+    explicit ConicGradientAdapter() { }
+    float gradientLength() const { return 1; }
+    float maxExtent(float, float) const { return 1; }
+
+    void normalizeStopsAndEndpointsOutsideRange(Vector<GradientStop>& stops)
+    {
+        auto numStops = stops.size();
+        
+        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;
+            }
+        }
+
+        size_t lastOneOrLessIndex = numStops;
+        for (int i = numStops - 1; i >= 0; --i) {
+            if (stops[i].offset <= 1) {
+                lastOneOrLessIndex = i;
+                break;
+            }
+        }
+        
+        if (lastOneOrLessIndex < numStops - 1) {
+            if (lastOneOrLessIndex < numStops && stops[lastOneOrLessIndex].offset < 1) {
+                float prevOffset = stops[lastOneOrLessIndex].offset;
+                float nextOffset = stops[lastOneOrLessIndex + 1].offset;
+                
+                float interStopProportion = 1 / (nextOffset - prevOffset);
+                // FIXME: when we interpolate gradients using premultiplied colors, this should do premultiplication.
+                Color blendedColor = blend(stops[lastOneOrLessIndex].color, stops[lastOneOrLessIndex + 1].color, interStopProportion);
+                
+                // Clamp the positions to 1 and set the color.
+                for (size_t i = lastOneOrLessIndex + 1; i < numStops; ++i) {
+                    stops[i].offset = 1;
+                    stops[i].color = blendedColor;
+                }
+            } else {
+                // All stops are above 1; just clamp them.
+                for (size_t i = lastOneOrLessIndex; i < numStops; ++i)
+                    stops[i].offset = 1;
+            }
+        }
+    }
+};
+
 template<typename GradientAdapter>
-Gradient::ColorStopVector CSSGradientValue::computeStops(GradientAdapter& gradient, const CSSToLengthConversionData& conversionData, const RenderStyle& style, float maxLengthForRepeat)
+Gradient::ColorStopVector CSSGradientValue::computeStops(GradientAdapter& gradientAdapter, const CSSToLengthConversionData& conversionData, const RenderStyle& style, float maxLengthForRepeat)
 {
     if (m_gradientType == CSSDeprecatedLinearGradient || m_gradientType == CSSDeprecatedRadialGradient) {
         sortStopsIfNeeded();
@@ -252,12 +326,8 @@
     size_t numStops = m_stops.size();
     Vector<GradientStop> stops(numStops);
 
-    auto gradientStart = gradient.startPoint();
-    auto gradientEnd = gradient.endPoint();
+    float gradientLength = gradientAdapter.gradientLength();
 
-    auto gradientSize = gradientStart - gradientEnd;
-    float gradientLength = gradientSize.diagonalLength();
-
     for (size_t i = 0; i < numStops; ++i) {
         auto& stop = m_stops[i];
 
@@ -282,7 +352,9 @@
                     length = calculationValue->evaluate(gradientLength);
                 }
                 stops[i].offset = (gradientLength > 0) ? length / gradientLength : 0;
-            } else {
+            } else if (positionValue.isAngle())
+                stops[i].offset = positionValue.floatValue(CSSPrimitiveValue::CSS_DEG) / 360;
+            else {
                 ASSERT_NOT_REACHED();
                 stops[i].offset = 0;
             }
@@ -438,7 +510,7 @@
             stops.shrink(1);
             numStops = 1;
         } else {
-            float maxExtent = gradient.maxExtent(maxLengthForRepeat, gradientLength);
+            float maxExtent = gradientAdapter.maxExtent(maxLengthForRepeat, gradientLength);
 
             size_t originalNumStops = numStops;
             size_t originalFirstStopIndex = 0;
@@ -486,7 +558,7 @@
 
     // If the gradient goes outside the 0-1 range, normalize it by moving the endpoints, and adjusting the stops.
     if (stops.size() > 1 && (stops.first().offset < 0 || stops.last().offset > 1))
-        gradient.normalizeStopsAndEndpointsOutsideRange(stops);
+        gradientAdapter.normalizeStopsAndEndpointsOutsideRange(stops);
     
     Gradient::ColorStopVector result;
     result.reserveInitialCapacity(stops.size());
@@ -1350,10 +1422,29 @@
     return result.toString();
 }
 
-Ref<Gradient> CSSConicGradientValue::createGradient(RenderElement&, const FloatSize&)
+Ref<Gradient> CSSConicGradientValue::createGradient(RenderElement& renderer, const FloatSize& size)
 {
-    // FIXME: Implement.
-    return Gradient::create(Gradient::LinearData { });
+    ASSERT(!size.isEmpty());
+
+    CSSToLengthConversionData conversionData(&renderer.style(), renderer.document().documentElement()->renderStyle(), &renderer.view());
+
+    FloatPoint centerPoint = computeEndPoint(m_firstX.get(), m_firstY.get(), conversionData, size);
+    if (!m_firstX)
+        centerPoint.setX(size.width() / 2);
+    if (!m_firstY)
+        centerPoint.setY(size.height() / 2);
+
+    float angle = 0;
+    if (m_angle)
+        angle = m_angle->floatValue(CSSPrimitiveValue::CSS_DEG);
+
+    Gradient::ConicData data { centerPoint, angle };
+    ConicGradientAdapter adapter;
+    auto stops = computeStops(adapter, conversionData, renderer.style(), 1);
+
+    auto gradient = Gradient::create(WTFMove(data));
+    gradient->setSortedColorStops(WTFMove(stops));
+    return gradient;
 }
 
 bool CSSConicGradientValue::equals(const CSSConicGradientValue& other) const

Modified: trunk/Source/WebCore/inspector/InspectorCanvas.cpp (235771 => 235772)


--- trunk/Source/WebCore/inspector/InspectorCanvas.cpp	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/Source/WebCore/inspector/InspectorCanvas.cpp	2018-09-07 01:36:36 UTC (rev 235772)
@@ -613,9 +613,9 @@
 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;
 
-    String type = gradient.type() == Gradient::Type::Radial ? "radial-gradient"_s : "linear-gradient"_s;
-
     auto parameters = JSON::ArrayOf<float>::create();
     WTF::switchOn(gradient.data(),
         [&parameters] (const Gradient::LinearData& data) {
@@ -631,6 +631,11 @@
             parameters->addItem(data.point1.x());
             parameters->addItem(data.point1.y());
             parameters->addItem(data.endRadius);
+        },
+        [&parameters] (const Gradient::ConicData& data) {
+            parameters->addItem(data.point0.x());
+            parameters->addItem(data.point0.y());
+            parameters->addItem(data.angle);
         }
     );
 

Modified: trunk/Source/WebCore/page/Settings.yaml (235771 => 235772)


--- trunk/Source/WebCore/page/Settings.yaml	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/Source/WebCore/page/Settings.yaml	2018-09-07 01:36:36 UTC (rev 235772)
@@ -525,7 +525,7 @@
   initial: false
 
 conicGradientsEnabled:
-  initial: false
+  initial: defaultConicGradient
 
 colorFilterEnabled:
   initial: false

Modified: trunk/Source/WebCore/page/SettingsDefaultValues.h (235771 => 235772)


--- trunk/Source/WebCore/page/SettingsDefaultValues.h	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/Source/WebCore/page/SettingsDefaultValues.h	2018-09-07 01:36:36 UTC (rev 235772)
@@ -103,5 +103,12 @@
 #else
 static const bool defaultMediaEnabled = false;
 #endif
+    
+#if (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 120000) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400) || PLATFORM(WATCHOS)
+static const bool defaultConicGradient = true;
+#else
+static const bool defaultConicGradient = false;
+#endif
+    
 
 }

Modified: trunk/Source/WebCore/platform/graphics/Gradient.cpp (235771 => 235772)


--- trunk/Source/WebCore/platform/graphics/Gradient.cpp	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/Source/WebCore/platform/graphics/Gradient.cpp	2018-09-07 01:36:36 UTC (rev 235772)
@@ -46,6 +46,11 @@
     return adoptRef(*new Gradient(WTFMove(data)));
 }
 
+Ref<Gradient> Gradient::create(ConicData&& data)
+{
+    return adoptRef(*new Gradient(WTFMove(data)));
+}
+
 Gradient::Gradient(LinearData&& data)
     : m_data(WTFMove(data))
 {
@@ -57,6 +62,12 @@
 {
     platformInit();
 }
+    
+Gradient::Gradient(ConicData&& data)
+    : m_data(WTFMove(data))
+{
+    platformInit();
+}
 
 Gradient::~Gradient()
 {
@@ -71,6 +82,9 @@
         },
         [] (const RadialData&) {
             return Type::Radial;
+        },
+        [] (const ConicData&) {
+            return Type::Conic;
         }
     );
 }
@@ -99,6 +113,8 @@
             srcRect.setY(0);
         },
         [] (const RadialData&) {
+        },
+        [] (const ConicData&) {
         }
     );
 }
@@ -111,6 +127,9 @@
         },
         [] (const RadialData& data) {
             return data.point0.x() == data.point1.x() && data.point0.y() == data.point1.y() && data.startRadius == data.endRadius;
+        },
+        [] (const ConicData&) {
+            return false;
         }
     );
 }
@@ -204,6 +223,7 @@
         float startRadius;
         float endRadius;
         float aspectRatio;
+        float angle;
         GradientSpreadMethod spreadMethod;
         AffineTransform gradientSpaceTransformation;
     } parameters;
@@ -223,6 +243,7 @@
             parameters.startRadius = 0;
             parameters.endRadius = 0;
             parameters.aspectRatio = 0;
+            parameters.angle = 0;
             parameters.type = Type::Linear;
         },
         [&parameters] (const RadialData& data) {
@@ -231,7 +252,17 @@
             parameters.startRadius = data.startRadius;
             parameters.endRadius = data.endRadius;
             parameters.aspectRatio = data.aspectRatio;
+            parameters.angle = 0;
             parameters.type = Type::Radial;
+        },
+        [&parameters] (const ConicData& data) {
+            parameters.point0 = data.point0;
+            parameters.point1 = {0, 0};
+            parameters.startRadius = 0;
+            parameters.endRadius = 0;
+            parameters.aspectRatio = 0;
+            parameters.angle = data.angle;
+            parameters.type = Type::Conic;
         }
     );
 

Modified: trunk/Source/WebCore/platform/graphics/Gradient.h (235771 => 235772)


--- trunk/Source/WebCore/platform/graphics/Gradient.h	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/Source/WebCore/platform/graphics/Gradient.h	2018-09-07 01:36:36 UTC (rev 235772)
@@ -85,13 +85,19 @@
         float endRadius;
         float aspectRatio; // For elliptical gradient, width / height.
     };
+    
+    struct ConicData {
+        FloatPoint point0;
+        float angle;
+    };
 
-    using Data = "" RadialData>;
+    using Data = "" RadialData, ConicData>;
 
-    enum class Type { Linear, Radial };
+    enum class Type { Linear, Radial, Conic };
 
     static Ref<Gradient> create(LinearData&&);
     static Ref<Gradient> create(RadialData&&);
+    static Ref<Gradient> create(ConicData&&);
 
     WEBCORE_EXPORT ~Gradient();
 
@@ -133,6 +139,7 @@
 private:
     Gradient(LinearData&&);
     Gradient(RadialData&&);
+    Gradient(ConicData&&);
 
     PlatformGradient platformGradient();
     void platformInit() { m_gradient = nullptr; }

Modified: trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp (235771 => 235772)


--- trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/Source/WebCore/platform/graphics/cg/GradientCG.cpp	2018-09-07 01:36:36 UTC (rev 235772)
@@ -127,6 +127,18 @@
 
             if (needScaling)
                 CGContextRestoreGState(platformContext);
+        },
+        [&] (const ConicData& data) {
+#if (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 120000) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400) || PLATFORM(WATCHOS)
+            CGContextSaveGState(platformContext);
+            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.angle);
+            CGContextRestoreGState(platformContext);
+#else
+            UNUSED_PARAM(data);
+#endif
         }
     );
 }

Modified: trunk/Source/WebKit/ChangeLog (235771 => 235772)


--- trunk/Source/WebKit/ChangeLog	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/Source/WebKit/ChangeLog	2018-09-07 01:36:36 UTC (rev 235772)
@@ -1,3 +1,16 @@
+2018-09-06  Megan Gardner  <[email protected]>
+
+        Add Support for Conic Gradients
+        https://bugs.webkit.org/show_bug.cgi?id=189329
+        <rdar://problem/21444701>
+
+        Reviewed by Simon Fraser.
+
+        Connect up web preferences to allow conic gradients to be turned on in the
+        experimental features menu.
+
+        * Shared/WebPreferences.yaml:
+
 2018-09-06  Wenson Hsieh  <[email protected]>
 
         [macOS] [WK2] Support changing attributes for selected text (text shadow, underline, strike-through)

Modified: trunk/Source/WebKit/Shared/WebPreferences.yaml (235771 => 235772)


--- trunk/Source/WebKit/Shared/WebPreferences.yaml	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/Source/WebKit/Shared/WebPreferences.yaml	2018-09-07 01:36:36 UTC (rev 235772)
@@ -1148,6 +1148,13 @@
   humanReadableDescription: "CSS Spring Animation prototype"
   category: experimental
 
+ConicGradientsEnabled:
+    type: bool
+    defaultValue: DEFAULT_CONIC_GRADIENT_ENABLED
+    humanReadableName: "CSS Conic Gradient"
+    humanReadableDescription: "Support for CSS Conic Gradients"
+    category: experimental
+
 ImageBitmapOffscreenCanvasEnabled:
   type: bool
   defaultValue: DEFAULT_EXPERIMENTAL_FEATURES_ENABLED

Modified: trunk/Source/WebKit/Shared/WebPreferencesDefaultValues.h (235771 => 235772)


--- trunk/Source/WebKit/Shared/WebPreferencesDefaultValues.h	2018-09-07 00:24:51 UTC (rev 235771)
+++ trunk/Source/WebKit/Shared/WebPreferencesDefaultValues.h	2018-09-07 01:36:36 UTC (rev 235772)
@@ -209,5 +209,11 @@
 #define DEFAULT_SERVICE_WORKERS_ENABLED false
 #endif
 
+#if (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 120000) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400) || PLATFORM(WATCHOS)
+#define DEFAULT_CONIC_GRADIENT_ENABLED true
+#else
+#define DEFAULT_CONIC_GRADIENT_ENABLED false
+#endif
+
 bool defaultPassiveTouchListenersAsDefaultOnDocument();
 bool defaultCustomPasteboardDataEnabled();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to