Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / CSSBasicShapes.cpp
index d518729..692fff7 100644 (file)
 #include "config.h"
 #include "core/css/CSSBasicShapes.h"
 
+#include "core/css/CSSValuePool.h"
+#include "core/css/Pair.h"
+#include "platform/Length.h"
 #include "wtf/text/StringBuilder.h"
 
 using namespace WTF;
 
 namespace WebCore {
 
-static String buildRectangleString(const String& x, const String& y, const String& width, const String& height, const String& radiusX, const String& radiusY, const String& layoutBox)
-{
-    const char opening[] = "rectangle(";
-    const char separator[] = ", ";
-    StringBuilder result;
-    // Compute the required capacity in advance to reduce allocations.
-    result.reserveCapacity((sizeof(opening) - 1) + (5 * (sizeof(separator) - 1)) + 1 + x.length() + y.length() + width.length() + height.length() + radiusX.length() + radiusY.length() + (layoutBox.isEmpty() ? 0 : layoutBox.length() + 1));
-    result.appendLiteral(opening);
-    result.append(x);
-    result.appendLiteral(separator);
-    result.append(y);
-    result.appendLiteral(separator);
-    result.append(width);
-    result.appendLiteral(separator);
-    result.append(height);
-    if (!radiusX.isNull()) {
-        result.appendLiteral(separator);
-        result.append(radiusX);
-        if (!radiusY.isNull()) {
-            result.appendLiteral(separator);
-            result.append(radiusY);
-        }
-    }
-    if (!layoutBox.isEmpty()) {
-        result.append(' ');
-        result.append(layoutBox);
-    }
-    result.append(')');
-    return result.toString();
-}
-
-String CSSBasicShapeRectangle::cssText() const
-{
-    return buildRectangleString(m_x->cssText(),
-        m_y->cssText(),
-        m_width->cssText(),
-        m_height->cssText(),
-        m_radiusX.get() ? m_radiusX->cssText() : String(),
-        m_radiusY.get() ? m_radiusY->cssText() : String(),
-        m_layoutBox ? m_layoutBox->cssText() : String());
-}
-
-bool CSSBasicShapeRectangle::equals(const CSSBasicShape& shape) const
-{
-    if (shape.type() != CSSBasicShapeRectangleType)
-        return false;
-
-    const CSSBasicShapeRectangle& other = static_cast<const CSSBasicShapeRectangle&>(shape);
-    return compareCSSValuePtr(m_x, other.m_x)
-        && compareCSSValuePtr(m_y, other.m_y)
-        && compareCSSValuePtr(m_width, other.m_width)
-        && compareCSSValuePtr(m_height, other.m_height)
-        && compareCSSValuePtr(m_radiusX, other.m_radiusX)
-        && compareCSSValuePtr(m_radiusY, other.m_radiusY)
-        && compareCSSValuePtr(m_layoutBox, other.m_layoutBox);
-}
-
-String CSSBasicShapeRectangle::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
-    return buildRectangleString(m_x->serializeResolvingVariables(variables),
-        m_y->serializeResolvingVariables(variables),
-        m_width->serializeResolvingVariables(variables),
-        m_height->serializeResolvingVariables(variables),
-        m_radiusX.get() ? m_radiusX->serializeResolvingVariables(variables) : String(),
-        m_radiusY.get() ? m_radiusY->serializeResolvingVariables(variables) : String(),
-        m_layoutBox ? m_layoutBox->serializeResolvingVariables(variables) : String());
-}
-
-bool CSSBasicShapeRectangle::hasVariableReference() const
-{
-    return m_x->hasVariableReference()
-        || m_y->hasVariableReference()
-        || m_width->hasVariableReference()
-        || m_height->hasVariableReference()
-        || (m_radiusX.get() && m_radiusX->hasVariableReference())
-        || (m_radiusY.get() && m_radiusY->hasVariableReference())
-        || (m_layoutBox && m_layoutBox->hasVariableReference());
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CSSBasicShape)
 
-static String buildCircleString(const String& radius, const String& centerX, const String& centerY, const String& layoutBox)
+static String buildCircleString(const String& radius, const String& centerX, const String& centerY, const String& box)
 {
     char at[] = "at";
     char separator[] = " ";
@@ -134,83 +60,84 @@ static String buildCircleString(const String& radius, const String& centerX, con
         result.append(centerY);
     }
     result.append(")");
-    if (layoutBox.length()) {
+    if (box.length()) {
         result.appendLiteral(separator);
-        result.append(layoutBox);
+        result.append(box);
     }
     return result.toString();
 }
 
-String CSSBasicShapeCircle::cssText() const
+static String serializePositionOffset(const Pair& offset, const Pair& other)
 {
-    return buildCircleString(m_radius ? m_radius->cssText() : String(),
-        m_centerX ? m_centerX->cssText() : String(),
-        m_centerY ? m_centerY->cssText() : String(),
-        m_layoutBox ? m_layoutBox->cssText() : String());
+    if ((offset.first()->getValueID() == CSSValueLeft && other.first()->getValueID() == CSSValueTop)
+        || (offset.first()->getValueID() == CSSValueTop && other.first()->getValueID() == CSSValueLeft))
+        return offset.second()->cssText();
+    return offset.cssText();
 }
 
-bool CSSBasicShapeCircle::equals(const CSSBasicShape& shape) const
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> buildSerializablePositionOffset(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> offset, CSSValueID defaultSide)
 {
-    if (shape.type() != CSSBasicShapeCircleType)
-        return false;
+    CSSValueID side = defaultSide;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> amount = nullptr;
 
-    const CSSBasicShapeCircle& other = static_cast<const CSSBasicShapeCircle&>(shape);
-    return compareCSSValuePtr(m_centerX, other.m_centerX)
-        && compareCSSValuePtr(m_centerY, other.m_centerY)
-        && compareCSSValuePtr(m_radius, other.m_radius)
-        && compareCSSValuePtr(m_layoutBox, other.m_layoutBox);
-}
+    if (!offset) {
+        side = CSSValueCenter;
+    } else if (offset->isValueID()) {
+        side = offset->getValueID();
+    } else if (Pair* pair = offset->getPairValue()) {
+        side = pair->first()->getValueID();
+        amount = pair->second();
+    } else {
+        amount = offset;
+    }
 
-String CSSBasicShapeCircle::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
-    return buildCircleString(m_radius.get() ? m_radius->serializeResolvingVariables(variables) : String(),
-        m_centerX.get() ? m_centerX->serializeResolvingVariables(variables) : String(),
-        m_centerY.get() ? m_centerY->serializeResolvingVariables(variables) : String(),
-        m_layoutBox.get() ? m_layoutBox->serializeResolvingVariables(variables) : String());
-}
+    if (side == CSSValueCenter) {
+        side = defaultSide;
+        amount = cssValuePool().createValue(Length(50, Percent));
+    } else if ((side == CSSValueRight || side == CSSValueBottom)
+        && amount->isPercentage()) {
+        side = defaultSide;
+        amount = cssValuePool().createValue(Length(100 - amount->getFloatValue(), Percent));
+    } else if (amount->isLength() && !amount->getFloatValue()) {
+        if (side == CSSValueRight || side == CSSValueBottom)
+            amount = cssValuePool().createValue(Length(100, Percent));
+        else
+            amount = cssValuePool().createValue(Length(0, Percent));
+        side = defaultSide;
+    }
 
-bool CSSBasicShapeCircle::hasVariableReference() const
-{
-    return (m_centerX && m_centerX->hasVariableReference())
-        || (m_centerY && m_centerY->hasVariableReference())
-        || (m_radius && m_radius->hasVariableReference())
-        || (m_layoutBox && m_layoutBox->hasVariableReference());
+    return cssValuePool().createValue(Pair::create(cssValuePool().createValue(side), amount.release(), Pair::KeepIdenticalValues));
 }
 
-static String buildDeprecatedCircleString(const String& x, const String& y, const String& radius)
+String CSSBasicShapeCircle::cssText() const
 {
-    return "circle(" + x + ", " + y + ", " + radius + ')';
-}
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> normalizedCX = buildSerializablePositionOffset(m_centerX, CSSValueLeft);
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> normalizedCY = buildSerializablePositionOffset(m_centerY, CSSValueTop);
 
-String CSSDeprecatedBasicShapeCircle::cssText() const
-{
-    return buildDeprecatedCircleString(m_centerX->cssText(), m_centerY->cssText(), m_radius->cssText());
+    return buildCircleString(m_radius ? m_radius->cssText() : String(),
+        serializePositionOffset(*normalizedCX->getPairValue(), *normalizedCY->getPairValue()),
+        serializePositionOffset(*normalizedCY->getPairValue(), *normalizedCX->getPairValue()),
+        m_referenceBox ? m_referenceBox->cssText() : String());
 }
 
-bool CSSDeprecatedBasicShapeCircle::equals(const CSSBasicShape& shape) const
+bool CSSBasicShapeCircle::equals(const CSSBasicShape& shape) const
 {
-    if (shape.type() != CSSDeprecatedBasicShapeCircleType)
+    if (shape.type() != CSSBasicShapeCircleType)
         return false;
 
-    const CSSDeprecatedBasicShapeCircle& other = static_cast<const CSSDeprecatedBasicShapeCircle&>(shape);
+    const CSSBasicShapeCircle& other = static_cast<const CSSBasicShapeCircle&>(shape);
     return compareCSSValuePtr(m_centerX, other.m_centerX)
         && compareCSSValuePtr(m_centerY, other.m_centerY)
-        && compareCSSValuePtr(m_radius, other.m_radius);
-}
-
-String CSSDeprecatedBasicShapeCircle::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
-    return buildDeprecatedCircleString(m_centerX->serializeResolvingVariables(variables),
-        m_centerY->serializeResolvingVariables(variables),
-        m_radius->serializeResolvingVariables(variables));
+        && compareCSSValuePtr(m_radius, other.m_radius)
+        && compareCSSValuePtr(m_referenceBox, other.m_referenceBox);
 }
 
-bool CSSDeprecatedBasicShapeCircle::hasVariableReference() const
+void CSSBasicShapeCircle::trace(Visitor* visitor)
 {
-    return m_centerX->hasVariableReference()
-        || m_centerY->hasVariableReference()
-        || m_radius->hasVariableReference()
-        || (m_layoutBox && m_layoutBox->hasVariableReference());
+    visitor->trace(m_centerX);
+    visitor->trace(m_centerY);
+    visitor->trace(m_radius);
+    CSSBasicShape::trace(visitor);
 }
 
 static String buildEllipseString(const String& radiusX, const String& radiusY, const String& centerX, const String& centerY, const String& box)
@@ -250,11 +177,14 @@ static String buildEllipseString(const String& radiusX, const String& radiusY, c
 
 String CSSBasicShapeEllipse::cssText() const
 {
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> normalizedCX = buildSerializablePositionOffset(m_centerX, CSSValueLeft);
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> normalizedCY = buildSerializablePositionOffset(m_centerY, CSSValueTop);
+
     return buildEllipseString(m_radiusX ? m_radiusX->cssText() : String(),
         m_radiusY ? m_radiusY->cssText() : String(),
-        m_centerX ? m_centerX->cssText() : String(),
-        m_centerY ? m_centerY->cssText() : String(),
-        m_layoutBox ? m_layoutBox->cssText() : String());
+        serializePositionOffset(*normalizedCX->getPairValue(), *normalizedCY->getPairValue()),
+        serializePositionOffset(*normalizedCY->getPairValue(), *normalizedCX->getPairValue()),
+        m_referenceBox ? m_referenceBox->cssText() : String());
 }
 
 bool CSSBasicShapeEllipse::equals(const CSSBasicShape& shape) const
@@ -267,75 +197,27 @@ bool CSSBasicShapeEllipse::equals(const CSSBasicShape& shape) const
         && compareCSSValuePtr(m_centerY, other.m_centerY)
         && compareCSSValuePtr(m_radiusX, other.m_radiusX)
         && compareCSSValuePtr(m_radiusY, other.m_radiusY)
-        && compareCSSValuePtr(m_layoutBox, other.m_layoutBox);
+        && compareCSSValuePtr(m_referenceBox, other.m_referenceBox);
 }
 
-String CSSBasicShapeEllipse::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
+void CSSBasicShapeEllipse::trace(Visitor* visitor)
 {
-    return buildEllipseString(m_radiusX.get() ? m_radiusX->serializeResolvingVariables(variables) : String(),
-        m_radiusY.get() ? m_radiusY->serializeResolvingVariables(variables) : String(),
-        m_centerX.get() ? m_centerX->serializeResolvingVariables(variables) : String(),
-        m_centerY.get() ? m_centerY->serializeResolvingVariables(variables) : String(),
-        m_layoutBox.get() ? m_layoutBox->serializeResolvingVariables(variables) : String());
+    visitor->trace(m_centerX);
+    visitor->trace(m_centerY);
+    visitor->trace(m_radiusX);
+    visitor->trace(m_radiusY);
+    CSSBasicShape::trace(visitor);
 }
 
-bool CSSBasicShapeEllipse::hasVariableReference() const
-{
-    return (m_centerX && m_centerX->hasVariableReference())
-        || (m_centerY && m_centerY->hasVariableReference())
-        || (m_radiusX && m_radiusX->hasVariableReference())
-        || (m_radiusY && m_radiusY->hasVariableReference())
-        || (m_layoutBox && m_layoutBox->hasVariableReference());
-}
-
-static String buildDeprecatedEllipseString(const String& x, const String& y, const String& radiusX, const String& radiusY)
-{
-    return "ellipse(" + x + ", " + y + ", " + radiusX + ", " + radiusY + ')';
-}
-
-String CSSDeprecatedBasicShapeEllipse::cssText() const
-{
-    return buildDeprecatedEllipseString(m_centerX->cssText(), m_centerY->cssText(), m_radiusX->cssText(), m_radiusY->cssText());
-}
-
-bool CSSDeprecatedBasicShapeEllipse::equals(const CSSBasicShape& shape) const
-{
-    if (shape.type() != CSSDeprecatedBasicShapeEllipseType)
-        return false;
-
-    const CSSDeprecatedBasicShapeEllipse& other = static_cast<const CSSDeprecatedBasicShapeEllipse&>(shape);
-    return compareCSSValuePtr(m_centerX, other.m_centerX)
-        && compareCSSValuePtr(m_centerY, other.m_centerY)
-        && compareCSSValuePtr(m_radiusX, other.m_radiusX)
-        && compareCSSValuePtr(m_radiusY, other.m_radiusY);
-}
-
-String CSSDeprecatedBasicShapeEllipse::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
-    return buildDeprecatedEllipseString(m_centerX->serializeResolvingVariables(variables),
-        m_centerY->serializeResolvingVariables(variables),
-        m_radiusX->serializeResolvingVariables(variables),
-        m_radiusY->serializeResolvingVariables(variables));
-}
-
-bool CSSDeprecatedBasicShapeEllipse::hasVariableReference() const
-{
-    return m_centerX->hasVariableReference()
-        || m_centerY->hasVariableReference()
-        || m_radiusX->hasVariableReference()
-        || m_radiusY->hasVariableReference()
-        || (m_layoutBox && m_layoutBox->hasVariableReference());
-}
-
-static String buildPolygonString(const WindRule& windRule, const Vector<String>& points, const String& layoutBox)
+static String buildPolygonString(const WindRule& windRule, const Vector<String>& points, const String& box)
 {
     ASSERT(!(points.size() % 2));
 
     StringBuilder result;
     const char evenOddOpening[] = "polygon(evenodd, ";
-    const char nonZeroOpening[] = "polygon(nonzero, ";
+    const char nonZeroOpening[] = "polygon(";
     const char commaSeparator[] = ", ";
-    COMPILE_ASSERT(sizeof(evenOddOpening) == sizeof(nonZeroOpening), polygon_string_openings_have_same_length);
+    COMPILE_ASSERT(sizeof(evenOddOpening) > sizeof(nonZeroOpening), polygon_string_openings_have_same_length);
 
     // Compute the required capacity in advance to reduce allocations.
     size_t length = sizeof(evenOddOpening) - 1;
@@ -345,8 +227,8 @@ static String buildPolygonString(const WindRule& windRule, const Vector<String>&
         // add length of two strings, plus one for the space separator.
         length += points[i].length() + 1 + points[i + 1].length();
     }
-    if (!layoutBox.isEmpty())
-        length += layoutBox.length() + 1;
+    if (!box.isEmpty())
+        length += box.length() + 1;
     result.reserveCapacity(length);
 
     if (windRule == RULE_EVENODD)
@@ -364,9 +246,9 @@ static String buildPolygonString(const WindRule& windRule, const Vector<String>&
 
     result.append(')');
 
-    if (!layoutBox.isEmpty()) {
+    if (!box.isEmpty()) {
         result.append(' ');
-        result.append(layoutBox);
+        result.append(box);
     }
 
     return result.toString();
@@ -380,7 +262,7 @@ String CSSBasicShapePolygon::cssText() const
     for (size_t i = 0; i < m_values.size(); ++i)
         points.append(m_values.at(i)->cssText());
 
-    return buildPolygonString(m_windRule, points, m_layoutBox ? m_layoutBox->cssText() : String());
+    return buildPolygonString(m_windRule, points, m_referenceBox ? m_referenceBox->cssText() : String());
 }
 
 bool CSSBasicShapePolygon::equals(const CSSBasicShape& shape) const
@@ -390,114 +272,162 @@ bool CSSBasicShapePolygon::equals(const CSSBasicShape& shape) const
 
     const CSSBasicShapePolygon& rhs = static_cast<const CSSBasicShapePolygon&>(shape);
 
-    if (!compareCSSValuePtr(m_layoutBox, rhs.m_layoutBox))
+    if (!compareCSSValuePtr(m_referenceBox, rhs.m_referenceBox))
         return false;
 
-    return compareCSSValueVector<CSSPrimitiveValue>(m_values, rhs.m_values);
+    return compareCSSValueVector(m_values, rhs.m_values);
 }
 
-String CSSBasicShapePolygon::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
+void CSSBasicShapePolygon::trace(Visitor* visitor)
 {
-    Vector<String> points;
-    points.reserveInitialCapacity(m_values.size());
-
-    for (size_t i = 0; i < m_values.size(); ++i)
-        points.append(m_values.at(i)->serializeResolvingVariables(variables));
-
-    return buildPolygonString(m_windRule, points, m_layoutBox ? m_layoutBox->serializeResolvingVariables(variables) : String());
+    visitor->trace(m_values);
+    CSSBasicShape::trace(visitor);
 }
 
-bool CSSBasicShapePolygon::hasVariableReference() const
+static bool buildInsetRadii(Vector<String> &radii, const String& topLeftRadius, const String& topRightRadius, const String& bottomRightRadius, const String& bottomLeftRadius)
 {
-    if (m_layoutBox && m_layoutBox->hasVariableReference())
-        return true;
+    bool showBottomLeft = topRightRadius != bottomLeftRadius;
+    bool showBottomRight = showBottomLeft || (bottomRightRadius != topLeftRadius);
+    bool showTopRight = showBottomRight || (topRightRadius != topLeftRadius);
 
-    for (size_t i = 0; i < m_values.size(); ++i) {
-        if (m_values.at(i)->hasVariableReference())
-            return true;
-    }
-    return false;
+    radii.append(topLeftRadius);
+    if (showTopRight)
+        radii.append(topRightRadius);
+    if (showBottomRight)
+        radii.append(bottomRightRadius);
+    if (showBottomLeft)
+        radii.append(bottomLeftRadius);
+
+    return radii.size() == 1 && radii[0] == "0px";
 }
 
-static String buildInsetRectangleString(const String& top, const String& right, const String& bottom, const String& left, const String& radiusX, const String& radiusY, const String& layoutBox)
+static String buildInsetString(const String& top, const String& right, const String& bottom, const String& left,
+    const String& topLeftRadiusWidth, const String& topLeftRadiusHeight,
+    const String& topRightRadiusWidth, const String& topRightRadiusHeight,
+    const String& bottomRightRadiusWidth, const String& bottomRightRadiusHeight,
+    const String& bottomLeftRadiusWidth, const String& bottomLeftRadiusHeight)
 {
-    const char opening[] = "inset-rectangle(";
-    const char separator[] = ", ";
+    char opening[] = "inset(";
+    char separator[] = " ";
+    char cornersSeparator[] = "round";
     StringBuilder result;
-    // Compute the required capacity in advance to reduce allocations.
-    result.reserveCapacity((sizeof(opening) - 1) + (5 * (sizeof(separator) - 1)) + 1 + top.length() + right.length() + bottom.length() + left.length() + radiusX.length() + radiusY.length() + (layoutBox.isEmpty() ? 0 : layoutBox.length() + 1));
     result.appendLiteral(opening);
     result.append(top);
-    result.appendLiteral(separator);
-    result.append(right);
-    result.appendLiteral(separator);
-    result.append(bottom);
-    result.appendLiteral(separator);
-    result.append(left);
-    if (!radiusX.isNull()) {
+    bool showLeftArg = !left.isNull() && left != right;
+    bool showBottomArg = !bottom.isNull() && (bottom != top || showLeftArg);
+    bool showRightArg = !right.isNull() && (right != top || showBottomArg);
+    if (showRightArg) {
         result.appendLiteral(separator);
-        result.append(radiusX);
-        if (!radiusY.isNull()) {
+        result.append(right);
+    }
+    if (showBottomArg) {
+        result.appendLiteral(separator);
+        result.append(bottom);
+    }
+    if (showLeftArg) {
+        result.appendLiteral(separator);
+        result.append(left);
+    }
+
+    if (!topLeftRadiusWidth.isNull() && !topLeftRadiusHeight.isNull()) {
+        Vector<String> horizontalRadii;
+        bool areDefaultCornerRadii = buildInsetRadii(horizontalRadii, topLeftRadiusWidth, topRightRadiusWidth, bottomRightRadiusWidth, bottomLeftRadiusWidth);
+
+        Vector<String> verticalRadii;
+        areDefaultCornerRadii &= buildInsetRadii(verticalRadii, topLeftRadiusHeight, topRightRadiusHeight, bottomRightRadiusHeight, bottomLeftRadiusHeight);
+
+        if (!areDefaultCornerRadii) {
             result.appendLiteral(separator);
-            result.append(radiusY);
+            result.appendLiteral(cornersSeparator);
+
+            for (size_t i = 0; i < horizontalRadii.size(); ++i) {
+                result.appendLiteral(separator);
+                result.append(horizontalRadii[i]);
+            }
+            if (horizontalRadii != verticalRadii) {
+                result.appendLiteral(separator);
+                result.appendLiteral("/");
+
+                for (size_t i = 0; i < verticalRadii.size(); ++i) {
+                    result.appendLiteral(separator);
+                    result.append(verticalRadii[i]);
+                }
+            }
         }
     }
     result.append(')');
 
-    if (!layoutBox.isEmpty()) {
-        result.append(' ');
-        result.append(layoutBox);
-    }
-
     return result.toString();
 }
 
-String CSSBasicShapeInsetRectangle::cssText() const
+static inline void updateCornerRadiusWidthAndHeight(CSSPrimitiveValue* corner, String& width, String& height)
+{
+    if (!corner)
+        return;
+
+    Pair* radius = corner->getPairValue();
+    width = radius->first() ? radius->first()->cssText() : String("0");
+    if (radius->second())
+        height = radius->second()->cssText();
+}
+
+String CSSBasicShapeInset::cssText() const
 {
-    return buildInsetRectangleString(m_top->cssText(),
-        m_right->cssText(),
-        m_bottom->cssText(),
-        m_left->cssText(),
-        m_radiusX.get() ? m_radiusX->cssText() : String(),
-        m_radiusY.get() ? m_radiusY->cssText() : String(),
-        m_layoutBox ? m_layoutBox->cssText() : String());
+    String topLeftRadiusWidth;
+    String topLeftRadiusHeight;
+    String topRightRadiusWidth;
+    String topRightRadiusHeight;
+    String bottomRightRadiusWidth;
+    String bottomRightRadiusHeight;
+    String bottomLeftRadiusWidth;
+    String bottomLeftRadiusHeight;
+
+    updateCornerRadiusWidthAndHeight(topLeftRadius(), topLeftRadiusWidth, topLeftRadiusHeight);
+    updateCornerRadiusWidthAndHeight(topRightRadius(), topRightRadiusWidth, topRightRadiusHeight);
+    updateCornerRadiusWidthAndHeight(bottomRightRadius(), bottomRightRadiusWidth, bottomRightRadiusHeight);
+    updateCornerRadiusWidthAndHeight(bottomLeftRadius(), bottomLeftRadiusWidth, bottomLeftRadiusHeight);
+
+    return buildInsetString(m_top ? m_top->cssText() : String(),
+        m_right ? m_right->cssText() : String(),
+        m_bottom ? m_bottom->cssText() : String(),
+        m_left ? m_left->cssText() : String(),
+        topLeftRadiusWidth,
+        topLeftRadiusHeight,
+        topRightRadiusWidth,
+        topRightRadiusHeight,
+        bottomRightRadiusWidth,
+        bottomRightRadiusHeight,
+        bottomLeftRadiusWidth,
+        bottomLeftRadiusHeight);
 }
 
-bool CSSBasicShapeInsetRectangle::equals(const CSSBasicShape& shape) const
+bool CSSBasicShapeInset::equals(const CSSBasicShape& shape) const
 {
-    if (shape.type() != CSSBasicShapeInsetRectangleType)
+    if (shape.type() != CSSBasicShapeInsetType)
         return false;
 
-    const CSSBasicShapeInsetRectangle& other = static_cast<const CSSBasicShapeInsetRectangle&>(shape);
+    const CSSBasicShapeInset& other = static_cast<const CSSBasicShapeInset&>(shape);
     return compareCSSValuePtr(m_top, other.m_top)
         && compareCSSValuePtr(m_right, other.m_right)
         && compareCSSValuePtr(m_bottom, other.m_bottom)
         && compareCSSValuePtr(m_left, other.m_left)
-        && compareCSSValuePtr(m_radiusX, other.m_radiusX)
-        && compareCSSValuePtr(m_radiusY, other.m_radiusY)
-        && compareCSSValuePtr(m_layoutBox, other.m_layoutBox);
-}
-
-String CSSBasicShapeInsetRectangle::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
-    return buildInsetRectangleString(m_top->serializeResolvingVariables(variables),
-        m_right->serializeResolvingVariables(variables),
-        m_bottom->serializeResolvingVariables(variables),
-        m_left->serializeResolvingVariables(variables),
-        m_radiusX.get() ? m_radiusX->serializeResolvingVariables(variables) : String(),
-        m_radiusY.get() ? m_radiusY->serializeResolvingVariables(variables) : String(),
-        m_layoutBox ? m_layoutBox->serializeResolvingVariables(variables) : String());
-}
-
-bool CSSBasicShapeInsetRectangle::hasVariableReference() const
-{
-    return m_top->hasVariableReference()
-        || m_right->hasVariableReference()
-        || m_bottom->hasVariableReference()
-        || m_left->hasVariableReference()
-        || (m_radiusX.get() && m_radiusX->hasVariableReference())
-        || (m_radiusY.get() && m_radiusY->hasVariableReference())
-        || (m_layoutBox && m_layoutBox->hasVariableReference());
+        && compareCSSValuePtr(m_topLeftRadius, other.m_topLeftRadius)
+        && compareCSSValuePtr(m_topRightRadius, other.m_topRightRadius)
+        && compareCSSValuePtr(m_bottomRightRadius, other.m_bottomRightRadius)
+        && compareCSSValuePtr(m_bottomLeftRadius, other.m_bottomLeftRadius);
+}
+
+void CSSBasicShapeInset::trace(Visitor* visitor)
+{
+    visitor->trace(m_top);
+    visitor->trace(m_right);
+    visitor->trace(m_bottom);
+    visitor->trace(m_left);
+    visitor->trace(m_topLeftRadius);
+    visitor->trace(m_topRightRadius);
+    visitor->trace(m_bottomRightRadius);
+    visitor->trace(m_bottomLeftRadius);
+    CSSBasicShape::trace(visitor);
 }
 
 } // namespace WebCore