OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> | 2 * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> |
3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> |
4 * Copyright (C) 2007 Apple Inc. All rights reserved. | 4 * Copyright (C) 2007 Apple Inc. All rights reserved. |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
11 * This library is distributed in the hope that it will be useful, | 11 * This library is distributed in the hope that it will be useful, |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 * Library General Public License for more details. | 14 * Library General Public License for more details. |
15 * | 15 * |
16 * You should have received a copy of the GNU Library General Public License | 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 | 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, | 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 * Boston, MA 02110-1301, USA. | 19 * Boston, MA 02110-1301, USA. |
20 */ | 20 */ |
21 | 21 |
22 #include "config.h" | 22 #include "config.h" |
23 | 23 |
24 #include "core/svg/SVGLength.h" | 24 #include "core/svg/SVGLength.h" |
25 | 25 |
26 #include "SVGNames.h" | 26 #include "SVGNames.h" |
27 #include "bindings/v8/ExceptionStatePlaceholder.h" | 27 #include "bindings/v8/ExceptionState.h" |
28 #include "core/css/CSSPrimitiveValue.h" | 28 #include "core/css/CSSPrimitiveValue.h" |
29 #include "core/dom/ExceptionCode.h" | 29 #include "core/dom/ExceptionCode.h" |
| 30 #include "core/svg/SVGAnimationElement.h" |
30 #include "core/svg/SVGParserUtilities.h" | 31 #include "core/svg/SVGParserUtilities.h" |
| 32 #include "platform/animation/AnimationUtilities.h" |
31 #include "wtf/MathExtras.h" | 33 #include "wtf/MathExtras.h" |
32 #include "wtf/text/WTFString.h" | 34 #include "wtf/text/WTFString.h" |
33 | 35 |
34 namespace WebCore { | 36 namespace WebCore { |
35 | 37 |
36 static inline SVGLengthMode toSVGLengthMode(unsigned short mode) | 38 namespace { |
37 { | |
38 ASSERT(mode >= LengthModeWidth && mode <= LengthModeOther); | |
39 return static_cast<SVGLengthMode>(mode); | |
40 } | |
41 | 39 |
42 static inline SVGLengthType toSVGLengthType(unsigned short type) | 40 inline String lengthTypeToString(SVGLengthType type) |
43 { | |
44 ASSERT(type >= LengthTypeUnknown && type <= LengthTypePC); | |
45 return static_cast<SVGLengthType>(type); | |
46 } | |
47 | |
48 static inline unsigned int storeUnit(SVGLengthMode mode, SVGLengthType type) | |
49 { | |
50 return (mode << 4) | type; | |
51 } | |
52 | |
53 static inline SVGLengthMode extractMode(unsigned int unit) | |
54 { | |
55 unsigned int mode = unit >> 4; | |
56 return toSVGLengthMode(mode); | |
57 } | |
58 | |
59 static inline SVGLengthType extractType(unsigned int unit) | |
60 { | |
61 unsigned int mode = unit >> 4; | |
62 unsigned int type = unit ^ (mode << 4); | |
63 return toSVGLengthType(type); | |
64 } | |
65 | |
66 static inline String lengthTypeToString(SVGLengthType type) | |
67 { | 41 { |
68 switch (type) { | 42 switch (type) { |
69 case LengthTypeUnknown: | 43 case LengthTypeUnknown: |
70 case LengthTypeNumber: | 44 case LengthTypeNumber: |
71 return ""; | 45 return ""; |
72 case LengthTypePercentage: | 46 case LengthTypePercentage: |
73 return "%"; | 47 return "%"; |
74 case LengthTypeEMS: | 48 case LengthTypeEMS: |
75 return "em"; | 49 return "em"; |
76 case LengthTypeEXS: | 50 case LengthTypeEXS: |
(...skipping 10 matching lines...) Expand all Loading... |
87 return "pt"; | 61 return "pt"; |
88 case LengthTypePC: | 62 case LengthTypePC: |
89 return "pc"; | 63 return "pc"; |
90 } | 64 } |
91 | 65 |
92 ASSERT_NOT_REACHED(); | 66 ASSERT_NOT_REACHED(); |
93 return String(); | 67 return String(); |
94 } | 68 } |
95 | 69 |
96 template<typename CharType> | 70 template<typename CharType> |
97 static SVGLengthType stringToLengthType(const CharType*& ptr, const CharType* en
d) | 71 SVGLengthType stringToLengthType(const CharType*& ptr, const CharType* end) |
98 { | 72 { |
99 if (ptr == end) | 73 if (ptr == end) |
100 return LengthTypeNumber; | 74 return LengthTypeNumber; |
101 | 75 |
102 const UChar firstChar = *ptr; | 76 const UChar firstChar = *ptr; |
103 | 77 |
104 if (++ptr == end) | 78 if (++ptr == end) |
105 return firstChar == '%' ? LengthTypePercentage : LengthTypeUnknown; | 79 return firstChar == '%' ? LengthTypePercentage : LengthTypeUnknown; |
106 | 80 |
107 const UChar secondChar = *ptr; | 81 const UChar secondChar = *ptr; |
(...skipping 14 matching lines...) Expand all Loading... |
122 if (firstChar == 'i' && secondChar == 'n') | 96 if (firstChar == 'i' && secondChar == 'n') |
123 return LengthTypeIN; | 97 return LengthTypeIN; |
124 if (firstChar == 'p' && secondChar == 't') | 98 if (firstChar == 'p' && secondChar == 't') |
125 return LengthTypePT; | 99 return LengthTypePT; |
126 if (firstChar == 'p' && secondChar == 'c') | 100 if (firstChar == 'p' && secondChar == 'c') |
127 return LengthTypePC; | 101 return LengthTypePC; |
128 | 102 |
129 return LengthTypeUnknown; | 103 return LengthTypeUnknown; |
130 } | 104 } |
131 | 105 |
132 SVGLength::SVGLength(SVGLengthMode mode, const String& valueAsString) | 106 } // namespace |
133 : m_valueInSpecifiedUnits(0) | |
134 , m_unit(storeUnit(mode, LengthTypeNumber)) | |
135 { | |
136 setValueAsString(valueAsString, IGNORE_EXCEPTION); | |
137 } | |
138 | 107 |
139 SVGLength::SVGLength(const SVGLengthContext& context, float value, SVGLengthMode
mode, SVGLengthType unitType) | 108 SVGLength::SVGLength(SVGLengthMode mode) |
140 : m_valueInSpecifiedUnits(0) | 109 : NewSVGPropertyBase(classType()) |
141 , m_unit(storeUnit(mode, unitType)) | 110 , m_valueInSpecifiedUnits(0) |
142 { | 111 , m_unitMode(mode) |
143 setValue(value, context, ASSERT_NO_EXCEPTION); | 112 , m_unitType(LengthTypeNumber) |
144 } | |
145 | |
146 SVGLength::SVGLength(const SVGLength& other) | |
147 : m_valueInSpecifiedUnits(other.m_valueInSpecifiedUnits) | |
148 , m_unit(other.m_unit) | |
149 { | 113 { |
150 } | 114 } |
151 | 115 |
152 void SVGLength::setValueAsString(const String& valueAsString, SVGLengthMode mode
, ExceptionState& exceptionState) | 116 SVGLength::SVGLength(const SVGLength& o) |
| 117 : NewSVGPropertyBase(classType()) |
| 118 , m_valueInSpecifiedUnits(o.m_valueInSpecifiedUnits) |
| 119 , m_unitMode(o.m_unitMode) |
| 120 , m_unitType(o.m_unitType) |
153 { | 121 { |
154 m_valueInSpecifiedUnits = 0; | 122 } |
155 m_unit = storeUnit(mode, LengthTypeNumber); | 123 |
156 setValueAsString(valueAsString, exceptionState); | 124 PassRefPtr<SVGLength> SVGLength::clone() const |
| 125 { |
| 126 return adoptRef(new SVGLength(*this)); |
| 127 } |
| 128 |
| 129 PassRefPtr<NewSVGPropertyBase> SVGLength::cloneForAnimation(const String& value)
const |
| 130 { |
| 131 RefPtr<SVGLength> length = create(); |
| 132 |
| 133 length->m_unitMode = m_unitMode; |
| 134 length->m_unitType = m_unitType; |
| 135 |
| 136 TrackExceptionState exceptionState; |
| 137 length->setValueAsString(value, exceptionState); |
| 138 if (exceptionState.hadException()) { |
| 139 length->m_unitType = LengthTypeNumber; |
| 140 length->m_valueInSpecifiedUnits = 0; |
| 141 } |
| 142 |
| 143 return length.release(); |
157 } | 144 } |
158 | 145 |
159 bool SVGLength::operator==(const SVGLength& other) const | 146 bool SVGLength::operator==(const SVGLength& other) const |
160 { | 147 { |
161 return m_unit == other.m_unit | 148 return m_unitMode == other.m_unitMode |
| 149 && m_unitType == other.m_unitType |
162 && m_valueInSpecifiedUnits == other.m_valueInSpecifiedUnits; | 150 && m_valueInSpecifiedUnits == other.m_valueInSpecifiedUnits; |
163 } | 151 } |
164 | 152 |
165 bool SVGLength::operator!=(const SVGLength& other) const | 153 float SVGLength::value(const SVGLengthContext& context, ExceptionState& es) cons
t |
166 { | 154 { |
167 return !operator==(other); | 155 return context.convertValueToUserUnits(m_valueInSpecifiedUnits, unitMode(),
unitType(), es); |
168 } | 156 } |
169 | 157 |
170 SVGLength SVGLength::construct(SVGLengthMode mode, const String& valueAsString,
SVGParsingError& parseError, SVGLengthNegativeValuesMode negativeValuesMode) | 158 void SVGLength::setValue(float value, const SVGLengthContext& context, Exception
State& es) |
171 { | 159 { |
172 TrackExceptionState exceptionState; | 160 // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually
be changed |
173 SVGLength length(mode); | 161 if (m_unitType == LengthTypePercentage) |
| 162 value = value / 100; |
174 | 163 |
175 length.setValueAsString(valueAsString, exceptionState); | 164 float convertedValue = context.convertValueFromUserUnits(value, unitMode(),
unitType(), es); |
| 165 if (es.hadException()) |
| 166 return; |
176 | 167 |
177 if (exceptionState.hadException()) | 168 m_valueInSpecifiedUnits = convertedValue; |
178 parseError = ParsingAttributeFailedError; | |
179 else if (negativeValuesMode == ForbidNegativeLengths && length.valueInSpecif
iedUnits() < 0) | |
180 parseError = NegativeValueForbiddenError; | |
181 | |
182 return length; | |
183 } | 169 } |
184 | 170 |
185 SVGLengthType SVGLength::unitType() const | 171 void SVGLength::setUnitType(SVGLengthType type) |
186 { | 172 { |
187 return extractType(m_unit); | 173 ASSERT(type != LengthTypeUnknown && type <= LengthTypePC); |
| 174 m_unitType = type; |
188 } | 175 } |
189 | 176 |
190 SVGLengthMode SVGLength::unitMode() const | |
191 { | |
192 return extractMode(m_unit); | |
193 } | |
194 | |
195 float SVGLength::value(const SVGLengthContext& context) const | |
196 { | |
197 return value(context, IGNORE_EXCEPTION); | |
198 } | |
199 | |
200 float SVGLength::value(const SVGLengthContext& context, ExceptionState& exceptio
nState) const | |
201 { | |
202 return context.convertValueToUserUnits(m_valueInSpecifiedUnits, extractMode(
m_unit), extractType(m_unit), exceptionState); | |
203 } | |
204 | |
205 void SVGLength::setValue(const SVGLengthContext& context, float value, SVGLength
Mode mode, SVGLengthType unitType, ExceptionState& exceptionState) | |
206 { | |
207 m_unit = storeUnit(mode, unitType); | |
208 setValue(value, context, exceptionState); | |
209 } | |
210 | |
211 void SVGLength::setValue(float value, const SVGLengthContext& context, Exception
State& exceptionState) | |
212 { | |
213 // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually
be changed | |
214 if (extractType(m_unit) == LengthTypePercentage) | |
215 value = value / 100; | |
216 | |
217 float convertedValue = context.convertValueFromUserUnits(value, extractMode(
m_unit), extractType(m_unit), exceptionState); | |
218 if (!exceptionState.hadException()) | |
219 m_valueInSpecifiedUnits = convertedValue; | |
220 } | |
221 float SVGLength::valueAsPercentage() const | 177 float SVGLength::valueAsPercentage() const |
222 { | 178 { |
223 // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually
be changed | 179 // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually
be changed |
224 if (extractType(m_unit) == LengthTypePercentage) | 180 if (m_unitType == LengthTypePercentage) |
225 return m_valueInSpecifiedUnits / 100; | 181 return m_valueInSpecifiedUnits / 100; |
226 | 182 |
227 return m_valueInSpecifiedUnits; | 183 return m_valueInSpecifiedUnits; |
228 } | 184 } |
229 | 185 |
230 template<typename CharType> | 186 template<typename CharType> |
231 static bool parseValueInternal(const String& string, float& convertedNumber, SVG
LengthType& type) | 187 static bool parseValueInternal(const String& string, float& convertedNumber, SVG
LengthType& type) |
232 { | 188 { |
233 const CharType* ptr = string.getCharacters<CharType>(); | 189 const CharType* ptr = string.getCharacters<CharType>(); |
234 const CharType* end = ptr + string.length(); | 190 const CharType* end = ptr + string.length(); |
235 | 191 |
236 if (!parseNumber(ptr, end, convertedNumber, false)) | 192 if (!parseNumber(ptr, end, convertedNumber, false)) |
237 return false; | 193 return false; |
238 | 194 |
239 type = stringToLengthType(ptr, end); | 195 type = stringToLengthType(ptr, end); |
240 ASSERT(ptr <= end); | 196 ASSERT(ptr <= end); |
241 if (type == LengthTypeUnknown) | 197 if (type == LengthTypeUnknown) |
242 return false; | 198 return false; |
243 | 199 |
244 return true; | 200 return true; |
245 } | 201 } |
246 | 202 |
247 void SVGLength::setValueAsString(const String& string, ExceptionState& exception
State) | 203 void SVGLength::setValueAsString(const String& string, ExceptionState& exception
State) |
248 { | 204 { |
249 if (string.isEmpty()) | 205 if (string.isEmpty()) { |
| 206 m_unitType = LengthTypeNumber; |
| 207 m_valueInSpecifiedUnits = 0; |
250 return; | 208 return; |
| 209 } |
251 | 210 |
252 float convertedNumber = 0; | 211 float convertedNumber = 0; |
253 SVGLengthType type = LengthTypeUnknown; | 212 SVGLengthType type = LengthTypeUnknown; |
254 | 213 |
255 bool success = string.is8Bit() ? | 214 bool success = string.is8Bit() ? |
256 parseValueInternal<LChar>(string, convertedNumber, type) : | 215 parseValueInternal<LChar>(string, convertedNumber, type) : |
257 parseValueInternal<UChar>(string, convertedNumber, type); | 216 parseValueInternal<UChar>(string, convertedNumber, type); |
258 | 217 |
259 if (!success) { | 218 if (!success) { |
260 exceptionState.throwDOMException(SyntaxError, "The value provided ('" +
string + "') is invalid."); | 219 exceptionState.throwDOMException(SyntaxError, "The value provided ('" +
string + "') is invalid."); |
261 return; | 220 return; |
262 } | 221 } |
263 | 222 |
264 m_unit = storeUnit(extractMode(m_unit), type); | 223 m_unitType = type; |
265 m_valueInSpecifiedUnits = convertedNumber; | 224 m_valueInSpecifiedUnits = convertedNumber; |
266 } | 225 } |
267 | 226 |
268 String SVGLength::valueAsString() const | 227 String SVGLength::valueAsString() const |
269 { | 228 { |
270 return String::number(m_valueInSpecifiedUnits) + lengthTypeToString(extractT
ype(m_unit)); | 229 return String::number(m_valueInSpecifiedUnits) + lengthTypeToString(unitType
()); |
271 } | 230 } |
272 | 231 |
273 void SVGLength::newValueSpecifiedUnits(unsigned short type, float value, Excepti
onState& exceptionState) | 232 void SVGLength::newValueSpecifiedUnits(SVGLengthType type, float value) |
274 { | 233 { |
275 if (type == LengthTypeUnknown || type > LengthTypePC) { | 234 setUnitType(type); |
276 exceptionState.throwDOMException(NotSupportedError, "Cannot set value wi
th unknown or invalid units (" + String::number(type) + ")."); | |
277 return; | |
278 } | |
279 | |
280 m_unit = storeUnit(extractMode(m_unit), toSVGLengthType(type)); | |
281 m_valueInSpecifiedUnits = value; | 235 m_valueInSpecifiedUnits = value; |
282 } | 236 } |
283 | 237 |
284 void SVGLength::convertToSpecifiedUnits(unsigned short type, const SVGLengthCont
ext& context, ExceptionState& exceptionState) | 238 void SVGLength::convertToSpecifiedUnits(SVGLengthType type, const SVGLengthConte
xt& context, ExceptionState& exceptionState) |
285 { | 239 { |
286 if (type == LengthTypeUnknown || type > LengthTypePC) { | 240 ASSERT(type != LengthTypeUnknown && type <= LengthTypePC); |
287 exceptionState.throwDOMException(NotSupportedError, "Cannot convert to u
nknown or invalid units (" + String::number(type) + ")."); | |
288 return; | |
289 } | |
290 | 241 |
291 float valueInUserUnits = value(context, exceptionState); | 242 float valueInUserUnits = value(context, exceptionState); |
292 if (exceptionState.hadException()) | 243 if (exceptionState.hadException()) |
293 return; | 244 return; |
294 | 245 |
295 unsigned int originalUnitAndType = m_unit; | 246 SVGLengthType originalType = unitType(); |
296 m_unit = storeUnit(extractMode(m_unit), toSVGLengthType(type)); | 247 m_unitType = type; |
297 setValue(valueInUserUnits, context, exceptionState); | 248 setValue(valueInUserUnits, context, exceptionState); |
298 if (!exceptionState.hadException()) | 249 if (!exceptionState.hadException()) |
299 return; | 250 return; |
300 | 251 |
301 // Eventually restore old unit and type | 252 // Eventually restore old unit and type |
302 m_unit = originalUnitAndType; | 253 m_unitType = originalType; |
303 } | 254 } |
304 | 255 |
305 SVGLength SVGLength::fromCSSPrimitiveValue(CSSPrimitiveValue* value) | 256 PassRefPtr<SVGLength> SVGLength::fromCSSPrimitiveValue(CSSPrimitiveValue* value) |
306 { | 257 { |
307 ASSERT(value); | 258 ASSERT(value); |
308 | 259 |
309 SVGLengthType svgType; | 260 SVGLengthType svgType; |
310 switch (value->primitiveType()) { | 261 switch (value->primitiveType()) { |
311 case CSSPrimitiveValue::CSS_NUMBER: | 262 case CSSPrimitiveValue::CSS_NUMBER: |
312 svgType = LengthTypeNumber; | 263 svgType = LengthTypeNumber; |
313 break; | 264 break; |
314 case CSSPrimitiveValue::CSS_PERCENTAGE: | 265 case CSSPrimitiveValue::CSS_PERCENTAGE: |
315 svgType = LengthTypePercentage; | 266 svgType = LengthTypePercentage; |
(...skipping 22 matching lines...) Expand all Loading... |
338 case CSSPrimitiveValue::CSS_PC: | 289 case CSSPrimitiveValue::CSS_PC: |
339 svgType = LengthTypePC; | 290 svgType = LengthTypePC; |
340 break; | 291 break; |
341 case CSSPrimitiveValue::CSS_UNKNOWN: | 292 case CSSPrimitiveValue::CSS_UNKNOWN: |
342 default: | 293 default: |
343 svgType = LengthTypeUnknown; | 294 svgType = LengthTypeUnknown; |
344 break; | 295 break; |
345 }; | 296 }; |
346 | 297 |
347 if (svgType == LengthTypeUnknown) | 298 if (svgType == LengthTypeUnknown) |
348 return SVGLength(); | 299 return SVGLength::create(); |
349 | 300 |
350 TrackExceptionState exceptionState; | 301 RefPtr<SVGLength> length = SVGLength::create(); |
351 SVGLength length; | 302 length->newValueSpecifiedUnits(svgType, value->getFloatValue()); |
352 length.newValueSpecifiedUnits(svgType, value->getFloatValue(), exceptionStat
e); | 303 return length.release(); |
353 if (exceptionState.hadException()) | |
354 return SVGLength(); | |
355 | |
356 return length; | |
357 } | 304 } |
358 | 305 |
359 PassRefPtr<CSSPrimitiveValue> SVGLength::toCSSPrimitiveValue(const SVGLength& le
ngth) | 306 PassRefPtr<CSSPrimitiveValue> SVGLength::toCSSPrimitiveValue(PassRefPtr<SVGLengt
h> passLength) |
360 { | 307 { |
| 308 RefPtr<SVGLength> length = passLength; |
| 309 |
361 CSSPrimitiveValue::UnitTypes cssType = CSSPrimitiveValue::CSS_UNKNOWN; | 310 CSSPrimitiveValue::UnitTypes cssType = CSSPrimitiveValue::CSS_UNKNOWN; |
362 switch (length.unitType()) { | 311 switch (length->unitType()) { |
363 case LengthTypeUnknown: | 312 case LengthTypeUnknown: |
364 break; | 313 break; |
365 case LengthTypeNumber: | 314 case LengthTypeNumber: |
366 cssType = CSSPrimitiveValue::CSS_NUMBER; | 315 cssType = CSSPrimitiveValue::CSS_NUMBER; |
367 break; | 316 break; |
368 case LengthTypePercentage: | 317 case LengthTypePercentage: |
369 cssType = CSSPrimitiveValue::CSS_PERCENTAGE; | 318 cssType = CSSPrimitiveValue::CSS_PERCENTAGE; |
370 break; | 319 break; |
371 case LengthTypeEMS: | 320 case LengthTypeEMS: |
372 cssType = CSSPrimitiveValue::CSS_EMS; | 321 cssType = CSSPrimitiveValue::CSS_EMS; |
(...skipping 14 matching lines...) Expand all Loading... |
387 cssType = CSSPrimitiveValue::CSS_IN; | 336 cssType = CSSPrimitiveValue::CSS_IN; |
388 break; | 337 break; |
389 case LengthTypePT: | 338 case LengthTypePT: |
390 cssType = CSSPrimitiveValue::CSS_PT; | 339 cssType = CSSPrimitiveValue::CSS_PT; |
391 break; | 340 break; |
392 case LengthTypePC: | 341 case LengthTypePC: |
393 cssType = CSSPrimitiveValue::CSS_PC; | 342 cssType = CSSPrimitiveValue::CSS_PC; |
394 break; | 343 break; |
395 }; | 344 }; |
396 | 345 |
397 return CSSPrimitiveValue::create(length.valueInSpecifiedUnits(), cssType); | 346 return CSSPrimitiveValue::create(length->valueInSpecifiedUnits(), cssType); |
398 } | 347 } |
399 | 348 |
400 SVGLengthMode SVGLength::lengthModeForAnimatedLengthAttribute(const QualifiedNam
e& attrName) | 349 SVGLengthMode SVGLength::lengthModeForAnimatedLengthAttribute(const QualifiedNam
e& attrName) |
401 { | 350 { |
402 typedef HashMap<QualifiedName, SVGLengthMode> LengthModeForLengthAttributeMa
p; | 351 typedef HashMap<QualifiedName, SVGLengthMode> LengthModeForLengthAttributeMa
p; |
403 DEFINE_STATIC_LOCAL(LengthModeForLengthAttributeMap, s_lengthModeMap, ()); | 352 DEFINE_STATIC_LOCAL(LengthModeForLengthAttributeMap, s_lengthModeMap, ()); |
404 | 353 |
405 if (s_lengthModeMap.isEmpty()) { | 354 if (s_lengthModeMap.isEmpty()) { |
406 s_lengthModeMap.set(SVGNames::xAttr, LengthModeWidth); | 355 s_lengthModeMap.set(SVGNames::xAttr, LengthModeWidth); |
407 s_lengthModeMap.set(SVGNames::yAttr, LengthModeHeight); | 356 s_lengthModeMap.set(SVGNames::yAttr, LengthModeHeight); |
408 s_lengthModeMap.set(SVGNames::cxAttr, LengthModeWidth); | 357 s_lengthModeMap.set(SVGNames::cxAttr, LengthModeWidth); |
409 s_lengthModeMap.set(SVGNames::cyAttr, LengthModeHeight); | 358 s_lengthModeMap.set(SVGNames::cyAttr, LengthModeHeight); |
410 s_lengthModeMap.set(SVGNames::dxAttr, LengthModeWidth); | 359 s_lengthModeMap.set(SVGNames::dxAttr, LengthModeWidth); |
411 s_lengthModeMap.set(SVGNames::dyAttr, LengthModeHeight); | 360 s_lengthModeMap.set(SVGNames::dyAttr, LengthModeHeight); |
412 s_lengthModeMap.set(SVGNames::fxAttr, LengthModeWidth); | 361 s_lengthModeMap.set(SVGNames::fxAttr, LengthModeWidth); |
413 s_lengthModeMap.set(SVGNames::fyAttr, LengthModeHeight); | 362 s_lengthModeMap.set(SVGNames::fyAttr, LengthModeHeight); |
414 s_lengthModeMap.set(SVGNames::rAttr, LengthModeOther); | 363 s_lengthModeMap.set(SVGNames::rAttr, LengthModeOther); |
| 364 s_lengthModeMap.set(SVGNames::rxAttr, LengthModeWidth); |
| 365 s_lengthModeMap.set(SVGNames::ryAttr, LengthModeHeight); |
415 s_lengthModeMap.set(SVGNames::widthAttr, LengthModeWidth); | 366 s_lengthModeMap.set(SVGNames::widthAttr, LengthModeWidth); |
416 s_lengthModeMap.set(SVGNames::heightAttr, LengthModeHeight); | 367 s_lengthModeMap.set(SVGNames::heightAttr, LengthModeHeight); |
417 s_lengthModeMap.set(SVGNames::x1Attr, LengthModeWidth); | 368 s_lengthModeMap.set(SVGNames::x1Attr, LengthModeWidth); |
418 s_lengthModeMap.set(SVGNames::x2Attr, LengthModeWidth); | 369 s_lengthModeMap.set(SVGNames::x2Attr, LengthModeWidth); |
419 s_lengthModeMap.set(SVGNames::y1Attr, LengthModeHeight); | 370 s_lengthModeMap.set(SVGNames::y1Attr, LengthModeHeight); |
420 s_lengthModeMap.set(SVGNames::y2Attr, LengthModeHeight); | 371 s_lengthModeMap.set(SVGNames::y2Attr, LengthModeHeight); |
421 s_lengthModeMap.set(SVGNames::refXAttr, LengthModeWidth); | 372 s_lengthModeMap.set(SVGNames::refXAttr, LengthModeWidth); |
422 s_lengthModeMap.set(SVGNames::refYAttr, LengthModeHeight); | 373 s_lengthModeMap.set(SVGNames::refYAttr, LengthModeHeight); |
423 s_lengthModeMap.set(SVGNames::markerWidthAttr, LengthModeWidth); | 374 s_lengthModeMap.set(SVGNames::markerWidthAttr, LengthModeWidth); |
424 s_lengthModeMap.set(SVGNames::markerHeightAttr, LengthModeHeight); | 375 s_lengthModeMap.set(SVGNames::markerHeightAttr, LengthModeHeight); |
425 s_lengthModeMap.set(SVGNames::textLengthAttr, LengthModeWidth); | 376 s_lengthModeMap.set(SVGNames::textLengthAttr, LengthModeWidth); |
426 s_lengthModeMap.set(SVGNames::startOffsetAttr, LengthModeWidth); | 377 s_lengthModeMap.set(SVGNames::startOffsetAttr, LengthModeWidth); |
427 } | 378 } |
428 | 379 |
429 if (s_lengthModeMap.contains(attrName)) | 380 if (s_lengthModeMap.contains(attrName)) |
430 return s_lengthModeMap.get(attrName); | 381 return s_lengthModeMap.get(attrName); |
431 | 382 |
432 return LengthModeOther; | 383 return LengthModeOther; |
433 } | 384 } |
434 | 385 |
| 386 PassRefPtr<SVGLength> SVGLength::blend(PassRefPtr<SVGLength> passFrom, float pro
gress) const |
| 387 { |
| 388 RefPtr<SVGLength> from = passFrom; |
| 389 |
| 390 SVGLengthType toType = unitType(); |
| 391 SVGLengthType fromType = from->unitType(); |
| 392 if ((from->isZero() && isZero()) |
| 393 || fromType == LengthTypeUnknown |
| 394 || toType == LengthTypeUnknown |
| 395 || (!from->isZero() && fromType != LengthTypePercentage && toType == Len
gthTypePercentage) |
| 396 || (!isZero() && fromType == LengthTypePercentage && toType != LengthTyp
ePercentage) |
| 397 || (!from->isZero() && !isZero() && (fromType == LengthTypeEMS || fromTy
pe == LengthTypeEXS) && fromType != toType)) |
| 398 return clone(); |
| 399 |
| 400 RefPtr<SVGLength> length = create(); |
| 401 |
| 402 if (fromType == LengthTypePercentage || toType == LengthTypePercentage) { |
| 403 float fromPercent = from->valueAsPercentage() * 100; |
| 404 float toPercent = valueAsPercentage() * 100; |
| 405 length->newValueSpecifiedUnits(LengthTypePercentage, WebCore::blend(from
Percent, toPercent, progress)); |
| 406 return length; |
| 407 } |
| 408 |
| 409 if (fromType == toType || from->isZero() || isZero() || fromType == LengthTy
peEMS || fromType == LengthTypeEXS) { |
| 410 float fromValue = from->valueInSpecifiedUnits(); |
| 411 float toValue = valueInSpecifiedUnits(); |
| 412 if (isZero()) |
| 413 length->newValueSpecifiedUnits(fromType, WebCore::blend(fromValue, t
oValue, progress)); |
| 414 else |
| 415 length->newValueSpecifiedUnits(toType, WebCore::blend(fromValue, toV
alue, progress)); |
| 416 return length; |
| 417 } |
| 418 |
| 419 ASSERT(!isRelative()); |
| 420 ASSERT(!from->isRelative()); |
| 421 |
| 422 TrackExceptionState es; |
| 423 SVGLengthContext nonRelativeLengthContext(0); |
| 424 float fromValueInUserUnits = nonRelativeLengthContext.convertValueToUserUnit
s(from->valueInSpecifiedUnits(), from->unitMode(), fromType, es); |
| 425 if (es.hadException()) |
| 426 return create(); |
| 427 |
| 428 float fromValue = nonRelativeLengthContext.convertValueFromUserUnits(fromVal
ueInUserUnits, unitMode(), toType, es); |
| 429 if (es.hadException()) |
| 430 return create(); |
| 431 |
| 432 float toValue = valueInSpecifiedUnits(); |
| 433 length->newValueSpecifiedUnits(toType, WebCore::blend(fromValue, toValue, pr
ogress)); |
| 434 return length; |
435 } | 435 } |
| 436 |
| 437 void SVGLength::add(PassRefPtr<NewSVGPropertyBase> other, SVGElement* contextEle
ment) |
| 438 { |
| 439 SVGLengthContext lengthContext(contextElement); |
| 440 |
| 441 setValue(value(lengthContext) + toSVGLength(other)->value(lengthContext), le
ngthContext, ASSERT_NO_EXCEPTION); |
| 442 } |
| 443 |
| 444 void SVGLength::calculateAnimatedValue(SVGAnimationElement* animationElement, fl
oat percentage, unsigned repeatCount, PassRefPtr<NewSVGPropertyBase> fromValue,
PassRefPtr<NewSVGPropertyBase> toValue, PassRefPtr<NewSVGPropertyBase> toAtEndOf
DurationValue, SVGElement* contextElement) |
| 445 { |
| 446 RefPtr<SVGLength> fromLength = toSVGLength(fromValue); |
| 447 RefPtr<SVGLength> toLength = toSVGLength(toValue); |
| 448 RefPtr<SVGLength> toAtEndOfDurationLength = toSVGLength(toAtEndOfDurationVal
ue); |
| 449 |
| 450 SVGLengthContext lengthContext(contextElement); |
| 451 float animatedNumber = value(lengthContext, IGNORE_EXCEPTION); |
| 452 animationElement->animateAdditiveNumber(percentage, repeatCount, fromLength-
>value(lengthContext, IGNORE_EXCEPTION), toLength->value(lengthContext, IGNORE_E
XCEPTION), toAtEndOfDurationLength->value(lengthContext, IGNORE_EXCEPTION), anim
atedNumber); |
| 453 |
| 454 ASSERT(unitMode() == lengthModeForAnimatedLengthAttribute(animationElement->
attributeName())); |
| 455 m_unitType = percentage < 0.5 ? fromLength->unitType() : toLength->unitType(
); |
| 456 setValue(animatedNumber, lengthContext, ASSERT_NO_EXCEPTION); |
| 457 } |
| 458 |
| 459 float SVGLength::calculateDistance(PassRefPtr<NewSVGPropertyBase> toValue, SVGEl
ement* contextElement) |
| 460 { |
| 461 SVGLengthContext lengthContext(contextElement); |
| 462 RefPtr<SVGLength> toLength = toSVGLength(toValue); |
| 463 |
| 464 return fabsf(toLength->value(lengthContext, IGNORE_EXCEPTION) - value(length
Context, IGNORE_EXCEPTION)); |
| 465 } |
| 466 |
| 467 } |
OLD | NEW |