Home | History | Annotate | Download | only in css
      1 /*
      2  * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1. Redistributions of source code must retain the above
      9  *    copyright notice, this list of conditions and the following
     10  *    disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above
     12  *    copyright notice, this list of conditions and the following
     13  *    disclaimer in the documentation and/or other materials
     14  *    provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AS IS AND ANY
     17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
     20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
     21  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
     25  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
     26  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  * SUCH DAMAGE.
     28  */
     29 
     30 #include "config.h"
     31 #include "core/css/BasicShapeFunctions.h"
     32 
     33 #include "core/css/CSSBasicShapes.h"
     34 #include "core/css/CSSPrimitiveValueMappings.h"
     35 #include "core/css/CSSValuePool.h"
     36 #include "core/css/resolver/StyleResolverState.h"
     37 #include "core/rendering/style/BasicShapes.h"
     38 #include "core/rendering/style/RenderStyle.h"
     39 
     40 namespace WebCore {
     41 
     42 PassRefPtr<CSSValue> valueForBasicShape(const RenderStyle& style, const BasicShape* basicShape)
     43 {
     44     CSSValuePool& pool = cssValuePool();
     45 
     46     RefPtr<CSSBasicShape> basicShapeValue;
     47     switch (basicShape->type()) {
     48     case BasicShape::BasicShapeRectangleType: {
     49         const BasicShapeRectangle* rectangle = static_cast<const BasicShapeRectangle*>(basicShape);
     50         RefPtr<CSSBasicShapeRectangle> rectangleValue = CSSBasicShapeRectangle::create();
     51 
     52         rectangleValue->setX(pool.createValue(rectangle->x(), style));
     53         rectangleValue->setY(pool.createValue(rectangle->y(), style));
     54         rectangleValue->setWidth(pool.createValue(rectangle->width(), style));
     55         rectangleValue->setHeight(pool.createValue(rectangle->height(), style));
     56         rectangleValue->setRadiusX(pool.createValue(rectangle->cornerRadiusX(), style));
     57         rectangleValue->setRadiusY(pool.createValue(rectangle->cornerRadiusY(), style));
     58 
     59         basicShapeValue = rectangleValue.release();
     60         break;
     61     }
     62     case BasicShape::BasicShapeCircleType: {
     63         const BasicShapeCircle* circle = static_cast<const BasicShapeCircle*>(basicShape);
     64         RefPtr<CSSBasicShapeCircle> circleValue = CSSBasicShapeCircle::create();
     65 
     66         circleValue->setCenterX(pool.createValue(circle->centerX(), style));
     67         circleValue->setCenterY(pool.createValue(circle->centerY(), style));
     68         circleValue->setRadius(pool.createValue(circle->radius(), style));
     69 
     70         basicShapeValue = circleValue.release();
     71         break;
     72     }
     73     case BasicShape::BasicShapeEllipseType: {
     74         const BasicShapeEllipse* ellipse = static_cast<const BasicShapeEllipse*>(basicShape);
     75         RefPtr<CSSBasicShapeEllipse> ellipseValue = CSSBasicShapeEllipse::create();
     76 
     77         ellipseValue->setCenterX(pool.createValue(ellipse->centerX(), style));
     78         ellipseValue->setCenterY(pool.createValue(ellipse->centerY(), style));
     79         ellipseValue->setRadiusX(pool.createValue(ellipse->radiusX(), style));
     80         ellipseValue->setRadiusY(pool.createValue(ellipse->radiusY(), style));
     81 
     82         basicShapeValue = ellipseValue.release();
     83         break;
     84     }
     85     case BasicShape::BasicShapePolygonType: {
     86         const BasicShapePolygon* polygon = static_cast<const BasicShapePolygon*>(basicShape);
     87         RefPtr<CSSBasicShapePolygon> polygonValue = CSSBasicShapePolygon::create();
     88 
     89         polygonValue->setWindRule(polygon->windRule());
     90         const Vector<Length>& values = polygon->values();
     91         for (unsigned i = 0; i < values.size(); i += 2)
     92             polygonValue->appendPoint(pool.createValue(values.at(i), style), pool.createValue(values.at(i + 1), style));
     93 
     94         basicShapeValue = polygonValue.release();
     95         break;
     96     }
     97     case BasicShape::BasicShapeInsetRectangleType: {
     98         const BasicShapeInsetRectangle* rectangle = static_cast<const BasicShapeInsetRectangle*>(basicShape);
     99         RefPtr<CSSBasicShapeInsetRectangle> rectangleValue = CSSBasicShapeInsetRectangle::create();
    100 
    101         rectangleValue->setTop(cssValuePool().createValue(rectangle->top()));
    102         rectangleValue->setRight(cssValuePool().createValue(rectangle->right()));
    103         rectangleValue->setBottom(cssValuePool().createValue(rectangle->bottom()));
    104         rectangleValue->setLeft(cssValuePool().createValue(rectangle->left()));
    105         rectangleValue->setRadiusX(cssValuePool().createValue(rectangle->cornerRadiusX()));
    106         rectangleValue->setRadiusY(cssValuePool().createValue(rectangle->cornerRadiusY()));
    107 
    108         basicShapeValue = rectangleValue.release();
    109         break;
    110     }
    111     default:
    112         break;
    113     }
    114     return pool.createValue(basicShapeValue.release());
    115 }
    116 
    117 static Length convertToLength(const StyleResolverState& state, CSSPrimitiveValue* value)
    118 {
    119     return value->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
    120 }
    121 
    122 PassRefPtr<BasicShape> basicShapeForValue(const StyleResolverState& state, const CSSBasicShape* basicShapeValue)
    123 {
    124     RefPtr<BasicShape> basicShape;
    125 
    126     switch (basicShapeValue->type()) {
    127     case CSSBasicShape::CSSBasicShapeRectangleType: {
    128         const CSSBasicShapeRectangle* rectValue = static_cast<const CSSBasicShapeRectangle *>(basicShapeValue);
    129         RefPtr<BasicShapeRectangle> rect = BasicShapeRectangle::create();
    130 
    131         rect->setX(convertToLength(state, rectValue->x()));
    132         rect->setY(convertToLength(state, rectValue->y()));
    133         rect->setWidth(convertToLength(state, rectValue->width()));
    134         rect->setHeight(convertToLength(state, rectValue->height()));
    135         if (rectValue->radiusX()) {
    136             Length radiusX = convertToLength(state, rectValue->radiusX());
    137             rect->setCornerRadiusX(radiusX);
    138             if (rectValue->radiusY())
    139                 rect->setCornerRadiusY(convertToLength(state, rectValue->radiusY()));
    140             else
    141                 rect->setCornerRadiusY(radiusX);
    142         } else {
    143             rect->setCornerRadiusX(Length(0, Fixed));
    144             rect->setCornerRadiusY(Length(0, Fixed));
    145         }
    146         basicShape = rect.release();
    147         break;
    148     }
    149     case CSSBasicShape::CSSBasicShapeCircleType: {
    150         const CSSBasicShapeCircle* circleValue = static_cast<const CSSBasicShapeCircle *>(basicShapeValue);
    151         RefPtr<BasicShapeCircle> circle = BasicShapeCircle::create();
    152 
    153         circle->setCenterX(convertToLength(state, circleValue->centerX()));
    154         circle->setCenterY(convertToLength(state, circleValue->centerY()));
    155         circle->setRadius(convertToLength(state, circleValue->radius()));
    156 
    157         basicShape = circle.release();
    158         break;
    159     }
    160     case CSSBasicShape::CSSBasicShapeEllipseType: {
    161         const CSSBasicShapeEllipse* ellipseValue = static_cast<const CSSBasicShapeEllipse *>(basicShapeValue);
    162         RefPtr<BasicShapeEllipse> ellipse = BasicShapeEllipse::create();
    163 
    164         ellipse->setCenterX(convertToLength(state, ellipseValue->centerX()));
    165         ellipse->setCenterY(convertToLength(state, ellipseValue->centerY()));
    166         ellipse->setRadiusX(convertToLength(state, ellipseValue->radiusX()));
    167         ellipse->setRadiusY(convertToLength(state, ellipseValue->radiusY()));
    168 
    169         basicShape = ellipse.release();
    170         break;
    171     }
    172     case CSSBasicShape::CSSBasicShapePolygonType: {
    173         const CSSBasicShapePolygon* polygonValue = static_cast<const CSSBasicShapePolygon *>(basicShapeValue);
    174         RefPtr<BasicShapePolygon> polygon = BasicShapePolygon::create();
    175 
    176         polygon->setWindRule(polygonValue->windRule());
    177         const Vector<RefPtr<CSSPrimitiveValue> >& values = polygonValue->values();
    178         for (unsigned i = 0; i < values.size(); i += 2)
    179             polygon->appendPoint(convertToLength(state, values.at(i).get()), convertToLength(state, values.at(i + 1).get()));
    180 
    181         basicShape = polygon.release();
    182         break;
    183     }
    184     case CSSBasicShape::CSSBasicShapeInsetRectangleType: {
    185         const CSSBasicShapeInsetRectangle* rectValue = static_cast<const CSSBasicShapeInsetRectangle *>(basicShapeValue);
    186         RefPtr<BasicShapeInsetRectangle> rect = BasicShapeInsetRectangle::create();
    187 
    188         rect->setTop(convertToLength(state, rectValue->top()));
    189         rect->setRight(convertToLength(state, rectValue->right()));
    190         rect->setBottom(convertToLength(state, rectValue->bottom()));
    191         rect->setLeft(convertToLength(state, rectValue->left()));
    192         if (rectValue->radiusX()) {
    193             Length radiusX = convertToLength(state, rectValue->radiusX());
    194             rect->setCornerRadiusX(radiusX);
    195             if (rectValue->radiusY())
    196                 rect->setCornerRadiusY(convertToLength(state, rectValue->radiusY()));
    197             else
    198                 rect->setCornerRadiusY(radiusX);
    199         } else {
    200             rect->setCornerRadiusX(Length(0, Fixed));
    201             rect->setCornerRadiusY(Length(0, Fixed));
    202         }
    203         basicShape = rect.release();
    204         break;
    205     }
    206     default:
    207         break;
    208     }
    209     return basicShape.release();
    210 }
    211 }
    212