summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp237
1 files changed, 153 insertions, 84 deletions
diff --git a/chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp b/chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp
index a49ea1495f1..e6399b99187 100644
--- a/chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp
@@ -33,58 +33,68 @@
#include "core/css/CSSBasicShapes.h"
#include "core/css/CSSPrimitiveValueMappings.h"
#include "core/css/CSSValuePool.h"
+#include "core/css/Pair.h"
#include "core/css/resolver/StyleResolverState.h"
#include "core/rendering/style/BasicShapes.h"
#include "core/rendering/style/RenderStyle.h"
namespace WebCore {
-PassRefPtr<CSSValue> valueForBasicShape(const RenderStyle& style, const BasicShape* basicShape)
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForCenterCoordinate(CSSValuePool& pool, const RenderStyle& style, const BasicShapeCenterCoordinate& center, EBoxOrient orientation)
+{
+ if (center.direction() == BasicShapeCenterCoordinate::TopLeft)
+ return pool.createValue(center.length(), style);
+
+ CSSValueID keyword = orientation == HORIZONTAL ? CSSValueRight : CSSValueBottom;
+
+ return pool.createValue(Pair::create(pool.createIdentifierValue(keyword), pool.createValue(center.length(), style), Pair::DropIdenticalValues));
+}
+
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> basicShapeRadiusToCSSValue(CSSValuePool& pool, const RenderStyle& style, const BasicShapeRadius& radius)
+{
+ switch (radius.type()) {
+ case BasicShapeRadius::Value:
+ return pool.createValue(radius.value(), style);
+ case BasicShapeRadius::ClosestSide:
+ return pool.createIdentifierValue(CSSValueClosestSide);
+ case BasicShapeRadius::FarthestSide:
+ return pool.createIdentifierValue(CSSValueFarthestSide);
+ }
+
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> valueForBasicShape(const RenderStyle& style, const BasicShape* basicShape)
{
CSSValuePool& pool = cssValuePool();
- RefPtr<CSSBasicShape> basicShapeValue;
+ RefPtrWillBeRawPtr<CSSBasicShape> basicShapeValue = nullptr;
switch (basicShape->type()) {
- case BasicShape::BasicShapeRectangleType: {
- const BasicShapeRectangle* rectangle = static_cast<const BasicShapeRectangle*>(basicShape);
- RefPtr<CSSBasicShapeRectangle> rectangleValue = CSSBasicShapeRectangle::create();
-
- rectangleValue->setX(pool.createValue(rectangle->x(), style));
- rectangleValue->setY(pool.createValue(rectangle->y(), style));
- rectangleValue->setWidth(pool.createValue(rectangle->width(), style));
- rectangleValue->setHeight(pool.createValue(rectangle->height(), style));
- rectangleValue->setRadiusX(pool.createValue(rectangle->cornerRadiusX(), style));
- rectangleValue->setRadiusY(pool.createValue(rectangle->cornerRadiusY(), style));
-
- basicShapeValue = rectangleValue.release();
- break;
- }
case BasicShape::BasicShapeCircleType: {
const BasicShapeCircle* circle = static_cast<const BasicShapeCircle*>(basicShape);
- RefPtr<CSSBasicShapeCircle> circleValue = CSSBasicShapeCircle::create();
-
- circleValue->setCenterX(pool.createValue(circle->centerX(), style));
- circleValue->setCenterY(pool.createValue(circle->centerY(), style));
- circleValue->setRadius(pool.createValue(circle->radius(), style));
+ RefPtrWillBeRawPtr<CSSBasicShapeCircle> circleValue = CSSBasicShapeCircle::create();
+ circleValue->setCenterX(valueForCenterCoordinate(pool, style, circle->centerX(), HORIZONTAL));
+ circleValue->setCenterY(valueForCenterCoordinate(pool, style, circle->centerY(), VERTICAL));
+ circleValue->setRadius(basicShapeRadiusToCSSValue(pool, style, circle->radius()));
basicShapeValue = circleValue.release();
break;
}
case BasicShape::BasicShapeEllipseType: {
const BasicShapeEllipse* ellipse = static_cast<const BasicShapeEllipse*>(basicShape);
- RefPtr<CSSBasicShapeEllipse> ellipseValue = CSSBasicShapeEllipse::create();
-
- ellipseValue->setCenterX(pool.createValue(ellipse->centerX(), style));
- ellipseValue->setCenterY(pool.createValue(ellipse->centerY(), style));
- ellipseValue->setRadiusX(pool.createValue(ellipse->radiusX(), style));
- ellipseValue->setRadiusY(pool.createValue(ellipse->radiusY(), style));
+ RefPtrWillBeRawPtr<CSSBasicShapeEllipse> ellipseValue = CSSBasicShapeEllipse::create();
+ ellipseValue->setCenterX(valueForCenterCoordinate(pool, style, ellipse->centerX(), HORIZONTAL));
+ ellipseValue->setCenterY(valueForCenterCoordinate(pool, style, ellipse->centerY(), VERTICAL));
+ ellipseValue->setRadiusX(basicShapeRadiusToCSSValue(pool, style, ellipse->radiusX()));
+ ellipseValue->setRadiusY(basicShapeRadiusToCSSValue(pool, style, ellipse->radiusY()));
basicShapeValue = ellipseValue.release();
break;
}
case BasicShape::BasicShapePolygonType: {
const BasicShapePolygon* polygon = static_cast<const BasicShapePolygon*>(basicShape);
- RefPtr<CSSBasicShapePolygon> polygonValue = CSSBasicShapePolygon::create();
+ RefPtrWillBeRawPtr<CSSBasicShapePolygon> polygonValue = CSSBasicShapePolygon::create();
polygonValue->setWindRule(polygon->windRule());
const Vector<Length>& values = polygon->values();
@@ -94,65 +104,117 @@ PassRefPtr<CSSValue> valueForBasicShape(const RenderStyle& style, const BasicSha
basicShapeValue = polygonValue.release();
break;
}
- case BasicShape::BasicShapeInsetRectangleType: {
- const BasicShapeInsetRectangle* rectangle = static_cast<const BasicShapeInsetRectangle*>(basicShape);
- RefPtr<CSSBasicShapeInsetRectangle> rectangleValue = CSSBasicShapeInsetRectangle::create();
-
- rectangleValue->setTop(cssValuePool().createValue(rectangle->top()));
- rectangleValue->setRight(cssValuePool().createValue(rectangle->right()));
- rectangleValue->setBottom(cssValuePool().createValue(rectangle->bottom()));
- rectangleValue->setLeft(cssValuePool().createValue(rectangle->left()));
- rectangleValue->setRadiusX(cssValuePool().createValue(rectangle->cornerRadiusX()));
- rectangleValue->setRadiusY(cssValuePool().createValue(rectangle->cornerRadiusY()));
-
- basicShapeValue = rectangleValue.release();
+ case BasicShape::BasicShapeInsetType: {
+ const BasicShapeInset* inset = static_cast<const BasicShapeInset*>(basicShape);
+ RefPtrWillBeRawPtr<CSSBasicShapeInset> insetValue = CSSBasicShapeInset::create();
+
+ insetValue->setTop(pool.createValue(inset->top(), style));
+ insetValue->setRight(pool.createValue(inset->right(), style));
+ insetValue->setBottom(pool.createValue(inset->bottom(), style));
+ insetValue->setLeft(pool.createValue(inset->left(), style));
+
+ insetValue->setTopLeftRadius(CSSPrimitiveValue::create(inset->topLeftRadius(), style));
+ insetValue->setTopRightRadius(CSSPrimitiveValue::create(inset->topRightRadius(), style));
+ insetValue->setBottomRightRadius(CSSPrimitiveValue::create(inset->bottomRightRadius(), style));
+ insetValue->setBottomLeftRadius(CSSPrimitiveValue::create(inset->bottomLeftRadius(), style));
+
+ basicShapeValue = insetValue.release();
break;
}
default:
break;
}
+
return pool.createValue(basicShapeValue.release());
}
static Length convertToLength(const StyleResolverState& state, CSSPrimitiveValue* value)
{
+ if (!value)
+ return Length(0, Fixed);
return value->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
}
+static LengthSize convertToLengthSize(const StyleResolverState& state, CSSPrimitiveValue* value)
+{
+ if (!value)
+ return LengthSize(Length(0, Fixed), Length(0, Fixed));
+
+ Pair* pair = value->getPairValue();
+ return LengthSize(convertToLength(state, pair->first()), convertToLength(state, pair->second()));
+}
+
+static BasicShapeCenterCoordinate convertToCenterCoordinate(const StyleResolverState& state, CSSPrimitiveValue* value)
+{
+ BasicShapeCenterCoordinate::Direction direction;
+ Length offset = Length(0, Fixed);
+
+ CSSValueID keyword = CSSValueTop;
+ if (!value) {
+ keyword = CSSValueCenter;
+ } else if (value->isValueID()) {
+ keyword = value->getValueID();
+ } else if (Pair* pair = value->getPairValue()) {
+ keyword = pair->first()->getValueID();
+ offset = convertToLength(state, pair->second());
+ } else {
+ offset = convertToLength(state, value);
+ }
+
+ switch (keyword) {
+ case CSSValueTop:
+ case CSSValueLeft:
+ direction = BasicShapeCenterCoordinate::TopLeft;
+ break;
+ case CSSValueRight:
+ case CSSValueBottom:
+ direction = BasicShapeCenterCoordinate::BottomRight;
+ break;
+ case CSSValueCenter:
+ direction = BasicShapeCenterCoordinate::TopLeft;
+ offset = Length(50, Percent);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ direction = BasicShapeCenterCoordinate::TopLeft;
+ break;
+ }
+
+ return BasicShapeCenterCoordinate(direction, offset);
+}
+
+static BasicShapeRadius cssValueToBasicShapeRadius(const StyleResolverState& state, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius)
+{
+ if (!radius)
+ return BasicShapeRadius(BasicShapeRadius::ClosestSide);
+
+ if (radius->isValueID()) {
+ switch (radius->getValueID()) {
+ case CSSValueClosestSide:
+ return BasicShapeRadius(BasicShapeRadius::ClosestSide);
+ case CSSValueFarthestSide:
+ return BasicShapeRadius(BasicShapeRadius::FarthestSide);
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+
+ return BasicShapeRadius(convertToLength(state, radius.get()));
+}
+
PassRefPtr<BasicShape> basicShapeForValue(const StyleResolverState& state, const CSSBasicShape* basicShapeValue)
{
RefPtr<BasicShape> basicShape;
switch (basicShapeValue->type()) {
- case CSSBasicShape::CSSBasicShapeRectangleType: {
- const CSSBasicShapeRectangle* rectValue = static_cast<const CSSBasicShapeRectangle *>(basicShapeValue);
- RefPtr<BasicShapeRectangle> rect = BasicShapeRectangle::create();
-
- rect->setX(convertToLength(state, rectValue->x()));
- rect->setY(convertToLength(state, rectValue->y()));
- rect->setWidth(convertToLength(state, rectValue->width()));
- rect->setHeight(convertToLength(state, rectValue->height()));
- if (rectValue->radiusX()) {
- Length radiusX = convertToLength(state, rectValue->radiusX());
- rect->setCornerRadiusX(radiusX);
- if (rectValue->radiusY())
- rect->setCornerRadiusY(convertToLength(state, rectValue->radiusY()));
- else
- rect->setCornerRadiusY(radiusX);
- } else {
- rect->setCornerRadiusX(Length(0, Fixed));
- rect->setCornerRadiusY(Length(0, Fixed));
- }
- basicShape = rect.release();
- break;
- }
case CSSBasicShape::CSSBasicShapeCircleType: {
const CSSBasicShapeCircle* circleValue = static_cast<const CSSBasicShapeCircle *>(basicShapeValue);
RefPtr<BasicShapeCircle> circle = BasicShapeCircle::create();
- circle->setCenterX(convertToLength(state, circleValue->centerX()));
- circle->setCenterY(convertToLength(state, circleValue->centerY()));
- circle->setRadius(convertToLength(state, circleValue->radius()));
+ circle->setCenterX(convertToCenterCoordinate(state, circleValue->centerX()));
+ circle->setCenterY(convertToCenterCoordinate(state, circleValue->centerY()));
+ circle->setRadius(cssValueToBasicShapeRadius(state, circleValue->radius()));
basicShape = circle.release();
break;
@@ -161,10 +223,10 @@ PassRefPtr<BasicShape> basicShapeForValue(const StyleResolverState& state, const
const CSSBasicShapeEllipse* ellipseValue = static_cast<const CSSBasicShapeEllipse *>(basicShapeValue);
RefPtr<BasicShapeEllipse> ellipse = BasicShapeEllipse::create();
- ellipse->setCenterX(convertToLength(state, ellipseValue->centerX()));
- ellipse->setCenterY(convertToLength(state, ellipseValue->centerY()));
- ellipse->setRadiusX(convertToLength(state, ellipseValue->radiusX()));
- ellipse->setRadiusY(convertToLength(state, ellipseValue->radiusY()));
+ ellipse->setCenterX(convertToCenterCoordinate(state, ellipseValue->centerX()));
+ ellipse->setCenterY(convertToCenterCoordinate(state, ellipseValue->centerY()));
+ ellipse->setRadiusX(cssValueToBasicShapeRadius(state, ellipseValue->radiusX()));
+ ellipse->setRadiusY(cssValueToBasicShapeRadius(state, ellipseValue->radiusY()));
basicShape = ellipse.release();
break;
@@ -174,38 +236,45 @@ PassRefPtr<BasicShape> basicShapeForValue(const StyleResolverState& state, const
RefPtr<BasicShapePolygon> polygon = BasicShapePolygon::create();
polygon->setWindRule(polygonValue->windRule());
- const Vector<RefPtr<CSSPrimitiveValue> >& values = polygonValue->values();
+ const WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue> >& values = polygonValue->values();
for (unsigned i = 0; i < values.size(); i += 2)
polygon->appendPoint(convertToLength(state, values.at(i).get()), convertToLength(state, values.at(i + 1).get()));
basicShape = polygon.release();
break;
}
- case CSSBasicShape::CSSBasicShapeInsetRectangleType: {
- const CSSBasicShapeInsetRectangle* rectValue = static_cast<const CSSBasicShapeInsetRectangle *>(basicShapeValue);
- RefPtr<BasicShapeInsetRectangle> rect = BasicShapeInsetRectangle::create();
+ case CSSBasicShape::CSSBasicShapeInsetType: {
+ const CSSBasicShapeInset* rectValue = static_cast<const CSSBasicShapeInset* >(basicShapeValue);
+ RefPtr<BasicShapeInset> rect = BasicShapeInset::create();
rect->setTop(convertToLength(state, rectValue->top()));
rect->setRight(convertToLength(state, rectValue->right()));
rect->setBottom(convertToLength(state, rectValue->bottom()));
rect->setLeft(convertToLength(state, rectValue->left()));
- if (rectValue->radiusX()) {
- Length radiusX = convertToLength(state, rectValue->radiusX());
- rect->setCornerRadiusX(radiusX);
- if (rectValue->radiusY())
- rect->setCornerRadiusY(convertToLength(state, rectValue->radiusY()));
- else
- rect->setCornerRadiusY(radiusX);
- } else {
- rect->setCornerRadiusX(Length(0, Fixed));
- rect->setCornerRadiusY(Length(0, Fixed));
- }
+
+ rect->setTopLeftRadius(convertToLengthSize(state, rectValue->topLeftRadius()));
+ rect->setTopRightRadius(convertToLengthSize(state, rectValue->topRightRadius()));
+ rect->setBottomRightRadius(convertToLengthSize(state, rectValue->bottomRightRadius()));
+ rect->setBottomLeftRadius(convertToLengthSize(state, rectValue->bottomLeftRadius()));
+
basicShape = rect.release();
break;
}
default:
break;
}
+
return basicShape.release();
}
+
+FloatPoint floatPointForCenterCoordinate(const BasicShapeCenterCoordinate& centerX, const BasicShapeCenterCoordinate& centerY, FloatSize boxSize)
+{
+ FloatPoint p;
+ float offset = floatValueForLength(centerX.length(), boxSize.width());
+ p.setX(centerX.direction() == BasicShapeCenterCoordinate::TopLeft ? offset : boxSize.width() - offset);
+ offset = floatValueForLength(centerY.length(), boxSize.height());
+ p.setY(centerY.direction() == BasicShapeCenterCoordinate::TopLeft ? offset : boxSize.height() - offset);
+ return p;
+}
+
}