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

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: rebaselined Created 7 years 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
4 * Copyright (C) 2007 Apple Inc. All rights reserved.
5 * 3 *
6 * This library is free software; you can redistribute it and/or 4 * Redistribution and use in source and binary forms, with or without
7 * modify it under the terms of the GNU Library General Public 5 * modification, are permitted provided that the following conditions are
8 * License as published by the Free Software Foundation; either 6 * met:
9 * version 2 of the License, or (at your option) any later version.
10 * 7 *
11 * This library is distributed in the hope that it will be useful, 8 * * Redistributions of source code must retain the above copyright
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * notice, this list of conditions and the following disclaimer.
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 * * Redistributions in binary form must reproduce the above
14 * Library General Public License for more details. 11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
15 * 17 *
16 * You should have received a copy of the GNU Library General Public License 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * along with this library; see the file COPYING.LIB. If not, write to 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * Boston, MA 02110-1301, USA. 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 */ 29 */
21 30
22 #include "config.h" 31 #include "config.h"
23 32
24 #include "core/svg/SVGLength.h" 33 #include "core/svg/SVGLength.h"
25 34
26 #include "SVGNames.h" 35 #include "SVGNames.h"
27 #include "bindings/v8/ExceptionStatePlaceholder.h" 36 #include "bindings/v8/ExceptionState.h"
28 #include "core/css/CSSPrimitiveValue.h" 37 #include "core/css/CSSPrimitiveValue.h"
29 #include "core/dom/ExceptionCode.h" 38 #include "core/dom/ExceptionCode.h"
39 #include "core/svg/SVGAnimationElement.h"
30 #include "core/svg/SVGParserUtilities.h" 40 #include "core/svg/SVGParserUtilities.h"
41 #include "platform/animation/AnimationUtilities.h"
31 #include "wtf/MathExtras.h" 42 #include "wtf/MathExtras.h"
32 #include "wtf/text/WTFString.h" 43 #include "wtf/text/WTFString.h"
33 44
34 namespace WebCore { 45 namespace WebCore {
35 46
36 static inline SVGLengthMode toSVGLengthMode(unsigned short mode) 47 namespace {
48
49 inline SVGLengthMode toSVGLengthMode(unsigned short mode)
37 { 50 {
38 ASSERT(mode >= LengthModeWidth && mode <= LengthModeOther); 51 ASSERT(mode >= LengthModeWidth && mode <= LengthModeOther);
39 return static_cast<SVGLengthMode>(mode); 52 return static_cast<SVGLengthMode>(mode);
40 } 53 }
41 54
42 static inline SVGLengthType toSVGLengthType(unsigned short type) 55 inline SVGLengthType toSVGLengthType(unsigned short type)
43 { 56 {
44 ASSERT(type >= LengthTypeUnknown && type <= LengthTypePC); 57 ASSERT(type >= LengthTypeUnknown && type <= LengthTypePC);
45 return static_cast<SVGLengthType>(type); 58 return static_cast<SVGLengthType>(type);
46 } 59 }
47 60
48 static inline unsigned int storeUnit(SVGLengthMode mode, SVGLengthType type) 61 inline String lengthTypeToString(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 { 62 {
68 switch (type) { 63 switch (type) {
69 case LengthTypeUnknown: 64 case LengthTypeUnknown:
70 case LengthTypeNumber: 65 case LengthTypeNumber:
71 return ""; 66 return "";
72 case LengthTypePercentage: 67 case LengthTypePercentage:
73 return "%"; 68 return "%";
74 case LengthTypeEMS: 69 case LengthTypeEMS:
75 return "em"; 70 return "em";
76 case LengthTypeEXS: 71 case LengthTypeEXS:
(...skipping 10 matching lines...) Expand all
87 return "pt"; 82 return "pt";
88 case LengthTypePC: 83 case LengthTypePC:
89 return "pc"; 84 return "pc";
90 } 85 }
91 86
92 ASSERT_NOT_REACHED(); 87 ASSERT_NOT_REACHED();
93 return String(); 88 return String();
94 } 89 }
95 90
96 template<typename CharType> 91 template<typename CharType>
97 static SVGLengthType stringToLengthType(const CharType*& ptr, const CharType* en d) 92 SVGLengthType stringToLengthType(const CharType*& ptr, const CharType* end)
98 { 93 {
99 if (ptr == end) 94 if (ptr == end)
100 return LengthTypeNumber; 95 return LengthTypeNumber;
101 96
102 const UChar firstChar = *ptr; 97 const UChar firstChar = *ptr;
103 98
104 if (++ptr == end) 99 if (++ptr == end)
105 return firstChar == '%' ? LengthTypePercentage : LengthTypeUnknown; 100 return firstChar == '%' ? LengthTypePercentage : LengthTypeUnknown;
106 101
107 const UChar secondChar = *ptr; 102 const UChar secondChar = *ptr;
(...skipping 14 matching lines...) Expand all
122 if (firstChar == 'i' && secondChar == 'n') 117 if (firstChar == 'i' && secondChar == 'n')
123 return LengthTypeIN; 118 return LengthTypeIN;
124 if (firstChar == 'p' && secondChar == 't') 119 if (firstChar == 'p' && secondChar == 't')
125 return LengthTypePT; 120 return LengthTypePT;
126 if (firstChar == 'p' && secondChar == 'c') 121 if (firstChar == 'p' && secondChar == 'c')
127 return LengthTypePC; 122 return LengthTypePC;
128 123
129 return LengthTypeUnknown; 124 return LengthTypeUnknown;
130 } 125 }
131 126
132 SVGLength::SVGLength(SVGLengthMode mode, const String& valueAsString) 127 } // namespace
128
129 SVGLength::SVGLength(SVGLengthMode mode)
133 : m_valueInSpecifiedUnits(0) 130 : m_valueInSpecifiedUnits(0)
134 , m_unit(storeUnit(mode, LengthTypeNumber)) 131 , m_unitMode(mode)
135 { 132 , m_unitType(LengthTypeNumber)
136 setValueAsString(valueAsString, IGNORE_EXCEPTION);
137 }
138
139 SVGLength::SVGLength(const SVGLengthContext& context, float value, SVGLengthMode mode, SVGLengthType unitType)
140 : m_valueInSpecifiedUnits(0)
141 , m_unit(storeUnit(mode, unitType))
142 {
143 setValue(value, context, ASSERT_NO_EXCEPTION);
144 }
145
146 SVGLength::SVGLength(const SVGLength& other)
147 : m_valueInSpecifiedUnits(other.m_valueInSpecifiedUnits)
148 , m_unit(other.m_unit)
149 { 133 {
150 } 134 }
151 135
152 void SVGLength::setValueAsString(const String& valueAsString, SVGLengthMode mode , ExceptionState& exceptionState) 136 PassRefPtr<SVGLength> SVGLength::clone() const
153 { 137 {
154 m_valueInSpecifiedUnits = 0; 138 RefPtr<SVGLength> length = create();
pdr. 2014/01/07 06:42:53 This function may be hot on performance. It could
kouhei (in TOK) 2014/01/08 08:12:07 Done.
155 m_unit = storeUnit(mode, LengthTypeNumber); 139
156 setValueAsString(valueAsString, exceptionState); 140 length->m_valueInSpecifiedUnits = m_valueInSpecifiedUnits;
141 length->m_unitMode = m_unitMode;
142 length->m_unitType = m_unitType;
143
144 return length.release();
145 }
146
147 PassRefPtr<NewSVGPropertyBase> SVGLength::cloneForAnimation(const String& value) const
148 {
149 RefPtr<SVGLength> length = create();
150
151 length->m_unitMode = m_unitMode;
152 length->m_unitType = m_unitType;
153 length->setValueAsString(value, IGNORE_EXCEPTION);
154
155 return length.release();
157 } 156 }
158 157
159 bool SVGLength::operator==(const SVGLength& other) const 158 bool SVGLength::operator==(const SVGLength& other) const
160 { 159 {
161 return m_unit == other.m_unit 160 return m_unitMode == other.m_unitMode
161 && m_unitType == other.m_unitType
162 && m_valueInSpecifiedUnits == other.m_valueInSpecifiedUnits; 162 && m_valueInSpecifiedUnits == other.m_valueInSpecifiedUnits;
163 } 163 }
164 164
165 bool SVGLength::operator!=(const SVGLength& other) const 165 void SVGLength::setUnitType(SVGLengthType unitType)
166 { 166 {
167 return !operator==(other); 167 ASSERT(unitType != LengthTypeUnknown && unitType <= LengthTypePC);
168 m_unitType = unitType;
168 } 169 }
169 170
170 SVGLength SVGLength::construct(SVGLengthMode mode, const String& valueAsString, SVGParsingError& parseError, SVGLengthNegativeValuesMode negativeValuesMode) 171 float SVGLength::value(const SVGLengthContext& context, ExceptionState& es) cons t
171 { 172 {
172 TrackExceptionState exceptionState; 173 return context.convertValueToUserUnits(m_valueInSpecifiedUnits, unitMode(), unitType(), es);
173 SVGLength length(mode);
174
175 length.setValueAsString(valueAsString, exceptionState);
176
177 if (exceptionState.hadException())
178 parseError = ParsingAttributeFailedError;
179 else if (negativeValuesMode == ForbidNegativeLengths && length.valueInSpecif iedUnits() < 0)
180 parseError = NegativeValueForbiddenError;
181
182 return length;
183 } 174 }
184 175
185 SVGLengthType SVGLength::unitType() const 176 void SVGLength::setValue(float value, const SVGLengthContext& context, Exception State& es)
186 { 177 {
187 return extractType(m_unit); 178 // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed
179 if (m_unitType == LengthTypePercentage)
180 value = value / 100;
181
182 float convertedValue = context.convertValueFromUserUnits(value, unitMode(), unitType(), es);
183 if (es.hadException())
184 return;
185
186 m_valueInSpecifiedUnits = convertedValue;
188 } 187 }
189 188
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 189 float SVGLength::valueAsPercentage() const
222 { 190 {
223 // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed 191 // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed
224 if (extractType(m_unit) == LengthTypePercentage) 192 if (m_unitType == LengthTypePercentage)
225 return m_valueInSpecifiedUnits / 100; 193 return m_valueInSpecifiedUnits / 100;
226 194
227 return m_valueInSpecifiedUnits; 195 return m_valueInSpecifiedUnits;
228 } 196 }
229 197
230 template<typename CharType> 198 template<typename CharType>
231 static bool parseValueInternal(const String& string, float& convertedNumber, SVG LengthType& type) 199 static bool parseValueInternal(const String& string, float& convertedNumber, SVG LengthType& type)
232 { 200 {
233 const CharType* ptr = string.getCharacters<CharType>(); 201 const CharType* ptr = string.getCharacters<CharType>();
234 const CharType* end = ptr + string.length(); 202 const CharType* end = ptr + string.length();
235 203
236 if (!parseNumber(ptr, end, convertedNumber, false)) 204 if (!parseNumber(ptr, end, convertedNumber, false))
237 return false; 205 return false;
238 206
239 type = stringToLengthType(ptr, end); 207 type = stringToLengthType(ptr, end);
240 ASSERT(ptr <= end); 208 ASSERT(ptr <= end);
241 if (type == LengthTypeUnknown) 209 if (type == LengthTypeUnknown)
242 return false; 210 return false;
243 211
244 return true; 212 return true;
245 } 213 }
246 214
247 void SVGLength::setValueAsString(const String& string, ExceptionState& exception State) 215 void SVGLength::setValueAsString(const String& string, ExceptionState& es)
248 { 216 {
249 if (string.isEmpty()) 217 if (string.isEmpty()) {
218 m_unitType = LengthTypeUnknown;
219 m_valueInSpecifiedUnits = 0;
250 return; 220 return;
221 }
251 222
252 float convertedNumber = 0; 223 float convertedNumber = 0;
253 SVGLengthType type = LengthTypeUnknown; 224 SVGLengthType type = LengthTypeUnknown;
254 225
255 bool success = string.is8Bit() ? 226 bool success = string.is8Bit() ?
256 parseValueInternal<LChar>(string, convertedNumber, type) : 227 parseValueInternal<LChar>(string, convertedNumber, type) :
257 parseValueInternal<UChar>(string, convertedNumber, type); 228 parseValueInternal<UChar>(string, convertedNumber, type);
258 229
259 if (!success) { 230 if (!success) {
260 exceptionState.throwUninformativeAndGenericDOMException(SyntaxError); 231 m_valueInSpecifiedUnits = 0;
232 es.throwDOMException(SyntaxError, "Invalid value");
261 return; 233 return;
262 } 234 }
263 235
264 m_unit = storeUnit(extractMode(m_unit), type); 236 m_unitType = type;
265 m_valueInSpecifiedUnits = convertedNumber; 237 m_valueInSpecifiedUnits = convertedNumber;
266 } 238 }
267 239
268 String SVGLength::valueAsString() const 240 String SVGLength::valueAsString() const
269 { 241 {
270 return String::number(m_valueInSpecifiedUnits) + lengthTypeToString(extractT ype(m_unit)); 242 return String::number(m_valueInSpecifiedUnits) + lengthTypeToString(unitType ());
271 } 243 }
272 244
273 void SVGLength::newValueSpecifiedUnits(unsigned short type, float value, Excepti onState& exceptionState) 245 void SVGLength::newValueSpecifiedUnits(SVGLengthType type, float value)
274 { 246 {
275 if (type == LengthTypeUnknown || type > LengthTypePC) { 247 m_unitType = type;
276 exceptionState.throwUninformativeAndGenericDOMException(NotSupportedErro r);
277 return;
278 }
279
280 m_unit = storeUnit(extractMode(m_unit), toSVGLengthType(type));
281 m_valueInSpecifiedUnits = value; 248 m_valueInSpecifiedUnits = value;
282 } 249 }
283 250
284 void SVGLength::convertToSpecifiedUnits(unsigned short type, const SVGLengthCont ext& context, ExceptionState& exceptionState) 251 void SVGLength::convertToSpecifiedUnits(SVGLengthType type, const SVGLengthConte xt& context, ExceptionState& es)
285 { 252 {
286 if (type == LengthTypeUnknown || type > LengthTypePC) { 253 float valueInUserUnits = value(context, es);
287 exceptionState.throwUninformativeAndGenericDOMException(NotSupportedErro r); 254 if (es.hadException())
288 return;
289 }
290
291 float valueInUserUnits = value(context, exceptionState);
292 if (exceptionState.hadException())
293 return; 255 return;
294 256
295 unsigned int originalUnitAndType = m_unit; 257 SVGLengthType originalType = unitType();
296 m_unit = storeUnit(extractMode(m_unit), toSVGLengthType(type)); 258 m_unitType = toSVGLengthType(type);
297 setValue(valueInUserUnits, context, exceptionState); 259 setValue(valueInUserUnits, context, es);
298 if (!exceptionState.hadException()) 260 if (!es.hadException())
299 return; 261 return;
300 262
301 // Eventually restore old unit and type 263 // Eventually restore old type
302 m_unit = originalUnitAndType; 264 m_unitType = originalType;
303 } 265 }
304 266
305 SVGLength SVGLength::fromCSSPrimitiveValue(CSSPrimitiveValue* value) 267 PassRefPtr<SVGLength> SVGLength::fromCSSPrimitiveValue(CSSPrimitiveValue* value)
306 { 268 {
307 ASSERT(value); 269 ASSERT(value);
308 270
309 SVGLengthType svgType; 271 SVGLengthType svgType;
310 switch (value->primitiveType()) { 272 switch (value->primitiveType()) {
311 case CSSPrimitiveValue::CSS_NUMBER: 273 case CSSPrimitiveValue::CSS_NUMBER:
312 svgType = LengthTypeNumber; 274 svgType = LengthTypeNumber;
313 break; 275 break;
314 case CSSPrimitiveValue::CSS_PERCENTAGE: 276 case CSSPrimitiveValue::CSS_PERCENTAGE:
315 svgType = LengthTypePercentage; 277 svgType = LengthTypePercentage;
(...skipping 22 matching lines...) Expand all
338 case CSSPrimitiveValue::CSS_PC: 300 case CSSPrimitiveValue::CSS_PC:
339 svgType = LengthTypePC; 301 svgType = LengthTypePC;
340 break; 302 break;
341 case CSSPrimitiveValue::CSS_UNKNOWN: 303 case CSSPrimitiveValue::CSS_UNKNOWN:
342 default: 304 default:
343 svgType = LengthTypeUnknown; 305 svgType = LengthTypeUnknown;
344 break; 306 break;
345 }; 307 };
346 308
347 if (svgType == LengthTypeUnknown) 309 if (svgType == LengthTypeUnknown)
348 return SVGLength(); 310 return SVGLength::create();
349 311
350 TrackExceptionState exceptionState; 312 RefPtr<SVGLength> length = SVGLength::create();
351 SVGLength length; 313 length->newValueSpecifiedUnits(svgType, value->getFloatValue());
352 length.newValueSpecifiedUnits(svgType, value->getFloatValue(), exceptionStat e);
353 if (exceptionState.hadException())
354 return SVGLength();
355
356 return length; 314 return length;
357 } 315 }
358 316
359 PassRefPtr<CSSPrimitiveValue> SVGLength::toCSSPrimitiveValue(const SVGLength& le ngth) 317 PassRefPtr<CSSPrimitiveValue> SVGLength::toCSSPrimitiveValue(PassRefPtr<SVGLengt h> passLength)
360 { 318 {
319 RefPtr<SVGLength> length = passLength;
320
361 CSSPrimitiveValue::UnitTypes cssType = CSSPrimitiveValue::CSS_UNKNOWN; 321 CSSPrimitiveValue::UnitTypes cssType = CSSPrimitiveValue::CSS_UNKNOWN;
362 switch (length.unitType()) { 322 switch (length->unitType()) {
363 case LengthTypeUnknown: 323 case LengthTypeUnknown:
364 break; 324 break;
365 case LengthTypeNumber: 325 case LengthTypeNumber:
366 cssType = CSSPrimitiveValue::CSS_NUMBER; 326 cssType = CSSPrimitiveValue::CSS_NUMBER;
367 break; 327 break;
368 case LengthTypePercentage: 328 case LengthTypePercentage:
369 cssType = CSSPrimitiveValue::CSS_PERCENTAGE; 329 cssType = CSSPrimitiveValue::CSS_PERCENTAGE;
370 break; 330 break;
371 case LengthTypeEMS: 331 case LengthTypeEMS:
372 cssType = CSSPrimitiveValue::CSS_EMS; 332 cssType = CSSPrimitiveValue::CSS_EMS;
(...skipping 14 matching lines...) Expand all
387 cssType = CSSPrimitiveValue::CSS_IN; 347 cssType = CSSPrimitiveValue::CSS_IN;
388 break; 348 break;
389 case LengthTypePT: 349 case LengthTypePT:
390 cssType = CSSPrimitiveValue::CSS_PT; 350 cssType = CSSPrimitiveValue::CSS_PT;
391 break; 351 break;
392 case LengthTypePC: 352 case LengthTypePC:
393 cssType = CSSPrimitiveValue::CSS_PC; 353 cssType = CSSPrimitiveValue::CSS_PC;
394 break; 354 break;
395 }; 355 };
396 356
397 return CSSPrimitiveValue::create(length.valueInSpecifiedUnits(), cssType); 357 return CSSPrimitiveValue::create(length->valueInSpecifiedUnits(), cssType);
398 } 358 }
399 359
400 SVGLengthMode SVGLength::lengthModeForAnimatedLengthAttribute(const QualifiedNam e& attrName) 360 SVGLengthMode SVGLength::lengthModeForAnimatedLengthAttribute(const QualifiedNam e& attrName)
401 { 361 {
402 typedef HashMap<QualifiedName, SVGLengthMode> LengthModeForLengthAttributeMa p; 362 typedef HashMap<QualifiedName, SVGLengthMode> LengthModeForLengthAttributeMa p;
403 DEFINE_STATIC_LOCAL(LengthModeForLengthAttributeMap, s_lengthModeMap, ()); 363 DEFINE_STATIC_LOCAL(LengthModeForLengthAttributeMap, s_lengthModeMap, ());
404 364
405 if (s_lengthModeMap.isEmpty()) { 365 if (s_lengthModeMap.isEmpty()) {
406 s_lengthModeMap.set(SVGNames::xAttr, LengthModeWidth); 366 s_lengthModeMap.set(SVGNames::xAttr, LengthModeWidth);
407 s_lengthModeMap.set(SVGNames::yAttr, LengthModeHeight); 367 s_lengthModeMap.set(SVGNames::yAttr, LengthModeHeight);
408 s_lengthModeMap.set(SVGNames::cxAttr, LengthModeWidth); 368 s_lengthModeMap.set(SVGNames::cxAttr, LengthModeWidth);
409 s_lengthModeMap.set(SVGNames::cyAttr, LengthModeHeight); 369 s_lengthModeMap.set(SVGNames::cyAttr, LengthModeHeight);
410 s_lengthModeMap.set(SVGNames::dxAttr, LengthModeWidth); 370 s_lengthModeMap.set(SVGNames::dxAttr, LengthModeWidth);
411 s_lengthModeMap.set(SVGNames::dyAttr, LengthModeHeight); 371 s_lengthModeMap.set(SVGNames::dyAttr, LengthModeHeight);
412 s_lengthModeMap.set(SVGNames::fxAttr, LengthModeWidth); 372 s_lengthModeMap.set(SVGNames::fxAttr, LengthModeWidth);
413 s_lengthModeMap.set(SVGNames::fyAttr, LengthModeHeight); 373 s_lengthModeMap.set(SVGNames::fyAttr, LengthModeHeight);
414 s_lengthModeMap.set(SVGNames::rAttr, LengthModeOther); 374 s_lengthModeMap.set(SVGNames::rAttr, LengthModeOther);
375 s_lengthModeMap.set(SVGNames::rxAttr, LengthModeWidth);
376 s_lengthModeMap.set(SVGNames::ryAttr, LengthModeHeight);
415 s_lengthModeMap.set(SVGNames::widthAttr, LengthModeWidth); 377 s_lengthModeMap.set(SVGNames::widthAttr, LengthModeWidth);
416 s_lengthModeMap.set(SVGNames::heightAttr, LengthModeHeight); 378 s_lengthModeMap.set(SVGNames::heightAttr, LengthModeHeight);
417 s_lengthModeMap.set(SVGNames::x1Attr, LengthModeWidth); 379 s_lengthModeMap.set(SVGNames::x1Attr, LengthModeWidth);
418 s_lengthModeMap.set(SVGNames::x2Attr, LengthModeWidth); 380 s_lengthModeMap.set(SVGNames::x2Attr, LengthModeWidth);
419 s_lengthModeMap.set(SVGNames::y1Attr, LengthModeHeight); 381 s_lengthModeMap.set(SVGNames::y1Attr, LengthModeHeight);
420 s_lengthModeMap.set(SVGNames::y2Attr, LengthModeHeight); 382 s_lengthModeMap.set(SVGNames::y2Attr, LengthModeHeight);
421 s_lengthModeMap.set(SVGNames::refXAttr, LengthModeWidth); 383 s_lengthModeMap.set(SVGNames::refXAttr, LengthModeWidth);
422 s_lengthModeMap.set(SVGNames::refYAttr, LengthModeHeight); 384 s_lengthModeMap.set(SVGNames::refYAttr, LengthModeHeight);
423 s_lengthModeMap.set(SVGNames::markerWidthAttr, LengthModeWidth); 385 s_lengthModeMap.set(SVGNames::markerWidthAttr, LengthModeWidth);
424 s_lengthModeMap.set(SVGNames::markerHeightAttr, LengthModeHeight); 386 s_lengthModeMap.set(SVGNames::markerHeightAttr, LengthModeHeight);
425 s_lengthModeMap.set(SVGNames::textLengthAttr, LengthModeWidth); 387 s_lengthModeMap.set(SVGNames::textLengthAttr, LengthModeWidth);
426 s_lengthModeMap.set(SVGNames::startOffsetAttr, LengthModeWidth); 388 s_lengthModeMap.set(SVGNames::startOffsetAttr, LengthModeWidth);
427 } 389 }
428 390
429 if (s_lengthModeMap.contains(attrName)) 391 if (s_lengthModeMap.contains(attrName))
430 return s_lengthModeMap.get(attrName); 392 return s_lengthModeMap.get(attrName);
431 393
432 return LengthModeOther; 394 return LengthModeOther;
433 } 395 }
434 396
397 PassRefPtr<SVGLength> SVGLength::blend(const SVGLength* from, float progress) co nst
398 {
399 SVGLengthType toType = unitType();
400 SVGLengthType fromType = from->unitType();
401 if ((from->isZero() && isZero())
402 || fromType == LengthTypeUnknown
403 || toType == LengthTypeUnknown
404 || (!from->isZero() && fromType != LengthTypePercentage && toType == Len gthTypePercentage)
405 || (!isZero() && fromType == LengthTypePercentage && toType != LengthTyp ePercentage)
406 || (!from->isZero() && !isZero() && (fromType == LengthTypeEMS || fromTy pe == LengthTypeEXS) && fromType != toType))
407 return clone();
408
409 RefPtr<SVGLength> length = create();
410
411 if (fromType == LengthTypePercentage || toType == LengthTypePercentage) {
412 float fromPercent = from->valueAsPercentage() * 100;
413 float toPercent = valueAsPercentage() * 100;
414 length->newValueSpecifiedUnits(LengthTypePercentage, WebCore::blend(from Percent, toPercent, progress));
415 return length;
416 }
417
418 if (fromType == toType || from->isZero() || isZero() || fromType == LengthTy peEMS || fromType == LengthTypeEXS) {
419 float fromValue = from->valueInSpecifiedUnits();
420 float toValue = valueInSpecifiedUnits();
421 if (isZero())
422 length->newValueSpecifiedUnits(fromType, WebCore::blend(fromValue, t oValue, progress));
423 else
424 length->newValueSpecifiedUnits(toType, WebCore::blend(fromValue, toV alue, progress));
425 return length;
426 }
427
428 ASSERT(!isRelative());
429 ASSERT(!from->isRelative());
430
431 TrackExceptionState es;
432 SVGLengthContext nonRelativeLengthContext(0);
433 float fromValueInUserUnits = nonRelativeLengthContext.convertValueToUserUnit s(from->valueInSpecifiedUnits(), from->unitMode(), fromType, es);
434 if (es.hadException())
435 return create();
436
437 float fromValue = nonRelativeLengthContext.convertValueFromUserUnits(fromVal ueInUserUnits, unitMode(), toType, es);
438 if (es.hadException())
439 return create();
440
441 float toValue = valueInSpecifiedUnits();
442 length->newValueSpecifiedUnits(toType, WebCore::blend(fromValue, toValue, pr ogress));
443 return length;
435 } 444 }
445
446 void SVGLength::add(PassRefPtr<NewSVGPropertyBase> other, SVGElement* contextEle ment)
447 {
448 SVGLengthContext lengthContext(contextElement);
449
450 SVGLength* otherLength = toSVGLength(other.get());
451
452 setValue(value(lengthContext) + otherLength->value(lengthContext), lengthCon text, ASSERT_NO_EXCEPTION);
453 }
454
455 void SVGLength::calculateAnimatedValue(SVGAnimationElement* animationElement, fl oat percentage, unsigned repeatCount, PassRefPtr<NewSVGPropertyBase> fromValue, PassRefPtr<NewSVGPropertyBase> toValue, PassRefPtr<NewSVGPropertyBase> toAtEndOf DurationValue, SVGElement* contextElement)
456 {
457 SVGLengthContext lengthContext(contextElement);
458 const SVGLength* fromLength = toSVGLength(fromValue.get());
459 const SVGLength* toLength = toSVGLength(toValue.get());
460 const SVGLength* toAtEndOfDurationLength = toSVGLength(toAtEndOfDurationValu e.get());
461 float animatedNumber = value(lengthContext, IGNORE_EXCEPTION);
462 SVGLengthType unitType = percentage < 0.5 ? fromLength->unitType() : toLengt h->unitType();
463 animationElement->animateAdditiveNumber(percentage, repeatCount, fromLength- >value(lengthContext, IGNORE_EXCEPTION), toLength->value(lengthContext, IGNORE_E XCEPTION), toAtEndOfDurationLength->value(lengthContext, IGNORE_EXCEPTION), anim atedNumber);
464 ASSERT(unitMode() == SVGLength::lengthModeForAnimatedLengthAttribute(animati onElement->attributeName()));
465
466 setUnitType(unitType);
467 setValue(animatedNumber, lengthContext, ASSERT_NO_EXCEPTION);
468 }
469
470 float SVGLength::calculateDistance(PassRefPtr<NewSVGPropertyBase> to, SVGElement * contextElement)
471 {
472 SVGLengthContext lengthContext(contextElement);
473 const SVGLength* toLength = toSVGLength(to.get());
474
475 return fabsf(toLength->value(lengthContext, IGNORE_EXCEPTION) - value(length Context, IGNORE_EXCEPTION));
476 }
477
478 SVGLengthType SVGLengthTearOff::unitType()
479 {
480 return target()->unitType();
481 }
482
483 SVGLengthMode SVGLengthTearOff::unitMode()
484 {
485 return target()->unitMode();
486 }
487
488 float SVGLengthTearOff::value(ExceptionState& es)
489 {
490 SVGLengthContext lengthContext(contextElement());
491 return target()->value(lengthContext, es);
492 }
493
494 void SVGLengthTearOff::setValue(float value, ExceptionState& es)
495 {
496 if (isImmutable()) {
497 es.throwDOMException(NoModificationAllowedError, ExceptionMessages::fail edToSet("value", "SVGLength", "The attribute is read-only."));
498 return;
499 }
500
501 SVGLengthContext lengthContext(contextElement());
502 target()->setValue(value, lengthContext, es);
503 commitChange();
504 }
505
506 float SVGLengthTearOff::valueInSpecifiedUnits()
507 {
508 return target()->valueInSpecifiedUnits();
509 }
510
511 void SVGLengthTearOff::setValueInSpecifiedUnits(float value, ExceptionState& es)
512 {
513 if (isImmutable()) {
514 es.throwDOMException(NoModificationAllowedError, ExceptionMessages::fail edToSet("valueInSpecifiedUnits", "SVGLength", "The attribute is read-only."));
515 return;
516 }
517 target()->setValueInSpecifiedUnits(value);
518 commitChange();
519 }
520
521 String SVGLengthTearOff::valueAsString()
522 {
523 return target()->valueAsString();
524 }
525
526 void SVGLengthTearOff::setValueAsString(const String& str, ExceptionState& es)
527 {
528 if (isImmutable()) {
529 es.throwDOMException(NoModificationAllowedError, ExceptionMessages::fail edToSet("valueAsString", "SVGLength", "The attribute is read-only."));
530 return;
531 }
532
533 target()->setValueAsString(str, es);
534 commitChange();
535 }
536
537 void SVGLengthTearOff::newValueSpecifiedUnits(unsigned short unitType, float val ueInSpecifiedUnits, ExceptionState& es)
538 {
539 if (isImmutable()) {
540 es.throwDOMException(NoModificationAllowedError, ExceptionMessages::fail edToSet("newValueSpecifiedUnits", "SVGLength", "The object is read-only."));
541 return;
542 }
543
544 if (unitType == LengthTypeUnknown || unitType > LengthTypePC) {
545 es.throwDOMException(NoModificationAllowedError, ExceptionMessages::fail edToSet("newValueSpecifiedUnits", "SVGLength", "The specified SVGLengthMode is i nvalid."));
546 return;
547 }
548
549 target()->newValueSpecifiedUnits(toSVGLengthType(unitType), valueInSpecified Units);
550 commitChange();
551 }
552
553 void SVGLengthTearOff::convertToSpecifiedUnits(unsigned short unitType, Exceptio nState& es)
554 {
555 if (isImmutable()) {
556 es.throwDOMException(NoModificationAllowedError, ExceptionMessages::fail edToSet("convertToSpecifiedUnits", "SVGLength", "The object is read-only."));
557 return;
558 }
559
560 if (unitType == LengthTypeUnknown || unitType > LengthTypePC) {
561 es.throwDOMException(NoModificationAllowedError, ExceptionMessages::fail edToSet("convertToSpecifiedUnits", "SVGLength", "The specified SVGLengthMode is invalid."));
562 return;
563 }
564
565 SVGLengthContext lengthContext(contextElement());
566 target()->convertToSpecifiedUnits(toSVGLengthType(unitType), lengthContext, es);
567 commitChange();
568 }
569
570 SVGLengthTearOff::SVGLengthTearOff(PassRefPtr<SVGLength> target, SVGElement* con textElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attri buteName)
571 : NewSVGPropertyTearOff<SVGLength>(target, contextElement, propertyIsAnimVal , attributeName)
572 {
573 ScriptWrappable::init(this);
574 }
575
576 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698