OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } | |
OLD | NEW |