1/* 2 * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> 3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21#ifndef SVGLength_h 22#define SVGLength_h 23 24#if ENABLE(SVG) 25#include "AnimationUtilities.h" 26#include "SVGLengthContext.h" 27#include "SVGParsingError.h" 28#include "SVGPropertyTraits.h" 29 30namespace WebCore { 31 32class CSSPrimitiveValue; 33class QualifiedName; 34 35typedef int ExceptionCode; 36 37enum SVGLengthNegativeValuesMode { 38 AllowNegativeLengths, 39 ForbidNegativeLengths 40}; 41 42class SVGLength { 43 WTF_MAKE_FAST_ALLOCATED; 44public: 45 // Forward declare these enums in the w3c naming scheme, for IDL generation 46 enum { 47 SVG_LENGTHTYPE_UNKNOWN = LengthTypeUnknown, 48 SVG_LENGTHTYPE_NUMBER = LengthTypeNumber, 49 SVG_LENGTHTYPE_PERCENTAGE = LengthTypePercentage, 50 SVG_LENGTHTYPE_EMS = LengthTypeEMS, 51 SVG_LENGTHTYPE_EXS = LengthTypeEXS, 52 SVG_LENGTHTYPE_PX = LengthTypePX, 53 SVG_LENGTHTYPE_CM = LengthTypeCM, 54 SVG_LENGTHTYPE_MM = LengthTypeMM, 55 SVG_LENGTHTYPE_IN = LengthTypeIN, 56 SVG_LENGTHTYPE_PT = LengthTypePT, 57 SVG_LENGTHTYPE_PC = LengthTypePC 58 }; 59 60 SVGLength(SVGLengthMode = LengthModeOther, const String& valueAsString = String()); 61 SVGLength(const SVGLengthContext&, float, SVGLengthMode = LengthModeOther, SVGLengthType = LengthTypeNumber); 62 SVGLength(const SVGLength&); 63 64 SVGLengthType unitType() const; 65 SVGLengthMode unitMode() const; 66 67 bool operator==(const SVGLength&) const; 68 bool operator!=(const SVGLength&) const; 69 70 static SVGLength construct(SVGLengthMode, const String&, SVGParsingError&, SVGLengthNegativeValuesMode = AllowNegativeLengths); 71 72 float value(const SVGLengthContext&) const; 73 float value(const SVGLengthContext&, ExceptionCode&) const; 74 void setValue(float, const SVGLengthContext&, ExceptionCode&); 75 void setValue(const SVGLengthContext&, float, SVGLengthMode, SVGLengthType, ExceptionCode&); 76 77 float valueInSpecifiedUnits() const { return m_valueInSpecifiedUnits; } 78 void setValueInSpecifiedUnits(float value) { m_valueInSpecifiedUnits = value; } 79 80 float valueAsPercentage() const; 81 82 String valueAsString() const; 83 void setValueAsString(const String&, ExceptionCode&); 84 void setValueAsString(const String&, SVGLengthMode, ExceptionCode&); 85 86 void newValueSpecifiedUnits(unsigned short, float valueInSpecifiedUnits, ExceptionCode&); 87 void convertToSpecifiedUnits(unsigned short, const SVGLengthContext&, ExceptionCode&); 88 89 // Helper functions 90 inline bool isRelative() const 91 { 92 SVGLengthType type = unitType(); 93 return type == LengthTypePercentage || type == LengthTypeEMS || type == LengthTypeEXS; 94 } 95 96 bool isZero() const 97 { 98 return !m_valueInSpecifiedUnits; 99 } 100 101 static SVGLength fromCSSPrimitiveValue(CSSPrimitiveValue*); 102 static PassRefPtr<CSSPrimitiveValue> toCSSPrimitiveValue(const SVGLength&); 103 static SVGLengthMode lengthModeForAnimatedLengthAttribute(const QualifiedName&); 104 105 SVGLength blend(const SVGLength& from, float progress) const 106 { 107 SVGLengthType toType = unitType(); 108 SVGLengthType fromType = from.unitType(); 109 if ((from.isZero() && isZero()) 110 || fromType == LengthTypeUnknown 111 || toType == LengthTypeUnknown 112 || (!from.isZero() && fromType != LengthTypePercentage && toType == LengthTypePercentage) 113 || (!isZero() && fromType == LengthTypePercentage && toType != LengthTypePercentage) 114 || (!from.isZero() && !isZero() && (fromType == LengthTypeEMS || fromType == LengthTypeEXS) && fromType != toType)) 115 return *this; 116 117 SVGLength length; 118 ExceptionCode ec = 0; 119 120 if (fromType == LengthTypePercentage || toType == LengthTypePercentage) { 121 float fromPercent = from.valueAsPercentage() * 100; 122 float toPercent = valueAsPercentage() * 100; 123 length.newValueSpecifiedUnits(LengthTypePercentage, WebCore::blend(fromPercent, toPercent, progress), ec); 124 if (ec) 125 return SVGLength(); 126 return length; 127 } 128 129 if (fromType == toType || from.isZero() || isZero() || fromType == LengthTypeEMS || fromType == LengthTypeEXS) { 130 float fromValue = from.valueInSpecifiedUnits(); 131 float toValue = valueInSpecifiedUnits(); 132 if (isZero()) 133 length.newValueSpecifiedUnits(fromType, WebCore::blend(fromValue, toValue, progress), ec); 134 else 135 length.newValueSpecifiedUnits(toType, WebCore::blend(fromValue, toValue, progress), ec); 136 if (ec) 137 return SVGLength(); 138 return length; 139 } 140 141 ASSERT(!isRelative()); 142 ASSERT(!from.isRelative()); 143 144 SVGLengthContext nonRelativeLengthContext(0); 145 float fromValueInUserUnits = nonRelativeLengthContext.convertValueToUserUnits(from.valueInSpecifiedUnits(), from.unitMode(), fromType, ec); 146 if (ec) 147 return SVGLength(); 148 149 float fromValue = nonRelativeLengthContext.convertValueFromUserUnits(fromValueInUserUnits, unitMode(), toType, ec); 150 if (ec) 151 return SVGLength(); 152 153 float toValue = valueInSpecifiedUnits(); 154 length.newValueSpecifiedUnits(toType, WebCore::blend(fromValue, toValue, progress), ec); 155 156 if (ec) 157 return SVGLength(); 158 return length; 159 } 160 161private: 162 float m_valueInSpecifiedUnits; 163 unsigned int m_unit; 164}; 165 166template<> 167struct SVGPropertyTraits<SVGLength> { 168 static SVGLength initialValue() { return SVGLength(); } 169 static String toString(const SVGLength& type) { return type.valueAsString(); } 170}; 171 172 173} // namespace WebCore 174 175#endif // ENABLE(SVG) 176#endif // SVGLength_h 177