Title: [190984] releases/WebKitGTK/webkit-2.10
Revision
190984
Author
[email protected]
Date
2015-10-13 06:29:00 -0700 (Tue, 13 Oct 2015)

Log Message

Merge r190879 - Clip-path transitions sometimes trigger endless animation timers
https://bugs.webkit.org/show_bug.cgi?id=150018

Reviewed by Tim Horton.

Source/WebCore:

Transitioning -webkit-clip-path could trigger endless animation
timers, because when CompositeAnimation::updateTransitions() calls
isTargetPropertyEqual(), a false negative answer triggers canceling the
current transition and starting a new one over and over.

This happened because StyleRareNonInheritedData simply tested pointer
equality for m_clipPath and m_shapeOutside. Both of these need to do deep
equality testing, requiring the implementation of operator== in BasicShapes
classes.

In addition, the PropertyWrappers in CSSPropertyAnimation need equals()
implementations that also do more than pointer equality testing.

Tests: transitions/clip-path-transitions.html
       transitions/shape-outside-transitions.html

* page/animation/CSSPropertyAnimation.cpp:
(WebCore::PropertyWrapperClipPath::equals):
(WebCore::PropertyWrapperShape::equals):
* rendering/ClipPathOperation.h:
* rendering/style/BasicShapes.cpp:
(WebCore::BasicShapeCircle::operator==):
(WebCore::BasicShapeEllipse::operator==):
(WebCore::BasicShapePolygon::operator==):
(WebCore::BasicShapeInset::operator==):
* rendering/style/BasicShapes.h:
(WebCore::BasicShapeCenterCoordinate::operator==):
(WebCore::BasicShapeRadius::operator==):
* rendering/style/ShapeValue.cpp:
(WebCore::pointersOrValuesEqual):
(WebCore::ShapeValue::operator==):
* rendering/style/ShapeValue.h:
(WebCore::ShapeValue::operator!=):
(WebCore::ShapeValue::operator==): Deleted.
(WebCore::ShapeValue::ShapeValue): Deleted.
* rendering/style/StyleRareNonInheritedData.cpp:
(WebCore::StyleRareNonInheritedData::operator==):
(WebCore::StyleRareNonInheritedData::clipPathOperationsEquivalent):
(WebCore::StyleRareNonInheritedData::shapeOutsideDataEquivalent):
* rendering/style/StyleRareNonInheritedData.h:

LayoutTests:

New tests for transitions of clip-path and shape-outside.

* transitions/clip-path-transitions-expected.txt: Added.
* transitions/clip-path-transitions.html: Added.
* transitions/resources/transition-test-helpers.js:
(parseClipPath):
(checkExpectedValue):
* transitions/shape-outside-transitions-expected.txt: Added.
* transitions/shape-outside-transitions.html: Added.
* transitions/svg-transitions-expected.txt:

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog (190983 => 190984)


--- releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog	2015-10-13 13:12:25 UTC (rev 190983)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog	2015-10-13 13:29:00 UTC (rev 190984)
@@ -1,3 +1,21 @@
+2015-10-12  Simon Fraser  <[email protected]>
+
+        Clip-path transitions sometimes trigger endless animation timers
+        https://bugs.webkit.org/show_bug.cgi?id=150018
+
+        Reviewed by Tim Horton.
+        
+        New tests for transitions of clip-path and shape-outside.
+
+        * transitions/clip-path-transitions-expected.txt: Added.
+        * transitions/clip-path-transitions.html: Added.
+        * transitions/resources/transition-test-helpers.js:
+        (parseClipPath):
+        (checkExpectedValue):
+        * transitions/shape-outside-transitions-expected.txt: Added.
+        * transitions/shape-outside-transitions.html: Added.
+        * transitions/svg-transitions-expected.txt:
+
 2015-10-09  Simon Fraser  <[email protected]>
 
         Garbage texture data with composited table row

Added: releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/clip-path-transitions-expected.txt (0 => 190984)


--- releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/clip-path-transitions-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/clip-path-transitions-expected.txt	2015-10-13 13:29:00 UTC (rev 190984)
@@ -0,0 +1,5 @@
+PASS - "-webkit-clip-path" property for "circle" element at 0.5s saw something close to: circle(60px at 50px 40px)
+PASS - "-webkit-clip-path" property for "ellipse" element at 0.5s saw something close to: ellipse(15px 30px at 50px 40px)
+PASS - "-webkit-clip-path" property for "inset" element at 0.5s saw something close to: inset(15px 22px)
+PASS - "-webkit-clip-path" property for "polygon" element at 0.5s saw something close to: polygon(15px 0px, 75px 0, 60px 45px, 0 45px)
+

Added: releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/clip-path-transitions.html (0 => 190984)


--- releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/clip-path-transitions.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/clip-path-transitions.html	2015-10-13 13:29:00 UTC (rev 190984)
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style>
+    .box {
+        height: 100px;
+        width: 100px;
+        margin: 50px;
+        background-color: gray;
+        -webkit-transition-duration: 1s;
+        -webkit-transition-timing-function: linear;
+        -webkit-transition-property: -webkit-clip-path;
+    }
+    
+    #circle {
+        -webkit-clip-path: circle(100px at 50px 30px);
+    }
+    
+    body.final #circle {
+        -webkit-clip-path: circle(20px at 50px 50px);
+    }
+
+    #ellipse {
+        -webkit-clip-path: ellipse(10px 20px at 50px 30px);
+    }
+    
+    body.final #ellipse {
+        -webkit-clip-path: ellipse(20px 40px at 50px 50px);
+    }
+
+    #inset {
+        -webkit-clip-path: inset(10px 20px);
+    }
+    
+    body.final #inset {
+        -webkit-clip-path: inset(20px 24px);
+    }
+
+    #polygon {
+        -webkit-clip-path: polygon(20px 0px, 100px 0, 100px 50px, 0 50px);
+    }
+    
+    body.final #polygon {
+        -webkit-clip-path: polygon(10px 0px, 50px 0, 20px 40px, 0 40px);
+    }
+  </style>
+  <script src=""
+  <script type="text/_javascript_">
+
+    const expectedValues = [
+      // [time, element-id, property, expected-value, tolerance]
+      [0.5, 'circle', '-webkit-clip-path', 'circle(60px at 50px 40px)', 1],
+      [0.5, 'ellipse', '-webkit-clip-path', 'ellipse(15px 30px at 50px 40px)', 1],
+      [0.5, 'inset', '-webkit-clip-path', 'inset(15px 22px)', 1],
+      [0.5, 'polygon', '-webkit-clip-path', 'polygon(15px 0px, 75px 0, 60px 45px, 0 45px)', 1],
+    ];
+  
+    function setupTest()
+    {
+        document.body.classList.add('final');
+    }
+    
+    runTransitionTest(expectedValues, setupTest, usePauseAPI);
+  </script>
+</head>
+<body>
+  <div id="circle" class="box"></div>
+  <div id="ellipse" class="box"></div>
+  <div id="inset" class="box"></div>
+  <div id="polygon" class="box"></div>
+
+  <div id="result"></div>
+
+</body>
+</html>

Modified: releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/resources/transition-test-helpers.js (190983 => 190984)


--- releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/resources/transition-test-helpers.js	2015-10-13 13:12:25 UTC (rev 190983)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/resources/transition-test-helpers.js	2015-10-13 13:29:00 UTC (rev 190984)
@@ -69,6 +69,29 @@
     return {"from": matches[1], "to": matches[2], "percent": parseFloat(matches[3])}
 }
 
+function parseClipPath(s)
+{
+    // FIXME: This only matches a subset of the shape syntax, and the polygon expects 4 points.
+    var patterns = [
+        /inset\(([\d.]+)\w+ ([\d.]+)\w+\)/,
+        /circle\(([\d.]+)\w+ at ([\d.]+)\w+ ([\d.]+)\w+\)/,
+        /ellipse\(([\d.]+)\w+ ([\d.]+)\w+ at ([\d.]+)\w+ ([\d.]+)\w+\)/,
+        /polygon\(([\d.]+)\w* ([\d.]+)\w*\, ([\d.]+)\w* ([\d.]+)\w*\, ([\d.]+)\w* ([\d.]+)\w*\, ([\d.]+)\w* ([\d.]+)\w*\)/
+    ];
+    
+    for (pattern of patterns) {
+        if (matchResult = s.match(pattern)) {
+            var result = [];
+            for (var i = 1; i < matchResult.length; ++i)
+                result.push(parseFloat(matchResult[i]));
+            return result;
+        }
+    }
+
+    window.console.log('failed to match ' + s);
+    return null;
+}
+
 function checkExpectedValue(expected, index)
 {
     var time = expected[index][0];
@@ -136,6 +159,18 @@
         } else {
             pass = isCloseEnough(computedCrossFade.percent, expectedValue, tolerance);
         }
+    } else if (property == "-webkit-clip-path" || property == "-webkit-shape-outside") {
+        computedValue = window.getComputedStyle(document.getElementById(elementId)).getPropertyCSSValue(property).cssText;
+
+        var expectedValues = parseClipPath(expectedValue);
+        var values = parseClipPath(computedValue);
+        
+        pass = false;
+        if (values && values.length == expectedValues.length) {
+            pass = true
+            for (var i = 0; i < values.length; ++i)
+                pass &= isCloseEnough(values[i], expectedValues[i], tolerance);
+        }
     } else {
         var computedStyle = window.getComputedStyle(document.getElementById(elementId)).getPropertyCSSValue(property);
         if (computedStyle.cssValueType == CSSValue.CSS_VALUE_LIST) {

Added: releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/shape-outside-transitions-expected.txt (0 => 190984)


--- releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/shape-outside-transitions-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/shape-outside-transitions-expected.txt	2015-10-13 13:29:00 UTC (rev 190984)
@@ -0,0 +1,37 @@
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+x
+PASS - "-webkit-shape-outside" property for "circle" element at 0.5s saw something close to: circle(60px at 50px 40px)
+PASS - "-webkit-shape-outside" property for "ellipse" element at 0.5s saw something close to: ellipse(15px 30px at 50px 40px)
+PASS - "-webkit-shape-outside" property for "inset" element at 0.5s saw something close to: inset(15px 22px)
+PASS - "-webkit-shape-outside" property for "polygon" element at 0.5s saw something close to: polygon(15px 0px, 75px 0, 60px 45px, 0 45px)
+

Added: releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/shape-outside-transitions.html (0 => 190984)


--- releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/shape-outside-transitions.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/shape-outside-transitions.html	2015-10-13 13:29:00 UTC (rev 190984)
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style>
+    .container {
+        width: 150px;
+        height: 150px;
+        border: 1px solid black;
+    }
+    .box {
+        height: 100px;
+        width: 100px;
+        margin: 10px;
+        background-color: silver;
+        -webkit-transition-duration: 1s;
+        -webkit-transition-timing-function: linear;
+        -webkit-transition-property: -webkit-shape-outside;
+        float: left;
+    }
+    
+    #circle {
+        -webkit-shape-outside: circle(100px at 50px 30px);
+    }
+    
+    body.final #circle {
+        -webkit-shape-outside: circle(20px at 50px 50px);
+    }
+
+    #ellipse {
+        -webkit-shape-outside: ellipse(10px 20px at 50px 30px);
+    }
+    
+    body.final #ellipse {
+        -webkit-shape-outside: ellipse(20px 40px at 50px 50px);
+    }
+
+    #inset {
+        -webkit-shape-outside: inset(10px 20px);
+    }
+    
+    body.final #inset {
+        -webkit-shape-outside: inset(20px 24px);
+    }
+
+    #polygon {
+        -webkit-shape-outside: polygon(20px 0px, 100px 0, 100px 50px, 0 50px);
+    }
+    
+    body.final #polygon {
+        -webkit-shape-outside: polygon(10px 0px, 50px 0, 20px 40px, 0 40px);
+    }
+  </style>
+  <script src=""
+  <script type="text/_javascript_">
+
+    const expectedValues = [
+      // [time, element-id, property, expected-value, tolerance]
+      [0.5, 'circle', '-webkit-shape-outside', 'circle(60px at 50px 40px)', 1],
+      [0.5, 'ellipse', '-webkit-shape-outside', 'ellipse(15px 30px at 50px 40px)', 1],
+      [0.5, 'inset', '-webkit-shape-outside', 'inset(15px 22px)', 1],
+      [0.5, 'polygon', '-webkit-shape-outside', 'polygon(15px 0px, 75px 0, 60px 45px, 0 45px)', 1],
+    ];
+  
+    function setupTest()
+    {
+        document.body.classList.add('final');
+    }
+    
+    runTransitionTest(expectedValues, setupTest, usePauseAPI);
+  </script>
+</head>
+<body>
+    <div class="container">
+        <div id="circle" class="box"></div>
+        x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
+    </div>
+
+    <div class="container">
+        <div id="ellipse" class="box"></div>
+        x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
+    </div>
+
+    <div class="container">
+        <div id="inset" class="box"></div>
+        x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
+    </div>
+
+    <div class="container">
+        <div id="polygon" class="box"></div>
+        x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
+    </div>
+
+    <div id="result"></div>
+
+</body>
+</html>

Modified: releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/svg-transitions-expected.txt (190983 => 190984)


--- releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/svg-transitions-expected.txt	2015-10-13 13:12:25 UTC (rev 190983)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/transitions/svg-transitions-expected.txt	2015-10-13 13:29:00 UTC (rev 190984)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 240: Failed to pause 'fill' transition on element 'rect7'
+CONSOLE MESSAGE: line 275: Failed to pause 'fill' transition on element 'rect7'
 Example
 PASS - "fill-opacity" property for "rect1" element at 1s saw something close to: 0.6
 PASS - "stroke-width" property for "rect1" element at 1s saw something close to: 3

Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog (190983 => 190984)


--- releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog	2015-10-13 13:12:25 UTC (rev 190983)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog	2015-10-13 13:29:00 UTC (rev 190984)
@@ -1,3 +1,51 @@
+2015-10-12  Simon Fraser  <[email protected]>
+
+        Clip-path transitions sometimes trigger endless animation timers
+        https://bugs.webkit.org/show_bug.cgi?id=150018
+
+        Reviewed by Tim Horton.
+        
+        Transitioning -webkit-clip-path could trigger endless animation
+        timers, because when CompositeAnimation::updateTransitions() calls
+        isTargetPropertyEqual(), a false negative answer triggers canceling the
+        current transition and starting a new one over and over.
+        
+        This happened because StyleRareNonInheritedData simply tested pointer
+        equality for m_clipPath and m_shapeOutside. Both of these need to do deep
+        equality testing, requiring the implementation of operator== in BasicShapes
+        classes.
+        
+        In addition, the PropertyWrappers in CSSPropertyAnimation need equals()
+        implementations that also do more than pointer equality testing.
+
+        Tests: transitions/clip-path-transitions.html
+               transitions/shape-outside-transitions.html
+
+        * page/animation/CSSPropertyAnimation.cpp:
+        (WebCore::PropertyWrapperClipPath::equals):
+        (WebCore::PropertyWrapperShape::equals):
+        * rendering/ClipPathOperation.h:
+        * rendering/style/BasicShapes.cpp:
+        (WebCore::BasicShapeCircle::operator==):
+        (WebCore::BasicShapeEllipse::operator==):
+        (WebCore::BasicShapePolygon::operator==):
+        (WebCore::BasicShapeInset::operator==):
+        * rendering/style/BasicShapes.h:
+        (WebCore::BasicShapeCenterCoordinate::operator==):
+        (WebCore::BasicShapeRadius::operator==):
+        * rendering/style/ShapeValue.cpp:
+        (WebCore::pointersOrValuesEqual):
+        (WebCore::ShapeValue::operator==):
+        * rendering/style/ShapeValue.h:
+        (WebCore::ShapeValue::operator!=):
+        (WebCore::ShapeValue::operator==): Deleted.
+        (WebCore::ShapeValue::ShapeValue): Deleted.
+        * rendering/style/StyleRareNonInheritedData.cpp:
+        (WebCore::StyleRareNonInheritedData::operator==):
+        (WebCore::StyleRareNonInheritedData::clipPathOperationsEquivalent):
+        (WebCore::StyleRareNonInheritedData::shapeOutsideDataEquivalent):
+        * rendering/style/StyleRareNonInheritedData.h:
+
 2015-10-10  Andreas Kling  <[email protected]>
 
         Reduce pointless malloc traffic in ElementRuleCollector.

Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/page/animation/CSSPropertyAnimation.cpp (190983 => 190984)


--- releases/WebKitGTK/webkit-2.10/Source/WebCore/page/animation/CSSPropertyAnimation.cpp	2015-10-13 13:12:25 UTC (rev 190983)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/page/animation/CSSPropertyAnimation.cpp	2015-10-13 13:29:00 UTC (rev 190984)
@@ -477,6 +477,24 @@
         : RefCountedPropertyWrapper<ClipPathOperation>(prop, getter, setter)
     {
     }
+
+    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
+    {
+        // If the style pointers are the same, don't bother doing the test.
+        // If either is null, return false. If both are null, return true.
+        if (a == b)
+            return true;
+        if (!a || !b)
+            return false;
+
+        ClipPathOperation* clipPathA = (a->*m_getter)();
+        ClipPathOperation* clipPathB = (b->*m_getter)();
+        if (clipPathA == clipPathB)
+            return true;
+        if (!clipPathA || !clipPathB)
+            return false;
+        return *clipPathA == *clipPathB;
+    }
 };
 
 #if ENABLE(CSS_SHAPES)
@@ -487,6 +505,24 @@
         : RefCountedPropertyWrapper<ShapeValue>(prop, getter, setter)
     {
     }
+
+    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
+    {
+        // If the style pointers are the same, don't bother doing the test.
+        // If either is null, return false. If both are null, return true.
+        if (a == b)
+            return true;
+        if (!a || !b)
+            return false;
+
+        ShapeValue* shapeA = (a->*m_getter)();
+        ShapeValue* shapeB = (b->*m_getter)();
+        if (shapeA == shapeB)
+            return true;
+        if (!shapeA || !shapeB)
+            return false;
+        return *shapeA == *shapeB;
+    }
 };
 #endif
 

Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/ClipPathOperation.h (190983 => 190984)


--- releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/ClipPathOperation.h	2015-10-13 13:12:25 UTC (rev 190983)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/ClipPathOperation.h	2015-10-13 13:29:00 UTC (rev 190984)
@@ -75,12 +75,12 @@
     const String& fragment() const { return m_fragment; }
 
 private:
-    virtual bool operator==(const ClipPathOperation& o) const override
+    virtual bool operator==(const ClipPathOperation& other) const override
     {
-        if (!isSameType(o))
+        if (!isSameType(other))
             return false;
-        const ReferenceClipPathOperation* other = static_cast<const ReferenceClipPathOperation*>(&o);
-        return m_url == other->m_url;
+        auto& referenceClip = downcast<ReferenceClipPathOperation>(other);
+        return m_url == referenceClip.m_url;
     }
 
     ReferenceClipPathOperation(const String& url, const String& fragment)
@@ -118,8 +118,9 @@
     {
         if (!isSameType(other))
             return false;
-        const auto& shapeClip = downcast<ShapeClipPathOperation>(other);
-        return m_shape.ptr() == shapeClip.m_shape.ptr();
+        auto& shapeClip = downcast<ShapeClipPathOperation>(other);
+        return m_referenceBox == shapeClip.referenceBox()
+            && (m_shape.ptr() == shapeClip.m_shape.ptr() || m_shape.get() == shapeClip.m_shape.get());
     }
 
     explicit ShapeClipPathOperation(Ref<BasicShape>&& shape)
@@ -149,12 +150,12 @@
     CSSBoxType referenceBox() const { return m_referenceBox; }
 
 private:
-    virtual bool operator==(const ClipPathOperation& o) const override
+    virtual bool operator==(const ClipPathOperation& other) const override
     {
-        if (!isSameType(o))
+        if (!isSameType(other))
             return false;
-        const BoxClipPathOperation* other = static_cast<const BoxClipPathOperation*>(&o);
-        return m_referenceBox == other->m_referenceBox;
+        auto& boxClip = downcast<BoxClipPathOperation>(other);
+        return m_referenceBox == boxClip.m_referenceBox;
     }
 
     explicit BoxClipPathOperation(CSSBoxType referenceBox)

Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/BasicShapes.cpp (190983 => 190984)


--- releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/BasicShapes.cpp	2015-10-13 13:12:25 UTC (rev 190983)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/BasicShapes.cpp	2015-10-13 13:29:00 UTC (rev 190984)
@@ -88,6 +88,18 @@
         && thisEllipse.radiusY().canBlend(otherEllipse.radiusY()));
 }
 
+
+bool BasicShapeCircle::operator==(const BasicShape& other) const
+{
+    if (type() != other.type())
+        return false;
+
+    const auto& otherCircle = downcast<BasicShapeCircle>(other);
+    return m_centerX == otherCircle.m_centerX
+        && m_centerY == otherCircle.m_centerY
+        && m_radius == otherCircle.m_radius;
+}
+
 float BasicShapeCircle::floatValueForRadiusInBox(float boxWidth, float boxHeight) const
 {
     if (m_radius.type() == BasicShapeRadius::Value)
@@ -132,6 +144,18 @@
     return result.releaseNonNull();
 }
 
+bool BasicShapeEllipse::operator==(const BasicShape& other) const
+{
+    if (type() != other.type())
+        return false;
+
+    const auto& otherEllipse = downcast<BasicShapeEllipse>(other);
+    return m_centerX == otherEllipse.m_centerX
+        && m_centerY == otherEllipse.m_centerY
+        && m_radiusX == otherEllipse.m_radiusX
+        && m_radiusY == otherEllipse.m_radiusY;
+}
+
 float BasicShapeEllipse::floatValueForRadiusInBox(const BasicShapeRadius& radius, float center, float boxWidthOrHeight) const
 {
     if (radius.type() == BasicShapeRadius::Value)
@@ -182,6 +206,16 @@
     return result.releaseNonNull();
 }
 
+bool BasicShapePolygon::operator==(const BasicShape& other) const
+{
+    if (type() != other.type())
+        return false;
+
+    const auto& otherPolygon = downcast<BasicShapePolygon>(other);
+    return m_windRule == otherPolygon.m_windRule
+        && m_values == otherPolygon.m_values;
+}
+
 void BasicShapePolygon::path(Path& path, const FloatRect& boundingBox)
 {
     ASSERT(path.isEmpty());
@@ -223,6 +257,22 @@
     return result.releaseNonNull();
 }
 
+bool BasicShapeInset::operator==(const BasicShape& other) const
+{
+    if (type() != other.type())
+        return false;
+
+    const auto& otherInset = downcast<BasicShapeInset>(other);
+    return m_right == otherInset.m_right
+        && m_top == otherInset.m_top
+        && m_bottom == otherInset.m_bottom
+        && m_left == otherInset.m_left
+        && m_topLeftRadius == otherInset.m_topLeftRadius
+        && m_topRightRadius == otherInset.m_topRightRadius
+        && m_bottomRightRadius == otherInset.m_bottomRightRadius
+        && m_bottomLeftRadius == otherInset.m_bottomLeftRadius;
+}
+
 static FloatSize floatSizeForLengthSize(const LengthSize& lengthSize, const FloatRect& boundingBox)
 {
     return FloatSize(floatValueForLength(lengthSize.width(), boundingBox.width()),

Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/BasicShapes.h (190983 => 190984)


--- releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/BasicShapes.h	2015-10-13 13:12:25 UTC (rev 190983)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/BasicShapes.h	2015-10-13 13:29:00 UTC (rev 190984)
@@ -63,6 +63,7 @@
     virtual Ref<BasicShape> blend(const BasicShape&, double) const = 0;
 
     virtual Type type() const = 0;
+    virtual bool operator==(const BasicShape&) const = 0;
 };
 
 class BasicShapeCenterCoordinate {
@@ -101,6 +102,13 @@
     {
         return BasicShapeCenterCoordinate(TopLeft, m_computedLength.blend(other.m_computedLength, progress));
     }
+    
+    bool operator==(const BasicShapeCenterCoordinate& other) const
+    {
+        return m_direction == other.m_direction
+            && m_length == other.m_length
+            && m_computedLength == other.m_computedLength;
+    }
 
 private:
     Direction m_direction;
@@ -138,6 +146,11 @@
 
         return BasicShapeRadius(m_value.blend(other.value(), progress));
     }
+    
+    bool operator==(const BasicShapeRadius& other) const
+    {
+        return m_value == other.m_value && m_type == other.m_type;
+    }
 
 private:
     Length m_value;
@@ -162,6 +175,8 @@
     virtual Ref<BasicShape> blend(const BasicShape&, double) const override;
 
     virtual Type type() const override { return BasicShapeCircleType; }
+    virtual bool operator==(const BasicShape&) const override;
+
 private:
     BasicShapeCircle() { }
 
@@ -189,6 +204,8 @@
     virtual Ref<BasicShape> blend(const BasicShape&, double) const override;
 
     virtual Type type() const override { return BasicShapeEllipseType; }
+    virtual bool operator==(const BasicShape&) const override;
+
 private:
     BasicShapeEllipse() { }
 
@@ -215,6 +232,8 @@
     virtual WindRule windRule() const override { return m_windRule; }
 
     virtual Type type() const override { return BasicShapePolygonType; }
+    virtual bool operator==(const BasicShape&) const override;
+
 private:
     BasicShapePolygon()
         : m_windRule(RULE_NONZERO)
@@ -252,6 +271,8 @@
     virtual Ref<BasicShape> blend(const BasicShape&, double) const override;
 
     virtual Type type() const override { return BasicShapeInsetType; }
+    virtual bool operator==(const BasicShape&) const override;
+
 private:
     BasicShapeInset() { }
 

Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/ShapeValue.cpp (190983 => 190984)


--- releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/ShapeValue.cpp	2015-10-13 13:12:25 UTC (rev 190983)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/ShapeValue.cpp	2015-10-13 13:29:00 UTC (rev 190984)
@@ -39,4 +39,26 @@
     return image()->isGeneratedImage();
 }
 
+template <typename T>
+bool pointersOrValuesEqual(T p1, T p2)
+{
+    if (p1 == p2)
+        return true;
+    
+    if (!p1 || !p2)
+        return false;
+    
+    return *p1 == *p2;
+}
+
+bool ShapeValue::operator==(const ShapeValue& other) const
+{
+    if (m_type != other.m_type || m_cssBox != other.m_cssBox)
+        return false;
+
+    return pointersOrValuesEqual(m_shape.get(), other.m_shape.get())
+        && pointersOrValuesEqual(m_image.get(), other.m_image.get());
+}
+
+
 } // namespace WebCore

Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/ShapeValue.h (190983 => 190984)


--- releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/ShapeValue.h	2015-10-13 13:12:25 UTC (rev 190983)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/ShapeValue.h	2015-10-13 13:29:00 UTC (rev 190984)
@@ -76,7 +76,11 @@
             m_image = image;
     }
 
-    bool operator==(const ShapeValue& other) const { return type() == other.type(); }
+    bool operator==(const ShapeValue&) const;
+    bool operator!=(const ShapeValue& other) const
+    {
+        return !(*this == other);
+    }
 
 private:
     ShapeValue(PassRefPtr<BasicShape> shape, CSSBoxType cssBox)
@@ -87,13 +91,11 @@
     }
     ShapeValue(Type type)
         : m_type(type)
-        , m_cssBox(BoxMissing)
     {
     }
     ShapeValue(PassRefPtr<StyleImage> image)
         : m_type(Type::Image)
         , m_image(image)
-        , m_cssBox(BoxMissing)
     {
     }
 
@@ -106,7 +108,7 @@
     Type m_type;
     RefPtr<BasicShape> m_shape;
     RefPtr<StyleImage> m_image;
-    CSSBoxType m_cssBox;
+    CSSBoxType m_cssBox { BoxMissing };
 };
 
 }

Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp (190983 => 190984)


--- releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp	2015-10-13 13:12:25 UTC (rev 190983)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp	2015-10-13 13:29:00 UTC (rev 190984)
@@ -241,11 +241,11 @@
         && m_maskBoxImage == o.m_maskBoxImage
         && m_pageSize == o.m_pageSize
 #if ENABLE(CSS_SHAPES)
-        && m_shapeOutside == o.m_shapeOutside
+        && shapeOutsideDataEquivalent(o)
         && m_shapeMargin == o.m_shapeMargin
         && m_shapeImageThreshold == o.m_shapeImageThreshold
 #endif
-        && m_clipPath == o.m_clipPath
+        && clipPathOperationsEquivalent(o)
         && m_textDecorationColor == o.m_textDecorationColor
         && m_visitedLinkTextDecorationColor == o.m_visitedLinkTextDecorationColor
         && m_visitedLinkBackgroundColor == o.m_visitedLinkBackgroundColor
@@ -351,6 +351,26 @@
     return true;
 }
 
+bool StyleRareNonInheritedData::clipPathOperationsEquivalent(const StyleRareNonInheritedData& o) const
+{
+    if ((!m_clipPath && o.m_clipPath) || (m_clipPath && !o.m_clipPath))
+        return false;
+    if (m_clipPath && o.m_clipPath && (*m_clipPath != *o.m_clipPath))
+        return false;
+    return true;
+}
+
+#if ENABLE(CSS_SHAPES)
+bool StyleRareNonInheritedData::shapeOutsideDataEquivalent(const StyleRareNonInheritedData& o) const
+{
+    if ((!m_shapeOutside && o.m_shapeOutside) || (m_shapeOutside && !o.m_shapeOutside))
+        return false;
+    if (m_shapeOutside && o.m_shapeOutside && (*m_shapeOutside != *o.m_shapeOutside))
+        return false;
+    return true;
+}
+#endif
+
 bool StyleRareNonInheritedData::hasFilters() const
 {
     return m_filter.get() && !m_filter->m_operations.isEmpty();

Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/StyleRareNonInheritedData.h (190983 => 190984)


--- releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/StyleRareNonInheritedData.h	2015-10-13 13:12:25 UTC (rev 190983)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/rendering/style/StyleRareNonInheritedData.h	2015-10-13 13:29:00 UTC (rev 190984)
@@ -95,6 +95,10 @@
     bool reflectionDataEquivalent(const StyleRareNonInheritedData&) const;
     bool animationDataEquivalent(const StyleRareNonInheritedData&) const;
     bool transitionDataEquivalent(const StyleRareNonInheritedData&) const;
+    bool clipPathOperationsEquivalent(const StyleRareNonInheritedData&) const;
+#if ENABLE(CSS_SHAPES)
+    bool shapeOutsideDataEquivalent(const StyleRareNonInheritedData&) const;
+#endif
     bool hasFilters() const;
 #if ENABLE(FILTERS_LEVEL_2)
     bool hasBackdropFilters() const;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to