109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)/*
209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Copyright (C) 2007 Apple Inc. All rights reserved.
509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * This library is free software; you can redistribute it and/or
709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * License as published by the Free Software Foundation; either
909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
1009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
1109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
1209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
1309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Library General Public License for more details.
1509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) *
1609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
1709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
1809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) * Boston, MA 02110-1301, USA.
2009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) */
2109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
2209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "config.h"
2309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
2409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/svg/SVGRect.h"
2509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
26197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionState.h"
2709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/dom/ExceptionCode.h"
2809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/svg/SVGAnimationElement.h"
2909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/svg/SVGParserUtilities.h"
3009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/text/StringBuilder.h"
3109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/text/WTFString.h"
3209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
33c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
3409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)SVGRect::SVGRect()
36197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    : m_isValid(true)
3709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
3809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
3909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
4009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)SVGRect::SVGRect(InvalidSVGRectTag)
4109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
4209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    setInvalid();
4309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
4409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
4509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)SVGRect::SVGRect(const FloatRect& rect)
46197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    : m_isValid(true)
4709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    , m_value(rect)
4809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
5009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
5109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)PassRefPtr<SVGRect> SVGRect::clone() const
5209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return SVGRect::create(m_value);
5409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
5509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
5609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<typename CharType>
5709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void SVGRect::parse(const CharType*& ptr, const CharType* end, ExceptionState& exceptionState)
5809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const CharType* start = ptr;
6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
6109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    skipOptionalSVGSpaces(ptr, end);
6209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
6309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float x = 0.0f;
6409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float y = 0.0f;
6509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float width = 0.0f;
6609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float height = 0.0f;
675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    bool valid = parseNumber(ptr, end, x) && parseNumber(ptr, end, y) && parseNumber(ptr, end, width) && parseNumber(ptr, end, height, DisallowWhitespace);
6809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
6909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!valid) {
7009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        exceptionState.throwDOMException(SyntaxError, "Problem parsing rect \"" + String(start, end - start) + "\"");
7109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        setInvalid();
7209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
7309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
7409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
7509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    skipOptionalSVGSpaces(ptr, end);
7609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (ptr < end) { // nothing should come after the last, fourth number
7709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        exceptionState.throwDOMException(SyntaxError, "Problem parsing rect \"" + String(start, end - start) + "\"");
7809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        setInvalid();
7909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
8009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
8109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
8209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_value = FloatRect(x, y, width, height);
8309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_isValid = true;
8409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
8509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void SVGRect::setValueAsString(const String& string, ExceptionState& exceptionState)
8709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
8809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (string.isNull()) {
8909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        setInvalid();
9009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
9109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
9209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (string.isEmpty()) {
9309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_value = FloatRect(0.0f, 0.0f, 0.0f, 0.0f);
9409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_isValid = true;
9509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
9609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
9709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
9809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (string.is8Bit()) {
9909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        const LChar* ptr = string.characters8();
10009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        const LChar* end = ptr + string.length();
10109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        parse(ptr, end, exceptionState);
10209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return;
10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
10409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const UChar* ptr = string.characters16();
10609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const UChar* end = ptr + string.length();
10709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    parse(ptr, end, exceptionState);
10809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
10909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
11009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)String SVGRect::valueAsString() const
11109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
11209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    StringBuilder builder;
1137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    builder.appendNumber(x());
11409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    builder.append(' ');
1157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    builder.appendNumber(y());
11609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    builder.append(' ');
1177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    builder.appendNumber(width());
11809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    builder.append(' ');
1197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    builder.appendNumber(height());
12009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return builder.toString();
12109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
123d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void SVGRect::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
12409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_value += toSVGRect(other)->value();
12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
12807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochvoid SVGRect::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*)
12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT(animationElement);
13109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    RefPtr<SVGRect> fromRect = animationElement->animationMode() == ToAnimation ? this : toSVGRect(fromValue);
13209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    RefPtr<SVGRect> toRect = toSVGRect(toValue);
13309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    RefPtr<SVGRect> toAtEndOfDurationRect = toSVGRect(toAtEndOfDurationValue);
13409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
13509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float animatedX = x();
13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float animatedY = y();
13709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float animatedWidth = width();
13809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    float animatedHeight = height();
13909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect->x(), toRect->x(), toAtEndOfDurationRect->x(), animatedX);
14009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect->y(), toRect->y(), toAtEndOfDurationRect->y(), animatedY);
14109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect->width(), toRect->width(), toAtEndOfDurationRect->width(), animatedWidth);
14209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect->height(), toRect->height(), toAtEndOfDurationRect->height(), animatedHeight);
14309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
14409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_value = FloatRect(animatedX, animatedY, animatedWidth, animatedHeight);
14509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
14609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
14707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochfloat SVGRect::calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement)
14809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
14909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // FIXME: Distance calculation is not possible for SVGRect right now. We need the distance for every single value.
15009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return -1;
15109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
15209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
15309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void SVGRect::setInvalid()
15409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
15509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_value = FloatRect(0.0f, 0.0f, 0.0f, 0.0f);
15609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_isValid = false;
15709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
15809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
15909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
160