Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Library General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 of the License, or (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Library General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Library General Public License
     15  * along with this library; see the file COPYING.LIB.  If not, write to
     16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  * Boston, MA 02110-1301, USA.
     18  */
     19 
     20 #include "config.h"
     21 #include "core/svg/SVGAnimatedType.h"
     22 
     23 #include "bindings/v8/ExceptionState.h"
     24 #include "core/svg/SVGParserUtilities.h"
     25 #include "core/svg/SVGPathByteStream.h"
     26 
     27 namespace WebCore {
     28 
     29 SVGAnimatedType::SVGAnimatedType(AnimatedPropertyType type)
     30     : m_type(type)
     31 {
     32 }
     33 
     34 SVGAnimatedType::~SVGAnimatedType()
     35 {
     36     switch (m_type) {
     37     case AnimatedAngle:
     38         delete m_data.angleAndEnumeration;
     39         break;
     40     case AnimatedBoolean:
     41         delete m_data.boolean;
     42         break;
     43     case AnimatedColor:
     44         delete m_data.color;
     45         break;
     46     case AnimatedEnumeration:
     47         delete m_data.enumeration;
     48         break;
     49     case AnimatedInteger:
     50         delete m_data.integer;
     51         break;
     52     case AnimatedIntegerOptionalInteger:
     53         delete m_data.integerOptionalInteger;
     54         break;
     55     case AnimatedLength:
     56         delete m_data.length;
     57         break;
     58     case AnimatedLengthList:
     59         delete m_data.lengthList;
     60         break;
     61     case AnimatedNumber:
     62         delete m_data.number;
     63         break;
     64     case AnimatedNumberList:
     65         delete m_data.numberList;
     66         break;
     67     case AnimatedNumberOptionalNumber:
     68         delete m_data.numberOptionalNumber;
     69         break;
     70     case AnimatedPath:
     71         delete m_data.path;
     72         break;
     73     case AnimatedPoints:
     74         delete m_data.pointList;
     75         break;
     76     case AnimatedPreserveAspectRatio:
     77         delete m_data.preserveAspectRatio;
     78         break;
     79     case AnimatedRect:
     80         delete m_data.rect;
     81         break;
     82     case AnimatedString:
     83         delete m_data.string;
     84         break;
     85     case AnimatedTransformList:
     86         delete m_data.transformList;
     87         break;
     88     case AnimatedUnknown:
     89         ASSERT_NOT_REACHED();
     90         break;
     91     }
     92 }
     93 
     94 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createAngleAndEnumeration(std::pair<SVGAngle, unsigned>* angleAndEnumeration)
     95 {
     96     ASSERT(angleAndEnumeration);
     97     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedAngle));
     98     animatedType->m_data.angleAndEnumeration = angleAndEnumeration;
     99     return animatedType.release();
    100 }
    101 
    102 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createBoolean(bool* boolean)
    103 {
    104     ASSERT(boolean);
    105     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedBoolean));
    106     animatedType->m_data.boolean = boolean;
    107     return animatedType.release();
    108 }
    109 
    110 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createColor(Color* color)
    111 {
    112     ASSERT(color);
    113     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedColor));
    114     animatedType->m_data.color = color;
    115     return animatedType.release();
    116 }
    117 
    118 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createEnumeration(unsigned* enumeration)
    119 {
    120     ASSERT(enumeration);
    121     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedEnumeration));
    122     animatedType->m_data.enumeration = enumeration;
    123     return animatedType.release();
    124 }
    125 
    126 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createInteger(int* integer)
    127 {
    128     ASSERT(integer);
    129     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedInteger));
    130     animatedType->m_data.integer = integer;
    131     return animatedType.release();
    132 }
    133 
    134 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createIntegerOptionalInteger(pair<int, int>* integerOptionalInteger)
    135 {
    136     ASSERT(integerOptionalInteger);
    137     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedIntegerOptionalInteger));
    138     animatedType->m_data.integerOptionalInteger = integerOptionalInteger;
    139     return animatedType.release();
    140 }
    141 
    142 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createLength(SVGLength* length)
    143 {
    144     ASSERT(length);
    145     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedLength));
    146     animatedType->m_data.length = length;
    147     return animatedType.release();
    148 }
    149 
    150 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createLengthList(SVGLengthList* lengthList)
    151 {
    152     ASSERT(lengthList);
    153     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedLengthList));
    154     animatedType->m_data.lengthList = lengthList;
    155     return animatedType.release();
    156 }
    157 
    158 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createNumber(float* number)
    159 {
    160     ASSERT(number);
    161     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedNumber));
    162     animatedType->m_data.number = number;
    163     return animatedType.release();
    164 }
    165 
    166 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createNumberList(SVGNumberList* numberList)
    167 {
    168     ASSERT(numberList);
    169     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedNumberList));
    170     animatedType->m_data.numberList = numberList;
    171     return animatedType.release();
    172 }
    173 
    174 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createNumberOptionalNumber(pair<float, float>* numberOptionalNumber)
    175 {
    176     ASSERT(numberOptionalNumber);
    177     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedNumberOptionalNumber));
    178     animatedType->m_data.numberOptionalNumber = numberOptionalNumber;
    179     return animatedType.release();
    180 }
    181 
    182 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createPath(PassOwnPtr<SVGPathByteStream> path)
    183 {
    184     ASSERT(path);
    185     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedPath));
    186     animatedType->m_data.path = path.leakPtr();
    187     return animatedType.release();
    188 }
    189 
    190 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createPointList(SVGPointList* pointList)
    191 {
    192     ASSERT(pointList);
    193     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedPoints));
    194     animatedType->m_data.pointList = pointList;
    195     return animatedType.release();
    196 }
    197 
    198 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createPreserveAspectRatio(SVGPreserveAspectRatio* preserveAspectRatio)
    199 {
    200     ASSERT(preserveAspectRatio);
    201     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedPreserveAspectRatio));
    202     animatedType->m_data.preserveAspectRatio = preserveAspectRatio;
    203     return animatedType.release();
    204 }
    205 
    206 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createRect(SVGRect* rect)
    207 {
    208     ASSERT(rect);
    209     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedRect));
    210     animatedType->m_data.rect = rect;
    211     return animatedType.release();
    212 }
    213 
    214 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createString(String* string)
    215 {
    216     ASSERT(string);
    217     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedString));
    218     animatedType->m_data.string = string;
    219     return animatedType.release();
    220 }
    221 
    222 PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createTransformList(SVGTransformList* transformList)
    223 {
    224     ASSERT(transformList);
    225     OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedTransformList));
    226     animatedType->m_data.transformList = transformList;
    227     return animatedType.release();
    228 }
    229 
    230 String SVGAnimatedType::valueAsString()
    231 {
    232     switch (m_type) {
    233     case AnimatedColor:
    234         ASSERT(m_data.color);
    235         return m_data.color->serialized();
    236     case AnimatedLength:
    237         ASSERT(m_data.length);
    238         return m_data.length->valueAsString();
    239     case AnimatedLengthList:
    240         ASSERT(m_data.lengthList);
    241         return m_data.lengthList->valueAsString();
    242     case AnimatedNumber:
    243         ASSERT(m_data.number);
    244         return String::number(*m_data.number);
    245     case AnimatedRect:
    246         ASSERT(m_data.rect);
    247         return String::number(m_data.rect->x()) + ' ' + String::number(m_data.rect->y()) + ' '
    248              + String::number(m_data.rect->width()) + ' ' + String::number(m_data.rect->height());
    249     case AnimatedString:
    250         ASSERT(m_data.string);
    251         return *m_data.string;
    252 
    253     // These types don't appear in the table in SVGElement::cssPropertyToTypeMap() and thus don't need valueAsString() support.
    254     case AnimatedAngle:
    255     case AnimatedBoolean:
    256     case AnimatedEnumeration:
    257     case AnimatedInteger:
    258     case AnimatedIntegerOptionalInteger:
    259     case AnimatedNumberList:
    260     case AnimatedNumberOptionalNumber:
    261     case AnimatedPath:
    262     case AnimatedPoints:
    263     case AnimatedPreserveAspectRatio:
    264     case AnimatedTransformList:
    265     case AnimatedUnknown:
    266         // Only SVG DOM animations use these property types - that means valueAsString() is never used for those.
    267         ASSERT_NOT_REACHED();
    268         break;
    269     }
    270     ASSERT_NOT_REACHED();
    271     return String();
    272 }
    273 
    274 bool SVGAnimatedType::setValueAsString(const QualifiedName& attrName, const String& value)
    275 {
    276     switch (m_type) {
    277     case AnimatedColor:
    278         ASSERT(m_data.color);
    279         *m_data.color = value.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(value);
    280         break;
    281     case AnimatedLength: {
    282         ASSERT(m_data.length);
    283         TrackExceptionState es;
    284         m_data.length->setValueAsString(value, SVGLength::lengthModeForAnimatedLengthAttribute(attrName), es);
    285         return !es.hadException();
    286     }
    287     case AnimatedLengthList:
    288         ASSERT(m_data.lengthList);
    289         m_data.lengthList->parse(value, SVGLength::lengthModeForAnimatedLengthAttribute(attrName));
    290         break;
    291     case AnimatedNumber:
    292         ASSERT(m_data.number);
    293         parseNumberFromString(value, *m_data.number);
    294         break;
    295     case AnimatedRect:
    296         ASSERT(m_data.rect);
    297         parseRect(value, *m_data.rect);
    298         break;
    299     case AnimatedString:
    300         ASSERT(m_data.string);
    301         *m_data.string = value;
    302         break;
    303 
    304     // These types don't appear in the table in SVGElement::cssPropertyToTypeMap() and thus don't need setValueAsString() support.
    305     case AnimatedAngle:
    306     case AnimatedBoolean:
    307     case AnimatedEnumeration:
    308     case AnimatedInteger:
    309     case AnimatedIntegerOptionalInteger:
    310     case AnimatedNumberList:
    311     case AnimatedNumberOptionalNumber:
    312     case AnimatedPath:
    313     case AnimatedPoints:
    314     case AnimatedPreserveAspectRatio:
    315     case AnimatedTransformList:
    316     case AnimatedUnknown:
    317         // Only SVG DOM animations use these property types - that means setValueAsString() is never used for those.
    318         ASSERT_NOT_REACHED();
    319         break;
    320     }
    321     return true;
    322 }
    323 
    324 bool SVGAnimatedType::supportsAnimVal(AnimatedPropertyType type)
    325 {
    326     // AnimatedColor is only used for CSS property animations.
    327     return type != AnimatedUnknown && type != AnimatedColor;
    328 }
    329 
    330 } // namespace WebCore
    331