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 
     22 #include "core/svg/SVGAnimatedColor.h"
     23 
     24 #include "core/rendering/RenderObject.h"
     25 #include "core/svg/ColorDistance.h"
     26 #include "core/svg/SVGAnimateElement.h"
     27 #include "core/svg/SVGColor.h"
     28 
     29 namespace WebCore {
     30 
     31 SVGAnimatedColorAnimator::SVGAnimatedColorAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
     32     : SVGAnimatedTypeAnimator(AnimatedColor, animationElement, contextElement)
     33 {
     34 }
     35 
     36 PassOwnPtr<SVGAnimatedType> SVGAnimatedColorAnimator::constructFromString(const String& string)
     37 {
     38     OwnPtr<SVGAnimatedType> animtedType = SVGAnimatedType::createColor(new Color);
     39     animtedType->color() = string.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(string);
     40     return animtedType.release();
     41 }
     42 
     43 void SVGAnimatedColorAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
     44 {
     45     ASSERT(from->type() == AnimatedColor);
     46     ASSERT(from->type() == to->type());
     47     to->color() = ColorDistance::addColors(from->color(), to->color());
     48 }
     49 
     50 static inline void adjustForCurrentColor(SVGElement* targetElement, Color& color)
     51 {
     52     ASSERT(targetElement);
     53 
     54     if (RenderObject* targetRenderer = targetElement->renderer())
     55         color = targetRenderer->resolveColor(CSSPropertyColor);
     56     else
     57         color = Color();
     58 }
     59 
     60 static Color parseColorFromString(SVGAnimationElement*, const String& string)
     61 {
     62     return SVGColor::colorFromRGBColorString(string);
     63 }
     64 
     65 void SVGAnimatedColorAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
     66 {
     67     ASSERT(m_animationElement);
     68     ASSERT(m_contextElement);
     69 
     70     Color fromColor = m_animationElement->animationMode() == ToAnimation ? animated->color() : from->color();
     71     Color toColor = to->color();
     72     const Color& toAtEndOfDurationColor = toAtEndOfDuration->color();
     73     Color& animatedColor = animated->color();
     74 
     75     // Apply CSS inheritance rules.
     76     m_animationElement->adjustForInheritance<Color>(parseColorFromString, m_animationElement->fromPropertyValueType(), fromColor, m_contextElement);
     77     m_animationElement->adjustForInheritance<Color>(parseColorFromString, m_animationElement->toPropertyValueType(), toColor, m_contextElement);
     78 
     79     // Apply <animateColor> rules.
     80     if (m_animationElement->fromPropertyValueType() == CurrentColorValue)
     81         adjustForCurrentColor(m_contextElement, fromColor);
     82     if (m_animationElement->toPropertyValueType() == CurrentColorValue)
     83         adjustForCurrentColor(m_contextElement, toColor);
     84 
     85     float animatedRed = animatedColor.red();
     86     m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.red(), toColor.red(), toAtEndOfDurationColor.red(), animatedRed);
     87 
     88     float animatedGreen = animatedColor.green();
     89     m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.green(), toColor.green(), toAtEndOfDurationColor.green(), animatedGreen);
     90 
     91     float animatedBlue = animatedColor.blue();
     92     m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.blue(), toColor.blue(), toAtEndOfDurationColor.blue(), animatedBlue);
     93 
     94     float animatedAlpha = animatedColor.alpha();
     95     m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.alpha(), toColor.alpha(), toAtEndOfDurationColor.alpha(), animatedAlpha);
     96 
     97     animatedColor = ColorDistance::clampColor(static_cast<int>(roundf(animatedRed)), static_cast<int>(roundf(animatedGreen)), static_cast<int>(roundf(animatedBlue)), static_cast<int>(roundf(animatedAlpha)));
     98 }
     99 
    100 float SVGAnimatedColorAnimator::calculateDistance(const String& fromString, const String& toString)
    101 {
    102     ASSERT(m_contextElement);
    103     Color from;
    104     if (!SVGColor::colorFromRGBColorString(fromString, from))
    105         return -1;
    106     Color to;
    107     if (!SVGColor::colorFromRGBColorString(toString, to))
    108         return -1;
    109     return ColorDistance(from, to).distance();
    110 }
    111 
    112 }
    113