Title: [160770] trunk
Revision
160770
Author
rwlb...@webkit.org
Date
2013-12-18 09:27:58 -0800 (Wed, 18 Dec 2013)

Log Message

2013-12-18  Rob Buis  <rob.b...@samsung.com>

        [CSS Shapes] Implement interpolation between keywords in basic shapes
        https://bugs.webkit.org/show_bug.cgi?id=125108

        Reviewed by Simon Fraser.

        Allow blending for all center coordinates since top/left and bottom/right default to correct
        Length values of 0% and 100%. For mixed keyword and value positions compute the length's used
        for blending to percentages. This is possible since we compute the reference box bounds given the
        renderer.

        * page/animation/CSSPropertyAnimation.cpp:
        (WebCore::blendFunc): Pass additional RenderBox parameter.
        * rendering/style/BasicShapes.cpp:
        (WebCore::BasicShape::canBlend): Don't check circle/ellipse center anymore, but do check that both
        shapes use the same reference box.
        (WebCore::BasicShape::referenceBoxSize): Compute box dimension depending on reference box.
        (WebCore::BasicShapeCenterCoordinate::lengthForBlending): Convert to percentage for Bottom/Right.
        (WebCore::BasicShapeRectangle::blend):
        (WebCore::DeprecatedBasicShapeCircle::blend):
        (WebCore::BasicShapeCircle::blend):
        (WebCore::DeprecatedBasicShapeEllipse::blend):
        (WebCore::BasicShapeEllipse::blend):
        (WebCore::BasicShapePolygon::blend):
        (WebCore::BasicShapeInsetRectangle::blend):
        (WebCore::BasicShapeInset::blend):
        * rendering/style/BasicShapes.h:
        (WebCore::BasicShapeCenterCoordinate::blend): Use new lengthForBlending.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (160769 => 160770)


--- trunk/LayoutTests/ChangeLog	2013-12-18 17:26:21 UTC (rev 160769)
+++ trunk/LayoutTests/ChangeLog	2013-12-18 17:27:58 UTC (rev 160770)
@@ -1,3 +1,19 @@
+2013-12-18  Rob Buis  <rob.b...@samsung.com>
+
+        [CSS Shapes] Implement interpolation between keywords in basic shapes
+        https://bugs.webkit.org/show_bug.cgi?id=125108
+
+        Reviewed by Simon Fraser.
+
+        Add tests to shape-outside-animation when animating using keywords for the circle/ellipse center positions.
+        Also add tests for invalid mixing of keyword and values in the center coordinate to parsing-test-utils.js.
+
+        * fast/shapes/parsing/parsing-shape-inside-expected.txt:
+        * fast/shapes/parsing/parsing-shape-outside-expected.txt:
+        * fast/shapes/parsing/parsing-test-utils.js:
+        * fast/shapes/shape-outside-floats/shape-outside-animation-expected.txt:
+        * fast/shapes/shape-outside-floats/shape-outside-animation.html:
+
 2013-12-18  Dániel Bátyai  <dbatyai.u-sze...@partner.samsung.com>
 
         CSS: Null-pointer dereference with negative 'orphans' value.

Modified: trunk/LayoutTests/fast/shapes/parsing/parsing-shape-inside-expected.txt (160769 => 160770)


--- trunk/LayoutTests/fast/shapes/parsing/parsing-shape-inside-expected.txt	2013-12-18 17:26:21 UTC (rev 160769)
+++ trunk/LayoutTests/fast/shapes/parsing/parsing-shape-inside-expected.txt	2013-12-18 17:27:58 UTC (rev 160770)
@@ -191,6 +191,8 @@
 PASS getComputedStyleValue("-webkit-shape-inside", "circle(10px at 10px 10px at center)") is "auto"
 PASS getCSSText("-webkit-shape-inside", "circle(10px at center center 10px)") is ""
 PASS getComputedStyleValue("-webkit-shape-inside", "circle(10px at center center 10px)") is "auto"
+PASS getCSSText("-webkit-shape-inside", "circle(10px at 10% left)") is ""
+PASS getComputedStyleValue("-webkit-shape-inside", "circle(10px at 10% left)") is "auto"
 PASS getCSSText("-webkit-shape-inside", "circle(at 10px 10px 10px)") is ""
 PASS getComputedStyleValue("-webkit-shape-inside", "circle(at 10px 10px 10px)") is "auto"
 PASS getCSSText("-webkit-shape-inside", "circle(at 10px 10px at center)") is ""
@@ -211,6 +213,8 @@
 PASS getComputedStyleValue("-webkit-shape-inside", "ellipse(10px at 10px 10px at center)") is "auto"
 PASS getCSSText("-webkit-shape-inside", "ellipse(10px at center center 10px)") is ""
 PASS getComputedStyleValue("-webkit-shape-inside", "ellipse(10px at center center 10px)") is "auto"
+PASS getCSSText("-webkit-shape-inside", "ellipse(10px 10px at 10% left)") is ""
+PASS getComputedStyleValue("-webkit-shape-inside", "ellipse(10px 10px at 10% left)") is "auto"
 PASS getCSSText("-webkit-shape-inside", "ellipse(10px 20px 30px at center center 10px)") is ""
 PASS getComputedStyleValue("-webkit-shape-inside", "ellipse(10px 20px 30px at center center 10px)") is "auto"
 PASS getCSSText("-webkit-shape-inside", "ellipse(at 10px 10px 10px)") is ""

Modified: trunk/LayoutTests/fast/shapes/parsing/parsing-shape-outside-expected.txt (160769 => 160770)


--- trunk/LayoutTests/fast/shapes/parsing/parsing-shape-outside-expected.txt	2013-12-18 17:26:21 UTC (rev 160769)
+++ trunk/LayoutTests/fast/shapes/parsing/parsing-shape-outside-expected.txt	2013-12-18 17:27:58 UTC (rev 160770)
@@ -189,6 +189,8 @@
 PASS getComputedStyleValue("-webkit-shape-outside", "circle(10px at 10px 10px at center)") is "auto"
 PASS getCSSText("-webkit-shape-outside", "circle(10px at center center 10px)") is ""
 PASS getComputedStyleValue("-webkit-shape-outside", "circle(10px at center center 10px)") is "auto"
+PASS getCSSText("-webkit-shape-outside", "circle(10px at 10% left)") is ""
+PASS getComputedStyleValue("-webkit-shape-outside", "circle(10px at 10% left)") is "auto"
 PASS getCSSText("-webkit-shape-outside", "circle(at 10px 10px 10px)") is ""
 PASS getComputedStyleValue("-webkit-shape-outside", "circle(at 10px 10px 10px)") is "auto"
 PASS getCSSText("-webkit-shape-outside", "circle(at 10px 10px at center)") is ""
@@ -209,6 +211,8 @@
 PASS getComputedStyleValue("-webkit-shape-outside", "ellipse(10px at 10px 10px at center)") is "auto"
 PASS getCSSText("-webkit-shape-outside", "ellipse(10px at center center 10px)") is ""
 PASS getComputedStyleValue("-webkit-shape-outside", "ellipse(10px at center center 10px)") is "auto"
+PASS getCSSText("-webkit-shape-outside", "ellipse(10px 10px at 10% left)") is ""
+PASS getComputedStyleValue("-webkit-shape-outside", "ellipse(10px 10px at 10% left)") is "auto"
 PASS getCSSText("-webkit-shape-outside", "ellipse(10px 20px 30px at center center 10px)") is ""
 PASS getComputedStyleValue("-webkit-shape-outside", "ellipse(10px 20px 30px at center center 10px)") is "auto"
 PASS getCSSText("-webkit-shape-outside", "ellipse(at 10px 10px 10px)") is ""

Modified: trunk/LayoutTests/fast/shapes/parsing/parsing-test-utils.js (160769 => 160770)


--- trunk/LayoutTests/fast/shapes/parsing/parsing-test-utils.js	2013-12-18 17:26:21 UTC (rev 160769)
+++ trunk/LayoutTests/fast/shapes/parsing/parsing-test-utils.js	2013-12-18 17:27:58 UTC (rev 160770)
@@ -117,6 +117,7 @@
     "circle(10px at 10px 10px 10px)",
     "circle(10px at 10px 10px at center)",
     "circle(10px at center center 10px)",
+    "circle(10px at 10% left)",
     "circle(at 10px 10px 10px)",
     "circle(at 10px 10px at center)",
     "circle(at center center 10px)",
@@ -129,6 +130,7 @@
     "ellipse(10px at 10px 10px 10px)",
     "ellipse(10px at 10px 10px at center)",
     "ellipse(10px at center center 10px)",
+    "ellipse(10px 10px at 10% left)",
     "ellipse(10px 20px 30px at center center 10px)",
     "ellipse(at 10px 10px 10px)",
     "ellipse(at 10px 10px at center)",

Modified: trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-animation-expected.txt (160769 => 160770)


--- trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-animation-expected.txt	2013-12-18 17:26:21 UTC (rev 160769)
+++ trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-animation-expected.txt	2013-12-18 17:27:58 UTC (rev 160770)
@@ -4,10 +4,24 @@
 Moving Text
 Moving Text
 Moving Text
+Moving Text
+Moving Text
+Moving Text
+Moving Text
+Moving Text
+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% 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%)
 PASS - "webkitShapeOutside" property for "polygon2-box" element at 1s saw something close to: polygon(nonzero, 20% 20%, 80% 20%, 80% 80%, 20% 80%)
 PASS - "webkitShapeOutside" property for "circle-auto-box" element at 1s saw something close to: circle(50% at 50% 50%)
+PASS - "webkitShapeOutside" property for "circle-to-topleft-box" element at 1s saw something close to: circle(35% at 25% 25%)
+PASS - "webkitShapeOutside" property for "circle-to-topleft-box" element at 1s saw something close to: circle(35% at 25% 25%)
+PASS - "webkitShapeOutside" property for "circle-to-bottomright-using-keyword-box" element at 1s saw something close to: circle(35% at 75% 75%)
+PASS - "webkitShapeOutside" property for "circle-to-bottomright-using-keyword-box" element at 1s saw something close to: circle(35% at 75% 75%)
+PASS - "webkitShapeOutside" property for "circle-to-bottomright-extended-box" element at 1s saw something close to: circle(35% at 75% 75%)
+PASS - "webkitShapeOutside" property for "circle-to-bottomright-extended-using-keyword-box" element at 1s saw something close to: circle(35% at 70% 70%)
+PASS - "webkitShapeOutside" property for "circle-to-bottomright-extended-using-keyword-2-box" element at 1s saw something close to: circle(35% at 70% 70%)
 

Modified: trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-animation.html (160769 => 160770)


--- trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-animation.html	2013-12-18 17:26:21 UTC (rev 160769)
+++ trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-animation.html	2013-12-18 17:27:58 UTC (rev 160770)
@@ -10,7 +10,7 @@
     .box {
         height: 100px;
         width: 100px;
-        margin: 10px;
+        margin: 50px;
         float: left;
     }
 
@@ -38,6 +38,34 @@
       -webkit-animation: circle-auto-anim 2s linear
     }
 
+    #circle-to-topleft-box {
+      -webkit-animation: circle-to-topleft-anim 2s linear
+    }
+
+    #circle-to-topleft-using-keyword-box {
+      -webkit-animation: circle-to-topleft-using-keyword-anim 2s linear
+    }
+
+    #circle-to-bottomright-box {
+      -webkit-animation: circle-to-bottomright-anim 2s linear
+    }
+
+    #circle-to-bottomright-using-keyword-box {
+      -webkit-animation: circle-to-bottomright-using-keyword-anim 2s linear
+    }
+
+    #circle-to-bottomright-extended-box {
+      -webkit-animation: circle-to-bottomright-extended-anim 2s linear
+    }
+
+    #circle-to-bottomright-extended-using-keyword-box {
+      -webkit-animation: circle-to-bottomright-extended-using-keyword-anim 2s linear
+    }
+
+    #circle-to-bottomright-extended-using-keyword-2-box {
+      -webkit-animation: circle-to-bottomright-extended-using-keyword-2-anim 2s linear
+    }
+
     @-webkit-keyframes rectangle-anim {
         from { -webkit-shape-outside: rectangle(0%, 0%, 100%, 100%); }
         to   { -webkit-shape-outside: rectangle(20%, 20%, 60%, 60%); }
@@ -68,6 +96,40 @@
         to   { -webkit-shape-outside: circle(50% at 50% 50%); }
     }
 
+    @-webkit-keyframes circle-to-topleft-anim {
+        from { -webkit-shape-outside: circle(50% at 50% 50%); }
+        to   { -webkit-shape-outside: circle(20% at 0% 0%); }
+    }
+
+    @-webkit-keyframes circle-to-topleft-using-keyword-anim {
+        from { -webkit-shape-outside: circle(50% at 50% 50%); }
+        to   { -webkit-shape-outside: circle(20% at left top); }
+    }
+
+    @-webkit-keyframes circle-to-bottomright-anim {
+        from { -webkit-shape-outside: circle(50% at 50% 50%); }
+        to   { -webkit-shape-outside: circle(20% at 100% 100%); }
+    }
+
+    @-webkit-keyframes circle-to-bottomright-using-keyword-anim {
+        from { -webkit-shape-outside: circle(50% at 50% 50%); }
+        to   { -webkit-shape-outside: circle(20% at right bottom); }
+    }
+
+    @-webkit-keyframes circle-to-bottomright-extended-anim {
+        from { -webkit-shape-outside: circle(50% at 50% 50%); }
+        to   { -webkit-shape-outside: circle(20% at 100% 100%); }
+    }
+
+    @-webkit-keyframes circle-to-bottomright-extended-using-keyword-anim {
+        from { -webkit-shape-outside: circle(50% at 50% 50%); }
+        to   { -webkit-shape-outside: circle(20% at right 10% bottom 20px); }
+    }
+
+    @-webkit-keyframes circle-to-bottomright-extended-using-keyword-2-anim {
+        from { -webkit-shape-outside: circle(50% at 50% 50%) border-box; }
+        to   { -webkit-shape-outside: circle(20% at right 10% bottom 10px) border-box; }
+    }
   </style>
   <script src=""
   <script type="text/_javascript_">
@@ -79,6 +141,13 @@
       ["polygon-anim",  1, "polygon-box", "webkitShapeOutside", "polygon(nonzero, 10% 10%, 90% 10%, 90% 90%, 10% 90%)", 0.05],
       ["polygon2-anim",  1, "polygon2-box", "webkitShapeOutside", "polygon(nonzero, 20% 20%, 80% 20%, 80% 80%, 20% 80%)", 0.05],
       ["circle-auto-anim",  1, "circle-auto-box", "webkitShapeOutside", "circle(50% at 50% 50%)", 0.05],
+      ["circle-to-topleft-anim",  1, "circle-to-topleft-box", "webkitShapeOutside", "circle(35% at 25% 25%)", 0.05],
+      ["circle-to-topleft-anim",  1, "circle-to-topleft-box", "webkitShapeOutside", "circle(35% at 25% 25%)", 0.05],
+      ["circle-to-bottomright-using-keyword-anim",  1, "circle-to-bottomright-using-keyword-box", "webkitShapeOutside", "circle(35% at 75% 75%)", 0.05],
+      ["circle-to-bottomright-using-keyword-anim",  1, "circle-to-bottomright-using-keyword-box", "webkitShapeOutside", "circle(35% at 75% 75%)", 0.05],
+      ["circle-to-bottomright-extended-anim",  1, "circle-to-bottomright-extended-box", "webkitShapeOutside", "circle(35% at 75% 75%)", 0.05],
+      ["circle-to-bottomright-extended-using-keyword-anim",  1, "circle-to-bottomright-extended-using-keyword-box", "webkitShapeOutside", "circle(35% at 70% 70%)", 0.01],
+      ["circle-to-bottomright-extended-using-keyword-2-anim",  1, "circle-to-bottomright-extended-using-keyword-2-box", "webkitShapeOutside", "circle(35% at 70% 70%)", 0.01],
     ];
     
     runAnimationTest(expectedValues);
@@ -110,6 +179,34 @@
   <div class="box" id="circle-auto-box"></div>
   Moving Text
 </div>
+<div class='container'>
+  <div class="box" id="circle-to-topleft-box"></div>
+  Moving Text
+</div>
+<div class='container'>
+  <div class="box" id="circle-to-topleft-using-keyword-box"></div>
+  Moving Text
+</div>
+<div class='container'>
+  <div class="box" id="circle-to-bottomright-box"></div>
+  Moving Text
+</div>
+<div class='container'>
+  <div class="box" id="circle-to-bottomright-using-keyword-box"></div>
+  Moving Text
+</div>
+<div class='container'>
+  <div class="box" id="circle-to-bottomright-extended-box"></div>
+  Moving Text
+</div>
+<div class='container'>
+  <div class="box" id="circle-to-bottomright-extended-using-keyword-box"></div>
+  Moving Text
+</div>
+<div class='container'>
+  <div class="box" id="circle-to-bottomright-extended-using-keyword-2-box"></div>
+  Moving Text
+</div>
 
 <div id="result">
 </div>

Modified: trunk/Source/WebCore/ChangeLog (160769 => 160770)


--- trunk/Source/WebCore/ChangeLog	2013-12-18 17:26:21 UTC (rev 160769)
+++ trunk/Source/WebCore/ChangeLog	2013-12-18 17:27:58 UTC (rev 160770)
@@ -1,3 +1,33 @@
+2013-12-18  Rob Buis  <rob.b...@samsung.com>
+
+        [CSS Shapes] Implement interpolation between keywords in basic shapes
+        https://bugs.webkit.org/show_bug.cgi?id=125108
+
+        Reviewed by Simon Fraser.
+
+        Allow blending for all center coordinates since top/left and bottom/right default to correct
+        Length values of 0% and 100%. For mixed keyword and value positions compute the length's used
+        for blending to percentages. This is possible since we compute the reference box bounds given the
+        renderer.
+
+        * page/animation/CSSPropertyAnimation.cpp:
+        (WebCore::blendFunc): Pass additional RenderBox parameter.
+        * rendering/style/BasicShapes.cpp:
+        (WebCore::BasicShape::canBlend): Don't check circle/ellipse center anymore, but do check that both
+        shapes use the same reference box.
+        (WebCore::BasicShape::referenceBoxSize): Compute box dimension depending on reference box.
+        (WebCore::BasicShapeCenterCoordinate::lengthForBlending): Convert to percentage for Bottom/Right.
+        (WebCore::BasicShapeRectangle::blend):
+        (WebCore::DeprecatedBasicShapeCircle::blend):
+        (WebCore::BasicShapeCircle::blend):
+        (WebCore::DeprecatedBasicShapeEllipse::blend):
+        (WebCore::BasicShapeEllipse::blend):
+        (WebCore::BasicShapePolygon::blend):
+        (WebCore::BasicShapeInsetRectangle::blend):
+        (WebCore::BasicShapeInset::blend):
+        * rendering/style/BasicShapes.h:
+        (WebCore::BasicShapeCenterCoordinate::blend): Use new lengthForBlending.
+
 2013-12-18  Dániel Bátyai  <dbatyai.u-sze...@partner.samsung.com>
 
         CSS: Null-pointer dereference with negative 'orphans' value.

Modified: trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp (160769 => 160770)


--- trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp	2013-12-18 17:26:21 UTC (rev 160769)
+++ trunk/Source/WebCore/page/animation/CSSPropertyAnimation.cpp	2013-12-18 17:27:58 UTC (rev 160770)
@@ -125,7 +125,7 @@
     return to.blendByUsingMatrixInterpolation(from, progress, anim->renderer()->isBox() ? toRenderBox(anim->renderer())->borderBoxRect().size() : LayoutSize());
 }
 
-static inline PassRefPtr<ClipPathOperation> blendFunc(const AnimationBase*, ClipPathOperation* from, ClipPathOperation* to, double progress)
+static inline PassRefPtr<ClipPathOperation> blendFunc(const AnimationBase* anim, ClipPathOperation* from, ClipPathOperation* to, double progress)
 {
     if (!from || !to)
         return to;
@@ -140,11 +140,12 @@
     if (!fromShape->canBlend(toShape))
         return to;
 
-    return ShapeClipPathOperation::create(toShape->blend(fromShape, progress));
+    ASSERT(anim->renderer()->isBox());
+    return ShapeClipPathOperation::create(toShape->blend(fromShape, progress, *toRenderBox(anim->renderer())));
 }
 
 #if ENABLE(CSS_SHAPES)
-static inline PassRefPtr<ShapeValue> blendFunc(const AnimationBase*, ShapeValue* from, ShapeValue* to, double progress)
+static inline PassRefPtr<ShapeValue> blendFunc(const AnimationBase* anim, ShapeValue* from, ShapeValue* to, double progress)
 {
     if (!from || !to)
         return to;
@@ -159,7 +160,8 @@
     if (!fromShape->canBlend(toShape))
         return to;
 
-    return ShapeValue::createShapeValue(toShape->blend(fromShape, progress));
+    ASSERT(anim->renderer()->isBox());
+    return ShapeValue::createShapeValue(toShape->blend(fromShape, progress, *toRenderBox(anim->renderer())));
 }
 #endif
 

Modified: trunk/Source/WebCore/rendering/style/BasicShapes.cpp (160769 => 160770)


--- trunk/Source/WebCore/rendering/style/BasicShapes.cpp	2013-12-18 17:26:21 UTC (rev 160769)
+++ trunk/Source/WebCore/rendering/style/BasicShapes.cpp	2013-12-18 17:27:58 UTC (rev 160770)
@@ -35,6 +35,7 @@
 #include "FloatRect.h"
 #include "LengthFunctions.h"
 #include "Path.h"
+#include "RenderBox.h"
 
 namespace WebCore {
 
@@ -44,34 +45,63 @@
     if (type() != other->type())
         return false;
 
+    // Both shapes must use the same reference box.
+    if (box() != other->box())
+        return false;
+
     // Just polygons with same number of vertices can be animated.
     if (type() == BasicShape::BasicShapePolygonType
         && (static_cast<const BasicShapePolygon*>(this)->values().size() != static_cast<const BasicShapePolygon*>(other)->values().size()
         || static_cast<const BasicShapePolygon*>(this)->windRule() != static_cast<const BasicShapePolygon*>(other)->windRule()))
         return false;
 
-    // Circles with keywords for radii or center coordinates cannot be animated.
+    // Circles with keywords for radii coordinates cannot be animated.
     if (type() == BasicShape::BasicShapeCircleType) {
         const BasicShapeCircle* thisCircle = static_cast<const BasicShapeCircle*>(this);
         const BasicShapeCircle* otherCircle = static_cast<const BasicShapeCircle*>(other);
-        if (!thisCircle->radius().canBlend(otherCircle->radius())
-            || !thisCircle->centerX().canBlend(otherCircle->centerX())
-            || !thisCircle->centerY().canBlend(otherCircle->centerY()))
+        if (!thisCircle->radius().canBlend(otherCircle->radius()))
             return false;
     }
 
-    // Ellipses with keywords for radii or center coordinates cannot be animated.
+    // Ellipses with keywords for radii 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);
     return (thisEllipse->radiusX().canBlend(otherEllipse->radiusX())
-        && thisEllipse->radiusY().canBlend(otherEllipse->radiusY())
-        && thisEllipse->centerX().canBlend(otherEllipse->centerX())
-        && thisEllipse->centerY().canBlend(otherEllipse->centerY()));
+        && thisEllipse->radiusY().canBlend(otherEllipse->radiusY()));
 }
 
+FloatSize BasicShape::referenceBoxSize(const RenderBox& renderer) const
+{
+    switch (box()) {
+    case ContentBox:
+        return renderer.contentBoxRect().size();
+    case PaddingBox:
+        return renderer.paddingBoxRect().size();
+    case BorderBox:
+        return renderer.size();
+    case None: // If <box> is not supplied, then the reference box defaults to margin-box.
+    case MarginBox:
+        return FloatSize(renderer.marginLeft() + renderer.width() + renderer.marginRight(),
+            renderer.marginTop() + renderer.height() + renderer.marginBottom());
+    }
+
+    ASSERT_NOT_REACHED();
+    return FloatSize();
+}
+
+Length BasicShapeCenterCoordinate::lengthForBlending(const FloatSize& boxSize) const
+{
+    Length length = this->length();
+    if (keyword() == Right)
+        return Length(100 - (length.isPercent() ? length.percent() : 100.f * (length.value() / boxSize.width())), Percent);
+    if (keyword() == Bottom)
+        return Length(100 - (length.isPercent() ? length.percent() : 100.f * (length.value() / boxSize.height())), Percent);
+    return length;
+}
+
 void BasicShapeRectangle::path(Path& path, const FloatRect& boundingBox)
 {
     ASSERT(path.isEmpty());
@@ -89,7 +119,7 @@
     );
 }
 
-PassRefPtr<BasicShape> BasicShapeRectangle::blend(const BasicShape* other, double progress) const
+PassRefPtr<BasicShape> BasicShapeRectangle::blend(const BasicShape* other, double progress, const RenderBox&) const
 {
     ASSERT(type() == other->type());
 
@@ -119,7 +149,7 @@
     ));
 }
 
-PassRefPtr<BasicShape> DeprecatedBasicShapeCircle::blend(const BasicShape* other, double progress) const
+PassRefPtr<BasicShape> DeprecatedBasicShapeCircle::blend(const BasicShape* other, double progress, const RenderBox&) const
 {
     ASSERT(type() == other->type());
 
@@ -161,14 +191,15 @@
     ));
 }
 
-PassRefPtr<BasicShape> BasicShapeCircle::blend(const BasicShape* other, double progress) const
+PassRefPtr<BasicShape> BasicShapeCircle::blend(const BasicShape* other, double progress, const RenderBox& renderer) const
 {
     ASSERT(type() == other->type());
     const BasicShapeCircle* o = static_cast<const BasicShapeCircle*>(other);
     RefPtr<BasicShapeCircle> result =  BasicShapeCircle::create();
 
-    result->setCenterX(m_centerX.blend(o->centerX(), progress));
-    result->setCenterY(m_centerY.blend(o->centerY(), progress));
+    FloatSize boxSize = referenceBoxSize(renderer);
+    result->setCenterX(m_centerX.blend(o->centerX(), progress, boxSize));
+    result->setCenterY(m_centerY.blend(o->centerY(), progress, boxSize));
     result->setRadius(m_radius.blend(o->radius(), progress));
     return result.release();
 }
@@ -188,7 +219,7 @@
     ));
 }
 
-PassRefPtr<BasicShape> DeprecatedBasicShapeEllipse::blend(const BasicShape* other, double progress) const
+PassRefPtr<BasicShape> DeprecatedBasicShapeEllipse::blend(const BasicShape* other, double progress, const RenderBox&) const
 {
     ASSERT(type() == other->type());
 
@@ -228,7 +259,7 @@
         radiusY * 2));
 }
 
-PassRefPtr<BasicShape> BasicShapeEllipse::blend(const BasicShape* other, double progress) const
+PassRefPtr<BasicShape> BasicShapeEllipse::blend(const BasicShape* other, double progress, const RenderBox& renderer) const
 {
     ASSERT(type() == other->type());
     const BasicShapeEllipse* o = static_cast<const BasicShapeEllipse*>(other);
@@ -243,8 +274,9 @@
         return result;
     }
 
-    result->setCenterX(m_centerX.blend(o->centerX(), progress));
-    result->setCenterY(m_centerY.blend(o->centerY(), progress));
+    FloatSize boxSize = referenceBoxSize(renderer);
+    result->setCenterX(m_centerX.blend(o->centerX(), progress, boxSize));
+    result->setCenterY(m_centerY.blend(o->centerY(), progress, boxSize));
     result->setRadiusX(m_radiusX.blend(o->radiusX(), progress));
     result->setRadiusY(m_radiusY.blend(o->radiusY(), progress));
     return result.release();
@@ -268,7 +300,7 @@
     path.closeSubpath();
 }
 
-PassRefPtr<BasicShape> BasicShapePolygon::blend(const BasicShape* other, double progress) const
+PassRefPtr<BasicShape> BasicShapePolygon::blend(const BasicShape* other, double progress, const RenderBox&) const
 {
     ASSERT(type() == other->type());
 
@@ -310,7 +342,7 @@
     );
 }
 
-PassRefPtr<BasicShape> BasicShapeInsetRectangle::blend(const BasicShape* other, double progress) const
+PassRefPtr<BasicShape> BasicShapeInsetRectangle::blend(const BasicShape* other, double progress, const RenderBox&) const
 {
     ASSERT(type() == other->type());
 
@@ -356,7 +388,7 @@
     );
 }
 
-PassRefPtr<BasicShape> BasicShapeInset::blend(const BasicShape* other, double progress) const
+PassRefPtr<BasicShape> BasicShapeInset::blend(const BasicShape* other, double progress, const RenderBox&) const
 {
     ASSERT(type() == other->type());
 

Modified: trunk/Source/WebCore/rendering/style/BasicShapes.h (160769 => 160770)


--- trunk/Source/WebCore/rendering/style/BasicShapes.h	2013-12-18 17:26:21 UTC (rev 160769)
+++ trunk/Source/WebCore/rendering/style/BasicShapes.h	2013-12-18 17:27:58 UTC (rev 160770)
@@ -41,6 +41,7 @@
 
 class FloatRect;
 class Path;
+class RenderBox;
 
 class BasicShape : public RefCounted<BasicShape> {
 public:
@@ -69,7 +70,7 @@
 
     virtual void path(Path&, const FloatRect&) = 0;
     virtual WindRule windRule() const { return RULE_NONZERO; }
-    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const = 0;
+    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double, const RenderBox&) const = 0;
 
     virtual Type type() const = 0;
 
@@ -82,6 +83,8 @@
     {
     }
 
+    FloatSize referenceBoxSize(const RenderBox&) const;
+
 private:
     ReferenceBox m_box;
 };
@@ -113,7 +116,7 @@
     }
 
     virtual void path(Path&, const FloatRect&) OVERRIDE;
-    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
+    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double, const RenderBox&) const OVERRIDE;
 
     virtual Type type() const OVERRIDE { return BasicShapeRectangleType; }
 private:
@@ -143,21 +146,13 @@
 
     Keyword keyword() const { return m_keyword; }
     const Length& length() const { return m_length; }
+    Length lengthForBlending(const FloatSize&) const;
 
-    bool canBlend(const BasicShapeCenterCoordinate& other) const
+    BasicShapeCenterCoordinate blend(const BasicShapeCenterCoordinate& other, double progress, const FloatSize& boxSize) const
     {
-        // FIXME determine how to interpolate between keywords. See bug 125108.
-        return m_keyword == None && other.keyword() == None;
+        return BasicShapeCenterCoordinate(lengthForBlending(boxSize).blend(other.lengthForBlending(boxSize), progress));
     }
 
-    BasicShapeCenterCoordinate blend(const BasicShapeCenterCoordinate& other, double progress) const
-    {
-        if (m_keyword != None || other.keyword() != None)
-            return BasicShapeCenterCoordinate(other);
-
-        return BasicShapeCenterCoordinate(m_length.blend(other.length(), progress));
-    }
-
 private:
     Keyword m_keyword;
     Length m_length;
@@ -212,7 +207,7 @@
     void setRadius(BasicShapeRadius radius) { m_radius = std::move(radius); }
 
     virtual void path(Path&, const FloatRect&) OVERRIDE;
-    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
+    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double, const RenderBox&) const OVERRIDE;
 
     virtual Type type() const OVERRIDE { return BasicShapeCircleType; }
 private:
@@ -236,7 +231,7 @@
     void setRadius(Length radius) { m_radius = std::move(radius); }
 
     virtual void path(Path&, const FloatRect&) OVERRIDE;
-    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
+    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double, const RenderBox&) const OVERRIDE;
 
     virtual Type type() const OVERRIDE { return DeprecatedBasicShapeCircleType; }
 private:
@@ -263,7 +258,7 @@
     void setRadiusY(BasicShapeRadius radiusY) { m_radiusY = std::move(radiusY); }
 
     virtual void path(Path&, const FloatRect&) OVERRIDE;
-    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
+    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double, const RenderBox&) const OVERRIDE;
 
     virtual Type type() const OVERRIDE { return BasicShapeEllipseType; }
 private:
@@ -290,7 +285,7 @@
     void setRadiusY(Length radiusY) { m_radiusY = std::move(radiusY); }
 
     virtual void path(Path&, const FloatRect&) OVERRIDE;
-    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
+    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double, const RenderBox&) const OVERRIDE;
 
     virtual Type type() const OVERRIDE { return DeprecatedBasicShapeEllipseType; }
 private:
@@ -314,7 +309,7 @@
     void appendPoint(Length x, Length y) { m_values.append(std::move(x)); m_values.append(std::move(y)); }
 
     virtual void path(Path&, const FloatRect&) OVERRIDE;
-    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
+    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double, const RenderBox&) const OVERRIDE;
 
     virtual WindRule windRule() const OVERRIDE { return m_windRule; }
 
@@ -355,7 +350,7 @@
     }
 
     virtual void path(Path&, const FloatRect&) OVERRIDE;
-    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
+    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double, const RenderBox&) const OVERRIDE;
 
     virtual Type type() const OVERRIDE { return BasicShapeInsetRectangleType; }
 private:
@@ -394,7 +389,7 @@
     void setBottomLeftRadius(LengthSize radius) { m_bottomLeftRadius = std::move(radius); }
 
     virtual void path(Path&, const FloatRect&) OVERRIDE;
-    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
+    virtual PassRefPtr<BasicShape> blend(const BasicShape*, double, const RenderBox&) const OVERRIDE;
 
     virtual Type type() const OVERRIDE { return BasicShapeInsetType; }
 private:
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to