[css shapes] layout for new ellipse syntax
authorrwlbuis@webkit.org <rwlbuis@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Dec 2013 17:18:01 +0000 (17:18 +0000)
committerrwlbuis@webkit.org <rwlbuis@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Dec 2013 17:18:01 +0000 (17:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=124621

Source/WebCore:

Reviewed by Dirk Schulze.

Implement support for doing layout with the new ellipse shape syntax,
including basic animation support.

Test: fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000.html

* rendering/shapes/Shape.cpp:
(WebCore::Shape::createShape): Convert new ellipse to a layout shape.
* rendering/style/BasicShapes.cpp:
(WebCore::BasicShape::canBlend): Ignore ellipses with values that
    cannot be interpolated.
(WebCore::BasicShapeEllipse::floatValueForRadiusInBox): Helper function to calculate
    either radiusX or radiusY, shared by clip-path and shape code paths.
(WebCore::BasicShapeEllipse::path):
* rendering/style/BasicShapes.h:

LayoutTests:

Add a new test for the new ellipse syntax. Also update existing shape-inside, animation, and clip-path tests to
test the new ellipse syntax for clipping and shape-inside.

Reviewed by Dirk Schulze.

* animations/resources/animation-test-helpers.js:
(parseBasicShape):
* css3/masking/clip-path-animation-expected.txt:
* css3/masking/clip-path-animation.html:
* css3/masking/clip-path-ellipse.html:
* fast/shapes/shape-inside/shape-inside-animation-expected.txt:
* fast/shapes/shape-inside/shape-inside-animation.html:
* fast/shapes/shape-inside/shape-inside-ellipse-padding.html:
* fast/shapes/shape-inside/shape-inside-ellipse.html:
* fast/shapes/shape-inside/shape-inside-empty-expected.html:
* fast/shapes/shape-inside/shape-inside-empty.html:
* fast/shapes/shape-outside-floats/shape-outside-animation-expected.txt:
* fast/shapes/shape-outside-floats/shape-outside-animation.html:
* fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000-expected.html: Added.
* fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@160007 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
LayoutTests/ChangeLog
LayoutTests/animations/resources/animation-test-helpers.js
LayoutTests/css3/masking/clip-path-animation-expected.txt
LayoutTests/css3/masking/clip-path-animation.html
LayoutTests/css3/masking/clip-path-ellipse.html
LayoutTests/fast/shapes/shape-inside/shape-inside-animation-expected.txt
LayoutTests/fast/shapes/shape-inside/shape-inside-animation.html
LayoutTests/fast/shapes/shape-inside/shape-inside-ellipse-padding.html
LayoutTests/fast/shapes/shape-inside/shape-inside-ellipse.html
LayoutTests/fast/shapes/shape-inside/shape-inside-empty-expected.html
LayoutTests/fast/shapes/shape-inside/shape-inside-empty.html
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-animation-expected.txt
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-animation.html
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000-expected.html [new file with mode: 0644]
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/shapes/Shape.cpp
Source/WebCore/rendering/style/BasicShapes.cpp
Source/WebCore/rendering/style/BasicShapes.h

index f8400e4..a7d529f 100644 (file)
@@ -1,3 +1,29 @@
+2013-12-03  Rob Buis  <rob.buis@samsung.com>
+
+        [css shapes] layout for new ellipse syntax
+        https://bugs.webkit.org/show_bug.cgi?id=124621
+
+        Add a new test for the new ellipse syntax. Also update existing shape-inside, animation, and clip-path tests to
+        test the new ellipse syntax for clipping and shape-inside.
+
+        Reviewed by Dirk Schulze.
+
+        * animations/resources/animation-test-helpers.js:
+        (parseBasicShape):
+        * css3/masking/clip-path-animation-expected.txt:
+        * css3/masking/clip-path-animation.html:
+        * css3/masking/clip-path-ellipse.html:
+        * fast/shapes/shape-inside/shape-inside-animation-expected.txt:
+        * fast/shapes/shape-inside/shape-inside-animation.html:
+        * fast/shapes/shape-inside/shape-inside-ellipse-padding.html:
+        * fast/shapes/shape-inside/shape-inside-ellipse.html:
+        * fast/shapes/shape-inside/shape-inside-empty-expected.html:
+        * fast/shapes/shape-inside/shape-inside-empty.html:
+        * fast/shapes/shape-outside-floats/shape-outside-animation-expected.txt:
+        * fast/shapes/shape-outside-floats/shape-outside-animation.html:
+        * fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000-expected.html: Added.
+        * fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000.html: Added.
+
 2013-12-03  Frédéric Wang  <fred.wang@free.fr>
 
         Add an MathMLSelectElement class to implement <maction> and <semantics>.
index 546650c..a53b856 100644 (file)
@@ -219,7 +219,7 @@ function parseBasicShape(s)
         matches = s.match("circle\\((.*)\\s+at\\s+(.*)\\s+(.*)\\)");
         break;
     case "ellipse":
-        matches = s.match("ellipse\\((.*)\\s*,\\s*(.*)\\s*,\\s*(.*)\\,\\s*(.*)\\)");
+        matches = s.match("ellipse\\((.*)\\s+(.*)\\s+at\\s+(.*)\\s+(.*)\\)");
         break;
     case "polygon":
         matches = s.match("polygon\\(nonzero, (.*)\\s+(.*)\\s*,\\s*(.*)\\s+(.*)\\s*,\\s*(.*)\\s+(.*)\\s*,\\s*(.*)\\s+(.*)\\)");
index e0982df..fe7194d 100644 (file)
@@ -1,7 +1,7 @@
     
 PASS - "webkitClipPath" property for "rectangle-box" element at 1s saw something close to: rectangle(10%, 10%, 80%, 80%, 0px, 0px)
 PASS - "webkitClipPath" property for "circle-box" element at 1s saw something close to: circle(35% at 35% 35%)
-PASS - "webkitClipPath" property for "ellipse-box" element at 1s saw something close to: ellipse(35%, 35%, 35%, 30%)
+PASS - "webkitClipPath" property for "ellipse-box" element at 1s saw something close to: ellipse(35% 30% at 35% 35%)
 PASS - "webkitClipPath" property for "polygon-box" element at 1s saw something close to: polygon(nonzero, 10% 10%, 90% 10%, 90% 90%, 10% 90%)
 PASS - "webkitClipPath" property for "none-box" element at 1s saw something close to: polygon(nonzero, 20% 20%, 80% 20%, 80% 80%, 20% 80%)
 
index b372acf..24922e7 100644 (file)
@@ -42,8 +42,8 @@
     }
 
     @-webkit-keyframes ellipse-anim {
-        from { -webkit-clip-path: ellipse(50%, 50%, 50%, 40%); }
-        to   { -webkit-clip-path: ellipse(20%, 20%, 20%, 20%); }
+        from { -webkit-clip-path: ellipse(50% 40% at 50% 50%); }
+        to   { -webkit-clip-path: ellipse(20% 20% at 20% 20%); }
     }
 
     @-webkit-keyframes polygon-anim {
@@ -64,7 +64,7 @@
       // [animation-name, time, element-id, property, expected-value, tolerance]
       ["rectangle-anim",  1, "rectangle-box", "webkitClipPath", "rectangle(10%, 10%, 80%, 80%, 0px, 0px)", 0.05],
       ["circle-anim",  1, "circle-box", "webkitClipPath", "circle(35% at 35% 35%)", 0.05],
-      ["ellipse-anim",  1, "ellipse-box", "webkitClipPath", "ellipse(35%, 35%, 35%, 30%)", 0.05],
+      ["ellipse-anim",  1, "ellipse-box", "webkitClipPath", "ellipse(35% 30% at 35% 35%)", 0.05],
       ["polygon-anim",  1, "polygon-box", "webkitClipPath", "polygon(nonzero, 10% 10%, 90% 10%, 90% 90%, 10% 90%)", 0.05],
       ["none-anim",  1, "none-box", "webkitClipPath", "polygon(nonzero, 20% 20%, 80% 20%, 80% 80%, 20% 80%)", 0],
     ];
index eabb993..6c6ca0c 100644 (file)
@@ -6,11 +6,11 @@ div {
     width: 200px;
     height: 200px;
     background-color: green;
-    -webkit-clip-path: ellipse(100px, 100px, 100px, 75px);
+    -webkit-clip-path: ellipse(100px 75px at 100px 100px);
 }
 </style>
 </head>
 <body>
 <div>
 </body>
-</html>
\ No newline at end of file
+</html>
index 78a7544..a0c8b54 100644 (file)
@@ -1,6 +1,6 @@
 Moving Text Moving Text Moving Text Moving Text
 PASS - "webkitShapeInside" property for "rectangle-box" element at 1s saw something close to: rectangle(10%, 10%, 80%, 80%, 0px, 0px)
 PASS - "webkitShapeInside" property for "circle-box" element at 1s saw something close to: circle(35% at 35% 35%)
-PASS - "webkitShapeInside" property for "ellipse-box" element at 1s saw something close to: ellipse(35%, 35%, 35%, 30%)
+PASS - "webkitShapeInside" property for "ellipse-box" element at 1s saw something close to: ellipse(35% 30% at 35% 35%)
 PASS - "webkitShapeInside" property for "polygon-box" element at 1s saw something close to: polygon(nonzero, 10% 10%, 90% 10%, 90% 90%, 10% 90%)
 
index e9db78a..f2c79ca 100644 (file)
@@ -38,8 +38,8 @@
     }
 
     @-webkit-keyframes ellipse-anim {
-        from { -webkit-shape-inside: ellipse(50%, 50%, 50%, 40%); }
-        to   { -webkit-shape-inside: ellipse(20%, 20%, 20%, 20%); }
+        from { -webkit-shape-inside: ellipse(50% 40% at 50% 50%); }
+        to   { -webkit-shape-inside: ellipse(20% 20% at 20% 20%); }
     }
 
     @-webkit-keyframes polygon-anim {
@@ -54,7 +54,7 @@
       // [animation-name, time, element-id, property, expected-value, tolerance]
       ["rectangle-anim",  1, "rectangle-box", "webkitShapeInside", "rectangle(10%, 10%, 80%, 80%, 0px, 0px)", 0.05],
       ["circle-anim",  1, "circle-box", "webkitShapeInside", "circle(35% at 35% 35%)", 0.05],
-      ["ellipse-anim",  1, "ellipse-box", "webkitShapeInside", "ellipse(35%, 35%, 35%, 30%)", 0.05],
+      ["ellipse-anim",  1, "ellipse-box", "webkitShapeInside", "ellipse(35% 30% at 35% 35%)", 0.05],
       ["polygon-anim",  1, "polygon-box", "webkitShapeInside", "polygon(nonzero, 10% 10%, 90% 10%, 90% 90%, 10% 90%)", 0.05],
     ];
     
index 76d7ac9..f7f7b3e 100644 (file)
@@ -9,7 +9,7 @@
         position: relative;
         width: 500px;
         height: 500px;
-        -webkit-shape-inside: ellipse(220px, 220px, 250px, 150px);
+        -webkit-shape-inside: ellipse(250px 150px at 220px 220px);
         -webkit-shape-padding: 50px;
         font: 178px/1 Ahem, sans-serif;
         color: green;
index 6f7087a..a25da52 100644 (file)
@@ -12,7 +12,7 @@
         position: relative;
         width: 500px;
         height: 500px;
-        -webkit-shape-inside: ellipse(220px, 220px, 200px, 100px);
+        -webkit-shape-inside: ellipse(200px 100px at 220px 220px);
         font: 178px/1 Ahem, sans-serif;
         color: green;
     }
index 0098717..191f773 100644 (file)
         <p>This text should be pushed down below the green rectangle. (There is a circle(0px at 0px 0px) shape-inside CSS property on the green rectangle.)</p>
     </div>
     <div>
-        <p>This text should be pushed down below the green rectangle. (There is an ellipse(0px, 0px, 0px, 1em) shape-inside CSS property on the green rectangle.)</p>
+        <p>This text should be pushed down below the green rectangle. (There is an ellipse(0px 1em at 0px 0px) shape-inside CSS property on the green rectangle.)</p>
     </div>
     <div>
-        <p>This text should be pushed down below the green rectangle. (There is an ellipse(0px, 0px, 1em, 0px) shape-inside CSS property on the green rectangle.)</p>
+        <p>This text should be pushed down below the green rectangle. (There is an ellipse(1em 0px at 0px 0px) shape-inside CSS property on the green rectangle.)</p>
     </div>
     <div>
         <p>This text should be pushed down below the green rectangle. (There is a polygon(0px 0px) shape-inside CSS property on the green rectangle.)</p>
index 9de9a52..e0a7e5e 100644 (file)
     }
 
     #shape-inside-ellipse-radiusX0 {
-        -webkit-shape-inside: ellipse(0px, 0px, 0px, 1em);
+        -webkit-shape-inside: ellipse(0px 1em at 0px 0px);
     }
 
     #shape-inside-ellipse-radiusY0 {
-        -webkit-shape-inside: ellipse(0px, 0px, 1em, 0px);
+        -webkit-shape-inside: ellipse(1em 0px at 0px 0px);
     }
 
     #shape-inside-polygon-1vertex {
         This text should be pushed down below the green rectangle. (There is a circle(0px at 0px 0px) shape-inside CSS property on the green rectangle.)
     </p>
     <p id="shape-inside-ellipse-radiusX0">
-        This text should be pushed down below the green rectangle. (There is an ellipse(0px, 0px, 0px, 1em) shape-inside CSS property on the green rectangle.)
+        This text should be pushed down below the green rectangle. (There is an ellipse(0px 1em at 0px 0px) shape-inside CSS property on the green rectangle.)
     </p>
     <p id="shape-inside-ellipse-radiusY0">
-        This text should be pushed down below the green rectangle. (There is an ellipse(0px, 0px, 1em, 0px) shape-inside CSS property on the green rectangle.)
+        This text should be pushed down below the green rectangle. (There is an ellipse(1em 0px at 0px 0px) shape-inside CSS property on the green rectangle.)
     </p>
     <p id="shape-inside-polygon-1vertex">
         This text should be pushed down below the green rectangle. (There is a polygon(0px 0px) shape-inside CSS property on the green rectangle.)
index 7d043bb..ff9afa0 100644 (file)
@@ -4,6 +4,6 @@ Moving Text
 Moving Text
 PASS - "webkitShapeOutside" property for "rectangle-box" element at 1s saw something close to: rectangle(10%, 10%, 80%, 80%, 0px, 0px)
 PASS - "webkitShapeOutside" property for "circle-box" element at 1s saw something close to: circle(35% at 35% 35%)
-PASS - "webkitShapeOutside" property for "ellipse-box" element at 1s saw something close to: ellipse(35%, 35%, 35%, 30%)
+PASS - "webkitShapeOutside" property for "ellipse-box" element at 1s saw something close to: ellipse(35% 30% at 35% 35%)
 PASS - "webkitShapeOutside" property for "polygon-box" element at 1s saw something close to: polygon(nonzero, 10% 10%, 90% 10%, 90% 90%, 10% 90%)
 
index 20ece6a..5d6cbf8 100644 (file)
@@ -42,8 +42,8 @@
     }
 
     @-webkit-keyframes ellipse-anim {
-        from { -webkit-shape-outside: ellipse(50%, 50%, 50%, 40%); }
-        to   { -webkit-shape-outside: ellipse(20%, 20%, 20%, 20%); }
+        from { -webkit-shape-outside: ellipse(50% 40% at 50% 50%); }
+        to   { -webkit-shape-outside: ellipse(20% 20% at 20% 20%); }
     }
 
     @-webkit-keyframes polygon-anim {
@@ -58,7 +58,7 @@
       // [animation-name, time, element-id, property, expected-value, tolerance]
       ["rectangle-anim",  1, "rectangle-box", "webkitShapeOutside", "rectangle(10%, 10%, 80%, 80%, 0px, 0px)", 0.05],
       ["circle-anim",  1, "circle-box", "webkitShapeOutside", "circle(35% at 35% 35%)", 0.05],
-      ["ellipse-anim",  1, "ellipse-box", "webkitShapeOutside", "ellipse(35%, 35%, 35%, 30%)", 0.05],
+      ["ellipse-anim",  1, "ellipse-box", "webkitShapeOutside", "ellipse(35% 30% at 35% 35%)", 0.05],
       ["polygon-anim",  1, "polygon-box", "webkitShapeOutside", "polygon(nonzero, 10% 10%, 90% 10%, 90% 90%, 10% 90%)", 0.05],
     ];
     
diff --git a/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000-expected.html b/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000-expected.html
new file mode 100644 (file)
index 0000000..8e2ec36
--- /dev/null
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<style>
+.container {
+    position: relative;
+    font: 20px/1 Ahem, sans-serif;
+    width: 500px;
+    height: 200px;
+    border: 1px solid black;
+}
+
+.ellipse {
+    z-index: -1;
+    width: 320px;
+    height: 160px;
+    border-radius: 160px / 80px;
+    background-color: blue;
+    overflow: hidden;
+}
+
+#left-ellipse-outline {
+    position: absolute;
+    top: 20px;
+    left: 0px;
+}
+
+#right-ellipse-outline {
+    position: absolute;
+    top: 20px;
+    right: 0px;
+}
+
+.left-ellipse-float-line {
+    float: left;
+    clear: left;
+    height: 20px;
+}
+
+.right-ellipse-float-line {
+    float: right;
+    clear: right;
+    height: 20px;
+}
+</style>
+<body>
+<p>The black squares should trace the right side of the ellipse's blue outline.</p>
+<div class="container">
+X<br/>
+    <div id="left-ellipse-outline" class="ellipse"></div>
+    <!--  generated left-rounded-rect-float-line divs will be inserted here  -->
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X
+</div>
+
+<p>The black squares should trace the left side of the ellipse's blue outline.</p>
+<div class="container" style="text-align: right">
+X<br/>
+    <div id="right-ellipse-outline" class="ellipse"></div>
+    <!--  generated right-rounded-rect-float-line divs will be inserted here  -->
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X
+</div>
+
+<script src="../resources/rounded-rectangle.js"></script>
+<script src="../resources/subpixel-utils.js"></script>
+<script>
+genLeftRightRoundedRectFloatShapeOutsideRefTest({
+    roundedRect: {x: 0, y: 20, width: 320, height: 160, rx: 160, ry: 80},
+    containerWidth: 500,
+    containerHeight: 200,
+    lineHeight: 20,
+    floatElementClassSuffix: "ellipse-float-line",
+    insertElementIdSuffix: "ellipse-outline"
+});
+</script>
+
+</body>
diff --git a/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000.html b/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000.html
new file mode 100644 (file)
index 0000000..32a88d2
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<title>CSS Test: circle shape-outside on floats</title>
+<link rel="author" title="Adobe" href="http://html.adobe.com/">
+<link rel="author" title="Bem Jones-Bey" href="mailto:bjonesbe@adobe.com">
+<link rel="help" href="http://dev.w3.org/csswg/css-shapes-1/#shape-outside-property">
+<link rel="match" href="shape-outside-floats-ellipse-000-ref.html">
+<meta name="flags" content="ahem">
+<style>
+.container {
+    font: 20px/1 Ahem, sans-serif;
+    width: 500px;
+    height: 200px; 
+    border: 1px solid black;
+}
+
+.ellipse {
+    width: 320px;
+    height: 160px;
+    background-color: blue;
+    overflow: hidden;
+    border-radius: 160px / 80px;
+    -webkit-shape-outside: ellipse(160px 80px at 160px 80px);
+}
+</style>
+
+<body>
+<p>The black squares should trace the right side of the ellipse's blue outline.</p>
+<div class="container">
+X<br/>
+    <div style="float: left" class="ellipse"></div>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X
+</div>
+
+<p>The black squares should trace the left side of the ellipse's blue outline.</p>
+<div class="container" style="text-align: right">
+X<br/>
+    <div style="float: right" class="ellipse"></div>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X<br/>
+X
+</div>
+</body>
index 69846e3..094ec1c 100644 (file)
@@ -1,3 +1,25 @@
+2013-12-03  Rob Buis  <rob.buis@samsung.com>
+
+        [css shapes] layout for new ellipse syntax
+        https://bugs.webkit.org/show_bug.cgi?id=124621
+
+        Reviewed by Dirk Schulze.
+
+        Implement support for doing layout with the new ellipse shape syntax,
+        including basic animation support.
+
+        Test: fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-000.html
+
+        * rendering/shapes/Shape.cpp:
+        (WebCore::Shape::createShape): Convert new ellipse to a layout shape.
+        * rendering/style/BasicShapes.cpp:
+        (WebCore::BasicShape::canBlend): Ignore ellipses with values that
+            cannot be interpolated.
+        (WebCore::BasicShapeEllipse::floatValueForRadiusInBox): Helper function to calculate
+            either radiusX or radiusY, shared by clip-path and shape code paths.
+        (WebCore::BasicShapeEllipse::path):
+        * rendering/style/BasicShapes.h:
+
 2013-12-03  Frédéric Wang  <fred.wang@free.fr>
 
         Add an MathMLSelectElement class to implement <maction> and <semantics>.
index 0229716..ba39c2c 100644 (file)
@@ -175,8 +175,14 @@ PassOwnPtr<Shape> Shape::createShape(const BasicShape* basicShape, const LayoutS
     }
 
     case BasicShape::BasicShapeEllipseType: {
-        // FIXME: Layout implementation needed. See bug https://bugs.webkit.org/show_bug.cgi?id=125079
-        shape = createRectangleShape(FloatRect(0, 0, boxWidth, boxHeight), FloatSize());
+        const BasicShapeEllipse* ellipse = static_cast<const BasicShapeEllipse*>(basicShape);
+        float centerX = floatValueForCenterCoordinate(ellipse->centerX(), boxWidth);
+        float centerY = floatValueForCenterCoordinate(ellipse->centerY(), boxHeight);
+        float radiusX = ellipse->floatValueForRadiusInBox(ellipse->radiusX(), centerX, boxWidth);
+        float radiusY = ellipse->floatValueForRadiusInBox(ellipse->radiusY(), centerY, boxHeight);
+        FloatPoint logicalCenter = physicalPointToLogical(FloatPoint(centerX, centerY), logicalBoxSize.height(), writingMode);
+
+        shape = createShapeEllipse(logicalCenter, FloatSize(radiusX, radiusY));
         break;
     }
 
index bfe32a3..283d766 100644 (file)
@@ -59,7 +59,17 @@ bool BasicShape::canBlend(const BasicShape* other) const
             return false;
     }
 
-    return true;
+    // Ellipses with keywords for radii or center coordinates cannot be animated.
+    if (type() != BasicShape::BasicShapeEllipseType)
+        return true;
+
+    const BasicShapeEllipse* thisEllipse = static_cast<const BasicShapeEllipse*>(this);
+    const BasicShapeEllipse* otherEllipse = static_cast<const BasicShapeEllipse*>(other);
+    if (!thisEllipse->radiusX().canBlend(otherEllipse->radiusX())
+        || !thisEllipse->radiusY().canBlend(otherEllipse->radiusY())
+        || !thisEllipse->centerX().canBlend(otherEllipse->centerX())
+        || !thisEllipse->centerY().canBlend(otherEllipse->centerY()))
+        return false;
 }
 
 void BasicShapeRectangle::path(Path& path, const FloatRect& boundingBox)
@@ -191,22 +201,26 @@ PassRefPtr<BasicShape> DeprecatedBasicShapeEllipse::blend(const BasicShape* othe
     return result.release();
 }
 
+float BasicShapeEllipse::floatValueForRadiusInBox(const BasicShapeRadius& radius, float center, float boxWidthOrHeight) const
+{
+    if (radius.type() == BasicShapeRadius::Value)
+        return floatValueForLength(radius.value(), boxWidthOrHeight);
+
+    if (radius.type() == BasicShapeRadius::ClosestSide)
+        return std::min(center, boxWidthOrHeight - center);
+
+    ASSERT(radius.type() == BasicShapeRadius::FarthestSide);
+    return std::max(center, boxWidthOrHeight - center);
+}
+
 void BasicShapeEllipse::path(Path& path, const FloatRect& boundingBox)
 {
     ASSERT(path.isEmpty());
-    // FIXME: The implementation of path is incomplete. See https://bugs.webkit.org/show_bug.cgi?id=125079 
-    // Compute closest-side and farthest-side from boundingBox.
-    // Compute top, left, bottom, right from boundingBox.
-    if (m_radiusX.type() != BasicShapeRadius::Value || m_radiusY.type() != BasicShapeRadius::Value)
-        return;
-    if (m_centerX.keyword() != BasicShapeCenterCoordinate::None || m_centerY.keyword() != BasicShapeCenterCoordinate::None)
-        return;
 
-    float diagonal = sqrtf((boundingBox.width() * boundingBox.width() + boundingBox.height() * boundingBox.height()) / 2);
-    float centerX = floatValueForLength(m_centerX.length(), boundingBox.width());
-    float centerY = floatValueForLength(m_centerY.length(), boundingBox.height());
-    float radiusX = floatValueForLength(m_radiusX.value(), diagonal);
-    float radiusY = floatValueForLength(m_radiusY.value(), diagonal);
+    float centerX = floatValueForCenterCoordinate(m_centerX, boundingBox.width());
+    float centerY = floatValueForCenterCoordinate(m_centerY, boundingBox.height());
+    float radiusX = floatValueForRadiusInBox(m_radiusX, centerX, boundingBox.width());
+    float radiusY = floatValueForRadiusInBox(m_radiusY, centerY, boundingBox.height());
     path.addEllipse(FloatRect(
         centerX - radiusX + boundingBox.x(),
         centerY - radiusY + boundingBox.y(),
index bd092de..a76c280 100644 (file)
@@ -255,6 +255,7 @@ public:
     const BasicShapeCenterCoordinate& centerY() const { return m_centerY; }
     const BasicShapeRadius& radiusX() const { return m_radiusX; }
     const BasicShapeRadius& radiusY() const { return m_radiusY; }
+    float floatValueForRadiusInBox(const BasicShapeRadius&, float center, float boxWidthOrHeight) const;
 
     void setCenterX(BasicShapeCenterCoordinate centerX) { m_centerX = std::move(centerX); }
     void setCenterY(BasicShapeCenterCoordinate centerY) { m_centerY = std::move(centerY); }