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 
     39 namespace WebCore {
     40 
     41 PassRefPtr<CSSValue> valueForBasicShape(const BasicShape* basicShape)
     42 {
     43     RefPtr<CSSBasicShape> basicShapeValue;
     44     switch (basicShape->type()) {
     45     case BasicShape::BasicShapeRectangleType: {
     46         const BasicShapeRectangle* rectangle = static_cast<const BasicShapeRectangle*>(basicShape);
     47         RefPtr<CSSBasicShapeRectangle> rectangleValue = CSSBasicShapeRectangle::create();
     48 
     49         rectangleValue->setX(cssValuePool().createValue(rectangle->x()));
     50         rectangleValue->setY(cssValuePool().createValue(rectangle->y()));
     51         rectangleValue->setWidth(cssValuePool().createValue(rectangle->width()));
     52         rectangleValue->setHeight(cssValuePool().createValue(rectangle->height()));
     53         rectangleValue->setRadiusX(cssValuePool().createValue(rectangle->cornerRadiusX()));
     54         rectangleValue->setRadiusY(cssValuePool().createValue(rectangle->cornerRadiusY()));
     55 
     56         basicShapeValue = rectangleValue.release();
     57         break;
     58     }
     59     case BasicShape::BasicShapeCircleType: {
     60         const BasicShapeCircle* circle = static_cast<const BasicShapeCircle*>(basicShape);
     61         RefPtr<CSSBasicShapeCircle> circleValue = CSSBasicShapeCircle::create();
     62 
     63         circleValue->setCenterX(cssValuePool().createValue(circle->centerX()));
     64         circleValue->setCenterY(cssValuePool().createValue(circle->centerY()));
     65         circleValue->setRadius(cssValuePool().createValue(circle->radius()));
     66 
     67         basicShapeValue = circleValue.release();
     68         break;
     69     }
     70     case BasicShape::BasicShapeEllipseType: {
     71         const BasicShapeEllipse* ellipse = static_cast<const BasicShapeEllipse*>(basicShape);
     72         RefPtr<CSSBasicShapeEllipse> ellipseValue = CSSBasicShapeEllipse::create();
     73 
     74         ellipseValue->setCenterX(cssValuePool().createValue(ellipse->centerX()));
     75         ellipseValue->setCenterY(cssValuePool().createValue(ellipse->centerY()));
     76         ellipseValue->setRadiusX(cssValuePool().createValue(ellipse->radiusX()));
     77         ellipseValue->setRadiusY(cssValuePool().createValue(ellipse->radiusY()));
     78 
     79         basicShapeValue = ellipseValue.release();
     80         break;
     81     }
     82     case BasicShape::BasicShapePolygonType: {
     83         const BasicShapePolygon* polygon = static_cast<const BasicShapePolygon*>(basicShape);
     84         RefPtr<CSSBasicShapePolygon> polygonValue = CSSBasicShapePolygon::create();
     85 
     86         polygonValue->setWindRule(polygon->windRule());
     87         const Vector<Length>& values = polygon->values();
     88         for (unsigned i = 0; i < values.size(); i += 2)
     89             polygonValue->appendPoint(cssValuePool().createValue(values.at(i)), cssValuePool().createValue(values.at(i + 1)));
     90 
     91         basicShapeValue = polygonValue.release();
     92         break;
     93     }
     94     case BasicShape::BasicShapeInsetRectangleType: {
     95         const BasicShapeInsetRectangle* rectangle = static_cast<const BasicShapeInsetRectangle*>(basicShape);
     96         RefPtr<CSSBasicShapeInsetRectangle> rectangleValue = CSSBasicShapeInsetRectangle::create();
     97 
     98         rectangleValue->setTop(cssValuePool().createValue(rectangle->top()));
     99         rectangleValue->setRight(cssValuePool().createValue(rectangle->right()));
    100         rectangleValue->setBottom(cssValuePool().createValue(rectangle->bottom()));
    101         rectangleValue->setLeft(cssValuePool().createValue(rectangle->left()));
    102         rectangleValue->setRadiusX(cssValuePool().createValue(rectangle->cornerRadiusX()));
    103         rectangleValue->setRadiusY(cssValuePool().createValue(rectangle->cornerRadiusY()));
    104 
    105         basicShapeValue = rectangleValue.release();
    106         break;
    107     }
    108     default:
    109         break;
    110     }
    111     return cssValuePool().createValue<PassRefPtr<CSSBasicShape> >(basicShapeValue.release());
    112 }
    113 
    114 static Length convertToLength(const StyleResolverState& state, CSSPrimitiveValue* value)
    115 {
    116     return value->convertToLength<FixedIntegerConversion | FixedFloatConversion | PercentConversion>(state.style(), state.rootElementStyle(), state.style()->effectiveZoom());
    117 }
    118 
    119 PassRefPtr<BasicShape> basicShapeForValue(const StyleResolverState& state, const CSSBasicShape* basicShapeValue)
    120 {
    121     RefPtr<BasicShape> basicShape;
    122 
    123     switch (basicShapeValue->type()) {
    124     case CSSBasicShape::CSSBasicShapeRectangleType: {
    125         const CSSBasicShapeRectangle* rectValue = static_cast<const CSSBasicShapeRectangle *>(basicShapeValue);
    126         RefPtr<BasicShapeRectangle> rect = BasicShapeRectangle::create();
    127 
    128         rect->setX(convertToLength(state, rectValue->x()));
    129         rect->setY(convertToLength(state, rectValue->y()));
    130         rect->setWidth(convertToLength(state, rectValue->width()));
    131         rect->setHeight(convertToLength(state, rectValue->height()));
    132         if (rectValue->radiusX()) {
    133             Length radiusX = convertToLength(state, rectValue->radiusX());
    134             rect->setCornerRadiusX(radiusX);
    135             if (rectValue->radiusY())
    136                 rect->setCornerRadiusY(convertToLength(state, rectValue->radiusY()));
    137             else
    138                 rect->setCornerRadiusY(radiusX);
    139         } else {
    140             rect->setCornerRadiusX(Length(0, Fixed));
    141             rect->setCornerRadiusY(Length(0, Fixed));
    142         }
    143         basicShape = rect.release();
    144         break;
    145     }
    146     case CSSBasicShape::CSSBasicShapeCircleType: {
    147         const CSSBasicShapeCircle* circleValue = static_cast<const CSSBasicShapeCircle *>(basicShapeValue);
    148         RefPtr<BasicShapeCircle> circle = BasicShapeCircle::create();
    149 
    150         circle->setCenterX(convertToLength(state, circleValue->centerX()));
    151         circle->setCenterY(convertToLength(state, circleValue->centerY()));
    152         circle->setRadius(convertToLength(state, circleValue->radius()));
    153 
    154         basicShape = circle.release();
    155         break;
    156     }
    157     case CSSBasicShape::CSSBasicShapeEllipseType: {
    158         const CSSBasicShapeEllipse* ellipseValue = static_cast<const CSSBasicShapeEllipse *>(basicShapeValue);
    159         RefPtr<BasicShapeEllipse> ellipse = BasicShapeEllipse::create();
    160 
    161         ellipse->setCenterX(convertToLength(state, ellipseValue->centerX()));
    162         ellipse->setCenterY(convertToLength(state, ellipseValue->centerY()));
    163         ellipse->setRadiusX(convertToLength(state, ellipseValue->radiusX()));
    164         ellipse->setRadiusY(convertToLength(state, ellipseValue->radiusY()));
    165 
    166         basicShape = ellipse.release();
    167         break;
    168     }
    169     case CSSBasicShape::CSSBasicShapePolygonType: {
    170         const CSSBasicShapePolygon* polygonValue = static_cast<const CSSBasicShapePolygon *>(basicShapeValue);
    171         RefPtr<BasicShapePolygon> polygon = BasicShapePolygon::create();
    172 
    173         polygon->setWindRule(polygonValue->windRule());
    174         const Vector<RefPtr<CSSPrimitiveValue> >& values = polygonValue->values();
    175         for (unsigned i = 0; i < values.size(); i += 2)
    176             polygon->appendPoint(convertToLength(state, values.at(i).get()), convertToLength(state, values.at(i + 1).get()));
    177 
    178         basicShape = polygon.release();
    179         break;
    180     }
    181     case CSSBasicShape::CSSBasicShapeInsetRectangleType: {
    182         const CSSBasicShapeInsetRectangle* rectValue = static_cast<const CSSBasicShapeInsetRectangle *>(basicShapeValue);
    183         RefPtr<BasicShapeInsetRectangle> rect = BasicShapeInsetRectangle::create();
    184 
    185         rect->setTop(convertToLength(state, rectValue->top()));
    186         rect->setRight(convertToLength(state, rectValue->right()));
    187         rect->setBottom(convertToLength(state, rectValue->bottom()));
    188         rect->setLeft(convertToLength(state, rectValue->left()));
    189         if (rectValue->radiusX()) {
    190             Length radiusX = convertToLength(state, rectValue->radiusX());
    191             rect->setCornerRadiusX(radiusX);
    192             if (rectValue->radiusY())
    193                 rect->setCornerRadiusY(convertToLength(state, rectValue->radiusY()));
    194             else
    195                 rect->setCornerRadiusY(radiusX);
    196         } else {
    197             rect->setCornerRadiusX(Length(0, Fixed));
    198             rect->setCornerRadiusY(Length(0, Fixed));
    199         }
    200         basicShape = rect.release();
    201         break;
    202     }
    203     default:
    204         break;
    205     }
    206     return basicShape.release();
    207 }
    208 }
    209