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