initial import
[vuplus_webkit] / Source / WebCore / platform / Length.h
1 /*
2     Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3     Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
4     Copyright (C) 2011 Rik Cabanier (cabanier@adobe.com)
5
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Library General Public
8     License as published by the Free Software Foundation; either
9     version 2 of the License, or (at your option) any later version.
10
11     This library is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14     Library General Public License for more details.
15
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
18     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19     Boston, MA 02110-1301, USA.
20 */
21
22 #ifndef Length_h
23 #define Length_h
24
25 #include <wtf/Assertions.h>
26 #include <wtf/FastAllocBase.h>
27 #include <wtf/Forward.h>
28 #include <wtf/MathExtras.h>
29 #include <wtf/PassOwnArrayPtr.h>
30
31 namespace WebCore {
32
33 const int undefinedLength = -1;
34 const int intMaxForLength = 0x7ffffff; // max value for a 28-bit int
35 const int intMinForLength = (-0x7ffffff - 1); // min value for a 28-bit int
36
37 enum LengthType { Auto, Relative, Percent, Fixed, Intrinsic, MinIntrinsic };
38
39 struct Length {
40     WTF_MAKE_FAST_ALLOCATED;
41 public:
42     Length()
43         :  m_intValue(0), m_quirk(false), m_type(Auto), m_isFloat(false)
44     {
45     }
46
47     Length(LengthType t)
48         : m_intValue(0), m_quirk(false), m_type(t), m_isFloat(false)
49     {
50     }
51
52     Length(int v, LengthType t, bool q = false)
53         : m_intValue(v), m_quirk(q), m_type(t), m_isFloat(false)
54     {
55     }
56     
57     Length(float v, LengthType t, bool q = false)
58     : m_floatValue(v), m_quirk(q), m_type(t), m_isFloat(true)
59     {            
60     }
61
62     Length(double v, LengthType t, bool q = false)
63         : m_quirk(q), m_type(t), m_isFloat(true)
64     {           
65         m_floatValue = static_cast<float>(v);    
66     }
67
68     bool operator==(const Length& o) const { return (getFloatValue() == o.getFloatValue()) && (m_type == o.m_type) && (m_quirk == o.m_quirk); }
69     bool operator!=(const Length& o) const { return (getFloatValue() != o.getFloatValue()) || (m_type != o.m_type) || (m_quirk != o.m_quirk); }
70
71     const Length& operator*=(float v)
72     {        
73         if (m_isFloat)
74             m_floatValue = static_cast<float>(m_floatValue * v);
75         else        
76             m_intValue = static_cast<int>(m_intValue * v);
77         
78         return *this;
79     }
80     
81     int value() const {
82         return getIntValue();
83     }
84
85     float percent() const
86     {
87         ASSERT(type() == Percent);
88         return getFloatValue();
89     }
90
91     LengthType type() const { return static_cast<LengthType>(m_type); }
92     bool quirk() const { return m_quirk; }
93
94     void setQuirk(bool quirk)
95     {
96         m_quirk = quirk;
97     }
98
99     void setValue(LengthType t, int value)
100     {
101         m_type = t;
102         m_intValue = value;
103         m_isFloat = false;
104     }
105
106     void setValue(int value)
107     {
108         setValue(Fixed, value);
109     }
110
111     void setValue(LengthType t, float value)
112     {
113         m_type = t;
114         m_floatValue = value;
115         m_isFloat = true;    
116     }
117
118     void setValue(float value)
119     {
120         *this = Length(value, Fixed);
121     }
122
123     // note: works only for certain types, returns undefinedLength otherwise
124     int calcValue(int maxValue, bool roundPercentages = false) const
125     {
126         switch (type()) {
127             case Fixed:
128             case Percent:
129                 return calcMinValue(maxValue, roundPercentages);
130             case Auto:
131                 return maxValue;
132             default:
133                 return undefinedLength;
134         }
135     }
136
137     int calcMinValue(int maxValue, bool roundPercentages = false) const
138     {
139         switch (type()) {
140             case Fixed:
141                 return value();
142             case Percent:
143                 if (roundPercentages)
144                     return static_cast<int>(round(maxValue * percent() / 100.0f));
145                 // Don't remove the extra cast to float. It is needed for rounding on 32-bit Intel machines that use the FPU stack.
146                 return static_cast<int>(static_cast<float>(maxValue * percent() / 100.0f));
147             case Auto:
148             default:
149                 return 0;
150         }
151     }
152
153     float calcFloatValue(int maxValue) const
154     {
155         switch (type()) {
156             case Fixed:
157                 return getFloatValue();
158             case Percent:
159                 return static_cast<float>(maxValue * percent() / 100.0f);
160             case Auto:
161                 return static_cast<float>(maxValue);
162             default:
163                 return static_cast<float>(undefinedLength);
164         }
165     }
166
167     bool isUndefined() const { return value() == undefinedLength; }
168     bool isZero() const 
169     { 
170         return m_isFloat ? !m_floatValue : !m_intValue;
171     }
172     
173     bool isPositive() const { return getFloatValue() > 0; }
174     bool isNegative() const { return getFloatValue() < 0; }
175
176     bool isAuto() const { return type() == Auto; }
177     bool isRelative() const { return type() == Relative; }
178     bool isPercent() const { return type() == Percent; }
179     bool isFixed() const { return type() == Fixed; }
180     bool isIntrinsicOrAuto() const { return type() == Auto || type() == MinIntrinsic || type() == Intrinsic; }
181     bool isSpecified() const { return type() == Fixed || type() == Percent; }
182
183     Length blend(const Length& from, float progress) const
184     {
185         // Blend two lengths to produce a new length that is in between them.  Used for animation.
186         if (!from.isZero() && !isZero() && from.type() != type())
187             return *this;
188
189         if (from.isZero() && isZero())
190             return *this;
191         
192         LengthType resultType = type();
193         if (isZero())
194             resultType = from.type();
195         
196         if (resultType == Percent) {
197             float fromPercent = from.isZero() ? 0 : from.percent();
198             float toPercent = isZero() ? 0 : percent();
199             return Length(fromPercent + (toPercent - fromPercent) * progress, Percent);
200         } 
201             
202         float fromValue = from.isZero() ? 0 : from.value();
203         float toValue = isZero() ? 0 : value();
204         return Length(fromValue + (toValue - fromValue) * progress, resultType);
205     }
206
207 private:
208     int getIntValue() const
209     {
210         return m_isFloat ? static_cast<int>(m_floatValue) : m_intValue;
211     }
212
213     float getFloatValue() const
214     {
215         return m_isFloat ? m_floatValue : m_intValue;
216     }
217
218     union {
219         int m_intValue;
220         float m_floatValue;
221     };
222     bool m_quirk;
223     unsigned char m_type;
224     bool m_isFloat;
225 };
226
227 PassOwnArrayPtr<Length> newCoordsArray(const String&, int& len);
228 PassOwnArrayPtr<Length> newLengthArray(const String&, int& len);
229
230 } // namespace WebCore
231
232 #endif // Length_h