Title: [275055] trunk
Revision
275055
Author
[email protected]
Date
2021-03-25 13:46:08 -0700 (Thu, 25 Mar 2021)

Log Message

Source/WebCore:
Fix edge cases in normalization of conic-gradient color stops
https://bugs.webkit.org/show_bug.cgi?id=221294
<rdar://problem/74157218>

Patch by Tim Nguyen <[email protected]> on 2021-03-25
Reviewed by Darin Adler.

`lastOneOrLessIndex` had an off-by-one error, so it did not go through the
branch handling clamping all the stop offsets when they're all above 1.

Also made `normalizeStopsAndEndpointsOutsideRange` logic easier to follow using
`Optional<size_t>` instead of placeholder values.

Test: web-platform-tests/css/css-images/normalization-conic-2.html

* css/CSSGradientValue.cpp:
(WebCore::ConicGradientAdapter::normalizeStopsAndEndpointsOutsideRange):

LayoutTests:
Enable normalization-conic-2.html WPT now that underlying bug is fixed.
Also skip some conic-gradient tests only on Windows instead of all platforms.
https://bugs.webkit.org/show_bug.cgi?id=221294
<rdar://problem/74157218>

Patch by Tim Nguyen <[email protected]> on 2021-03-25
Reviewed by Darin Adler.

* TestExpectations: enabled imported/w3c/web-platform-tests/css/css-images/normalization-conic-2.html.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (275054 => 275055)


--- trunk/LayoutTests/ChangeLog	2021-03-25 20:22:10 UTC (rev 275054)
+++ trunk/LayoutTests/ChangeLog	2021-03-25 20:46:08 UTC (rev 275055)
@@ -1,3 +1,14 @@
+2021-03-25  Tim Nguyen  <[email protected]>
+
+        Enable normalization-conic-2.html WPT now that underlying bug is fixed.
+        Also skip some conic-gradient tests only on Windows instead of all platforms.
+        https://bugs.webkit.org/show_bug.cgi?id=221294
+        <rdar://problem/74157218>
+
+        Reviewed by Darin Adler.
+
+        * TestExpectations: enabled imported/w3c/web-platform-tests/css/css-images/normalization-conic-2.html.
+
 2021-03-25  Robert Jenner  <[email protected]>
 
         [ Debug wk2 ] ASSERTION FAILED: willBeComposited == needsToBeComposited(layer, queryData)

Modified: trunk/LayoutTests/TestExpectations (275054 => 275055)


--- trunk/LayoutTests/TestExpectations	2021-03-25 20:22:10 UTC (rev 275054)
+++ trunk/LayoutTests/TestExpectations	2021-03-25 20:46:08 UTC (rev 275055)
@@ -3010,18 +3010,6 @@
 imported/w3c/web-platform-tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html [ Skip ]
 imported/w3c/web-platform-tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html [ Skip ]
 
-http/wpt/css/css-images-4/conic-gradient-parsing.html [ Skip ]
-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 ]
-fast/gradients/conic-from-angle.html [ Skip ]
-fast/gradients/conic-repeating-last-stop.html [ Skip ]
-fast/gradients/conic-gradient-alpha.html [ Skip ]
-fast/gradients/conic-gradient-extended-stops.html [ Skip ]
-fast/gradients/conic-gradient.html [ Skip ]
-fast/gradients/conic-two-hints.html [ Skip ]
 imported/w3c/web-platform-tests/css/css-images/multiple-position-color-stop-conic.html [ ImageOnlyFailure ]
 
 webkit.org/b/187773 http/tests/webAPIStatistics [ Skip ]
@@ -4449,7 +4437,6 @@
 webkit.org/b/214456 imported/w3c/web-platform-tests/css/css-images/image-resolution/image-resolution-010.html [ ImageOnlyFailure ]
 webkit.org/b/214456 imported/w3c/web-platform-tests/css/css-images/infinite-radial-gradient-refcrash.html [ ImageOnlyFailure ]
 webkit.org/b/214456 imported/w3c/web-platform-tests/css/css-images/multiple-position-color-stop-conic-2.html [ ImageOnlyFailure ]
-webkit.org/b/214456 imported/w3c/web-platform-tests/css/css-images/normalization-conic-2.html [ ImageOnlyFailure ]
 webkit.org/b/214456 imported/w3c/web-platform-tests/css/css-images/normalization-linear.html [ ImageOnlyFailure ]
 webkit.org/b/214456 imported/w3c/web-platform-tests/css/css-images/normalization-radial.html [ ImageOnlyFailure ]
 webkit.org/b/214456 imported/w3c/web-platform-tests/css/css-images/out-of-range-color-stop-conic.html [ ImageOnlyFailure ]

Modified: trunk/LayoutTests/platform/win/TestExpectations (275054 => 275055)


--- trunk/LayoutTests/platform/win/TestExpectations	2021-03-25 20:22:10 UTC (rev 275054)
+++ trunk/LayoutTests/platform/win/TestExpectations	2021-03-25 20:46:08 UTC (rev 275055)
@@ -269,6 +269,20 @@
 accessibility/listbox-clear-selection.html [ Skip ]
 accessibility/embedded-image-description.html [ Skip ]
 
+# TODO Conic gradients
+http/wpt/css/css-images-4/conic-gradient-parsing.html [ Skip ]
+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 ]
+fast/gradients/conic-from-angle.html [ Skip ]
+fast/gradients/conic-repeating-last-stop.html [ Skip ]
+fast/gradients/conic-gradient-alpha.html [ Skip ]
+fast/gradients/conic-gradient-extended-stops.html [ Skip ]
+fast/gradients/conic-gradient.html [ Skip ]
+fast/gradients/conic-two-hints.html [ Skip ]
+
 # TODO Investigate why these mouse scroll tests are failing.
 fast/events/scroll-in-scaled-page-with-overflow-hidden.html [ Failure ]
 fast/events/wheel/continuous-platform-wheelevent-in-scrolling-div.html [ Failure ]

Modified: trunk/Source/WebCore/ChangeLog (275054 => 275055)


--- trunk/Source/WebCore/ChangeLog	2021-03-25 20:22:10 UTC (rev 275054)
+++ trunk/Source/WebCore/ChangeLog	2021-03-25 20:46:08 UTC (rev 275055)
@@ -1,3 +1,22 @@
+2021-03-25  Tim Nguyen  <[email protected]>
+
+        Fix edge cases in normalization of conic-gradient color stops
+        https://bugs.webkit.org/show_bug.cgi?id=221294
+        <rdar://problem/74157218>
+
+        Reviewed by Darin Adler.
+
+        `lastOneOrLessIndex` had an off-by-one error, so it did not go through the
+        branch handling clamping all the stop offsets when they're all above 1.
+
+        Also made `normalizeStopsAndEndpointsOutsideRange` logic easier to follow using
+        `Optional<size_t>` instead of placeholder values.
+
+        Test: web-platform-tests/css/css-images/normalization-conic-2.html
+
+        * css/CSSGradientValue.cpp:
+        (WebCore::ConicGradientAdapter::normalizeStopsAndEndpointsOutsideRange):
+
 2021-03-25  Chris Dumez  <[email protected]>
 
         Address some alignment issues found by UBSan in contentextensions code

Modified: trunk/Source/WebCore/css/CSSGradientValue.cpp (275054 => 275055)


--- trunk/Source/WebCore/css/CSSGradientValue.cpp	2021-03-25 20:22:10 UTC (rev 275054)
+++ trunk/Source/WebCore/css/CSSGradientValue.cpp	2021-03-25 20:46:08 UTC (rev 275055)
@@ -237,9 +237,10 @@
 
     void normalizeStopsAndEndpointsOutsideRange(Vector<GradientStop>& stops)
     {
-        auto numStops = stops.size();
-        
-        size_t firstZeroOrGreaterIndex = numStops;
+        size_t numStops = stops.size();
+        size_t lastStopIndex = numStops - 1;
+
+        Optional<size_t> firstZeroOrGreaterIndex;
         for (size_t i = 0; i < numStops; ++i) {
             if (*stops[i].offset >= 0) {
                 firstZeroOrGreaterIndex = i;
@@ -247,54 +248,56 @@
             }
         }
 
-        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);
+        if (firstZeroOrGreaterIndex) {
+            size_t index = *firstZeroOrGreaterIndex;
+            if (index > 0) {
+                float previousOffset = *stops[index - 1].offset;
+                float nextOffset = *stops[index].offset;
+
+                float interStopProportion = -previousOffset / (nextOffset - previousOffset);
                 // FIXME: when we interpolate gradients using premultiplied colors, this should do premultiplication.
-                Color blendedColor = blend(stops[firstZeroOrGreaterIndex - 1].color, stops[firstZeroOrGreaterIndex].color, interStopProportion);
-                
+                Color blendedColor = blend(stops[index - 1].color, stops[index].color, interStopProportion);
+
                 // Clamp the positions to 0 and set the color.
-                for (size_t i = 0; i < firstZeroOrGreaterIndex; ++i) {
+                for (size_t i = 0; i < index; ++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;
             }
+        } else {
+            // All stop offsets below 0, clamp them.
+            for (auto& stop : stops)
+                stop.offset = 0;
         }
 
-        size_t lastOneOrLessIndex = numStops;
-        for (int i = numStops - 1; i >= 0; --i) {
+        Optional<size_t> lastOneOrLessIndex;
+        for (int i = lastStopIndex; 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 - prevOffset) / (nextOffset - prevOffset);
+
+        if (lastOneOrLessIndex) {
+            size_t index = *lastOneOrLessIndex;
+            if (index < lastStopIndex) {
+                float previousOffset = *stops[index].offset;
+                float nextOffset = *stops[index + 1].offset;
+
+                float interStopProportion = (1 - previousOffset) / (nextOffset - previousOffset);
                 // FIXME: when we interpolate gradients using premultiplied colors, this should do premultiplication.
-                Color blendedColor = blend(stops[lastOneOrLessIndex].color, stops[lastOneOrLessIndex + 1].color, interStopProportion);
-                
+                Color blendedColor = blend(stops[index].color, stops[index + 1].color, interStopProportion);
+
                 // Clamp the positions to 1 and set the color.
-                for (size_t i = lastOneOrLessIndex + 1; i < numStops; ++i) {
+                for (size_t i = index + 1; i <= lastStopIndex; ++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;
             }
+        } else {
+            // All stop offsets above 1, clamp them.
+            for (auto& stop : stops)
+                stop.offset = 1;
         }
     }
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to