Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: Source/core/svg/SVGLength.cpp

Issue 112003003: [SVG] SVGLength{,List} migration to new SVG property impl. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: revert aggressive svgAttributeChanged, add NeedsRebaseline Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/svg/SVGLength.h ('k') | Source/core/svg/SVGLength.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « Source/core/svg/SVGLength.h ('k') | Source/core/svg/SVGLength.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698