initial import
[vuplus_webkit] / Source / WebCore / svg / SVGLength.h
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3  * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #ifndef SVGLength_h
22 #define SVGLength_h
23
24 #if ENABLE(SVG)
25 #include "ExceptionCode.h"
26 #include "SVGParsingError.h"
27 #include "SVGPropertyTraits.h"
28
29 namespace WebCore {
30
31 class CSSPrimitiveValue;
32
33 enum SVGLengthType {
34     LengthTypeUnknown = 0,
35     LengthTypeNumber = 1,
36     LengthTypePercentage = 2,
37     LengthTypeEMS = 3,
38     LengthTypeEXS = 4,
39     LengthTypePX = 5,
40     LengthTypeCM = 6,
41     LengthTypeMM = 7,
42     LengthTypeIN = 8,
43     LengthTypePT = 9,
44     LengthTypePC = 10
45 };
46
47 enum SVGLengthMode {
48     LengthModeWidth = 0,
49     LengthModeHeight,
50     LengthModeOther
51 };
52
53 enum SVGLengthNegativeValuesMode {
54     AllowNegativeLengths,
55     ForbidNegativeLengths
56 };
57
58 class QualifiedName;
59 class SVGElement;
60
61 class SVGLength {
62 public:
63     // Forward declare these enums in the w3c naming scheme, for IDL generation
64     enum {
65         SVG_LENGTHTYPE_UNKNOWN = LengthTypeUnknown,
66         SVG_LENGTHTYPE_NUMBER = LengthTypeNumber,
67         SVG_LENGTHTYPE_PERCENTAGE = LengthTypePercentage,
68         SVG_LENGTHTYPE_EMS = LengthTypeEMS,
69         SVG_LENGTHTYPE_EXS = LengthTypeEXS,
70         SVG_LENGTHTYPE_PX = LengthTypePX,
71         SVG_LENGTHTYPE_CM = LengthTypeCM,
72         SVG_LENGTHTYPE_MM = LengthTypeMM,
73         SVG_LENGTHTYPE_IN = LengthTypeIN,
74         SVG_LENGTHTYPE_PT = LengthTypePT,
75         SVG_LENGTHTYPE_PC = LengthTypePC
76     };
77
78     SVGLength(SVGLengthMode mode = LengthModeOther, const String& valueAsString = String());
79     SVGLength(const SVGElement*, float, SVGLengthMode mode = LengthModeOther, SVGLengthType type = LengthTypeNumber);
80     SVGLength(const SVGLength&);
81
82     SVGLengthType unitType() const;
83
84     bool operator==(const SVGLength&) const;
85     bool operator!=(const SVGLength&) const;
86
87     static SVGLength construct(SVGLengthMode, const String&, SVGParsingError&, SVGLengthNegativeValuesMode = AllowNegativeLengths);
88
89     float value(const SVGElement* context) const;
90     float value(const SVGElement* context, ExceptionCode&) const;
91     void setValue(float, const SVGElement* context, ExceptionCode&);
92     void setValue(const SVGElement* context, float, SVGLengthMode, SVGLengthType, ExceptionCode&);
93
94     float valueInSpecifiedUnits() const { return m_valueInSpecifiedUnits; }
95     void setValueInSpecifiedUnits(float value) { m_valueInSpecifiedUnits = value; }
96
97     float valueAsPercentage() const;
98
99     String valueAsString() const;
100     void setValueAsString(const String&, ExceptionCode&);
101     void setValueAsString(const String&, SVGLengthMode, ExceptionCode&);
102     
103     void newValueSpecifiedUnits(unsigned short, float valueInSpecifiedUnits, ExceptionCode&);
104     void convertToSpecifiedUnits(unsigned short, const SVGElement* context, ExceptionCode&);
105
106     // Helper functions
107     inline bool isRelative() const
108     {
109         SVGLengthType type = unitType();
110         return type == LengthTypePercentage || type == LengthTypeEMS || type == LengthTypeEXS;
111     }
112
113     bool isZero() const 
114     { 
115         return !m_valueInSpecifiedUnits;
116     }
117
118     static SVGLength fromCSSPrimitiveValue(CSSPrimitiveValue*);
119     static PassRefPtr<CSSPrimitiveValue> toCSSPrimitiveValue(const SVGLength&);
120     static SVGLengthMode lengthModeForAnimatedLengthAttribute(const QualifiedName&);
121
122     SVGLength blend(const SVGLength& from, float progress) const
123     {
124         SVGLengthType toType = unitType();
125         SVGLengthType fromType = from.unitType();
126
127         if ((from.isZero() && isZero())
128             || fromType == LengthTypeUnknown
129             || toType == LengthTypeUnknown
130             || (!from.isZero() && fromType != LengthTypePercentage && toType == LengthTypePercentage)
131             || (!isZero() && fromType == LengthTypePercentage && toType != LengthTypePercentage)
132             || (!from.isZero() && !isZero() && (fromType == LengthTypeEMS || fromType == LengthTypeEXS) && fromType != toType))
133             return *this;
134
135         SVGLength length;
136         ExceptionCode ec = 0;
137
138         if (fromType == LengthTypePercentage || toType == LengthTypePercentage) {
139             float fromPercent = from.valueAsPercentage() * 100;
140             float toPercent = valueAsPercentage() * 100;
141             length.newValueSpecifiedUnits(LengthTypePercentage, fromPercent + (toPercent - fromPercent) * progress, ec);
142             if (ec)
143                 return SVGLength();
144             return length;
145         }
146
147         if (fromType == toType || from.isZero() || isZero() || fromType == LengthTypeEMS || fromType == LengthTypeEXS) {
148             float fromValue = from.valueInSpecifiedUnits();
149             float toValue = valueInSpecifiedUnits();
150             if (isZero())
151                 length.newValueSpecifiedUnits(fromType, fromValue + (toValue - fromValue) * progress, ec);
152             else
153                 length.newValueSpecifiedUnits(toType, fromValue + (toValue - fromValue) * progress, ec);
154             if (ec)
155                 return SVGLength();
156             return length;
157         }
158
159         ASSERT(!isRelative());
160         ASSERT(!from.isRelative());
161         float fromValueInUserUnits = convertValueToUserUnits(from.valueInSpecifiedUnits(), fromType, 0, ec);
162         if (ec)
163             return SVGLength();
164
165         float fromValue = convertValueFromUserUnits(fromValueInUserUnits, toType, 0, ec);
166         if (ec)
167             return SVGLength();
168
169         float toValue = valueInSpecifiedUnits();
170         length.newValueSpecifiedUnits(toType, fromValue + (toValue - fromValue) * progress, ec);
171
172         if (ec)
173             return SVGLength();
174         return length;
175     }
176
177 private:
178     bool determineViewport(const SVGElement* context, float& width, float& height) const;
179
180     float convertValueToUserUnits(float value, SVGLengthType fromUnit, const SVGElement* context, ExceptionCode&) const;
181     float convertValueFromUserUnits(float value, SVGLengthType toUnit, const SVGElement* context, ExceptionCode&) const;
182
183     float convertValueFromPercentageToUserUnits(float value, const SVGElement* context, ExceptionCode&) const;
184     float convertValueFromUserUnitsToPercentage(float value, const SVGElement* context, ExceptionCode&) const;
185
186     float convertValueFromUserUnitsToEMS(float value, const SVGElement* context, ExceptionCode&) const;
187     float convertValueFromEMSToUserUnits(float value, const SVGElement* context, ExceptionCode&) const;
188
189     float convertValueFromUserUnitsToEXS(float value, const SVGElement* context, ExceptionCode&) const;
190     float convertValueFromEXSToUserUnits(float value, const SVGElement* context, ExceptionCode&) const;
191
192 private:
193     float m_valueInSpecifiedUnits;
194     unsigned int m_unit;
195 };
196
197 template<>
198 struct SVGPropertyTraits<SVGLength> {
199     static SVGLength initialValue() { return SVGLength(); }
200     static String toString(const SVGLength& type) { return type.valueAsString(); }
201 };
202
203
204 } // namespace WebCore
205
206 #endif // ENABLE(SVG)
207 #endif // SVGLength_h