Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann (at) kde.org>
      3  * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis (at) kde.org>
      4  * Copyright (C) 2007 Apple Inc. All rights reserved.
      5  *
      6  * This library is free software; you can redistribute it and/or
      7  * modify it under the terms of the GNU Library General Public
      8  * License as published by the Free Software Foundation; either
      9  * version 2 of the License, or (at your option) any later version.
     10  *
     11  * This library is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  * Library General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU Library General Public License
     17  * along with this library; see the file COPYING.LIB.  If not, write to
     18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     19  * Boston, MA 02110-1301, USA.
     20  */
     21 
     22 #include "config.h"
     23 
     24 #include "core/svg/SVGRect.h"
     25 
     26 #include "bindings/core/v8/ExceptionState.h"
     27 #include "core/dom/ExceptionCode.h"
     28 #include "core/svg/SVGAnimationElement.h"
     29 #include "core/svg/SVGParserUtilities.h"
     30 #include "wtf/text/StringBuilder.h"
     31 #include "wtf/text/WTFString.h"
     32 
     33 namespace blink {
     34 
     35 SVGRect::SVGRect()
     36     : m_isValid(true)
     37 {
     38 }
     39 
     40 SVGRect::SVGRect(InvalidSVGRectTag)
     41 {
     42     setInvalid();
     43 }
     44 
     45 SVGRect::SVGRect(const FloatRect& rect)
     46     : m_isValid(true)
     47     , m_value(rect)
     48 {
     49 }
     50 
     51 PassRefPtr<SVGRect> SVGRect::clone() const
     52 {
     53     return SVGRect::create(m_value);
     54 }
     55 
     56 template<typename CharType>
     57 void SVGRect::parse(const CharType*& ptr, const CharType* end, ExceptionState& exceptionState)
     58 {
     59     const CharType* start = ptr;
     60 
     61     skipOptionalSVGSpaces(ptr, end);
     62 
     63     float x = 0.0f;
     64     float y = 0.0f;
     65     float width = 0.0f;
     66     float height = 0.0f;
     67     bool valid = parseNumber(ptr, end, x) && parseNumber(ptr, end, y) && parseNumber(ptr, end, width) && parseNumber(ptr, end, height, DisallowWhitespace);
     68 
     69     if (!valid) {
     70         exceptionState.throwDOMException(SyntaxError, "Problem parsing rect \"" + String(start, end - start) + "\"");
     71         setInvalid();
     72         return;
     73     }
     74 
     75     skipOptionalSVGSpaces(ptr, end);
     76     if (ptr < end) { // nothing should come after the last, fourth number
     77         exceptionState.throwDOMException(SyntaxError, "Problem parsing rect \"" + String(start, end - start) + "\"");
     78         setInvalid();
     79         return;
     80     }
     81 
     82     m_value = FloatRect(x, y, width, height);
     83     m_isValid = true;
     84 }
     85 
     86 void SVGRect::setValueAsString(const String& string, ExceptionState& exceptionState)
     87 {
     88     if (string.isNull()) {
     89         setInvalid();
     90         return;
     91     }
     92     if (string.isEmpty()) {
     93         m_value = FloatRect(0.0f, 0.0f, 0.0f, 0.0f);
     94         m_isValid = true;
     95         return;
     96     }
     97 
     98     if (string.is8Bit()) {
     99         const LChar* ptr = string.characters8();
    100         const LChar* end = ptr + string.length();
    101         parse(ptr, end, exceptionState);
    102         return;
    103     }
    104 
    105     const UChar* ptr = string.characters16();
    106     const UChar* end = ptr + string.length();
    107     parse(ptr, end, exceptionState);
    108 }
    109 
    110 String SVGRect::valueAsString() const
    111 {
    112     StringBuilder builder;
    113     builder.appendNumber(x());
    114     builder.append(' ');
    115     builder.appendNumber(y());
    116     builder.append(' ');
    117     builder.appendNumber(width());
    118     builder.append(' ');
    119     builder.appendNumber(height());
    120     return builder.toString();
    121 }
    122 
    123 void SVGRect::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
    124 {
    125     m_value += toSVGRect(other)->value();
    126 }
    127 
    128 void SVGRect::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*)
    129 {
    130     ASSERT(animationElement);
    131     RefPtr<SVGRect> fromRect = animationElement->animationMode() == ToAnimation ? this : toSVGRect(fromValue);
    132     RefPtr<SVGRect> toRect = toSVGRect(toValue);
    133     RefPtr<SVGRect> toAtEndOfDurationRect = toSVGRect(toAtEndOfDurationValue);
    134 
    135     float animatedX = x();
    136     float animatedY = y();
    137     float animatedWidth = width();
    138     float animatedHeight = height();
    139     animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect->x(), toRect->x(), toAtEndOfDurationRect->x(), animatedX);
    140     animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect->y(), toRect->y(), toAtEndOfDurationRect->y(), animatedY);
    141     animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect->width(), toRect->width(), toAtEndOfDurationRect->width(), animatedWidth);
    142     animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect->height(), toRect->height(), toAtEndOfDurationRect->height(), animatedHeight);
    143 
    144     m_value = FloatRect(animatedX, animatedY, animatedWidth, animatedHeight);
    145 }
    146 
    147 float SVGRect::calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement)
    148 {
    149     // FIXME: Distance calculation is not possible for SVGRect right now. We need the distance for every single value.
    150     return -1;
    151 }
    152 
    153 void SVGRect::setInvalid()
    154 {
    155     m_value = FloatRect(0.0f, 0.0f, 0.0f, 0.0f);
    156     m_isValid = false;
    157 }
    158 
    159 }
    160