Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / 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     Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
6
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Library General Public
9     License as published by the Free Software Foundation; either
10     version 2 of the License, or (at your option) any later version.
11
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Library General Public License for more details.
16
17     You should have received a copy of the GNU Library General Public License
18     along with this library; see the file COPYING.LIB.  If not, write to
19     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20     Boston, MA 02110-1301, USA.
21 */
22
23 #ifndef Length_h
24 #define Length_h
25
26 #include "platform/PlatformExport.h"
27 #include "platform/animation/AnimationUtilities.h"
28 #include "wtf/Assertions.h"
29 #include "wtf/FastAllocBase.h"
30 #include "wtf/Forward.h"
31 #include "wtf/HashMap.h"
32 #include "wtf/MathExtras.h"
33 #include "wtf/Vector.h"
34 #include <cstring>
35
36 namespace WebCore {
37
38 // FIXME: This enum makes it hard to tell in general what values may be
39 // appropriate for any given Length.
40 enum LengthType {
41     Auto, Percent, Fixed,
42     Intrinsic, MinIntrinsic,
43     MinContent, MaxContent, FillAvailable, FitContent,
44     Calculated,
45     ExtendToZoom, DeviceWidth, DeviceHeight,
46     Undefined
47 };
48
49 enum ValueRange {
50     ValueRangeAll,
51     ValueRangeNonNegative
52 };
53
54 struct PixelsAndPercent {
55     PixelsAndPercent(float pixels, float percent)
56         : pixels(pixels)
57         , percent(percent)
58     {
59     }
60     float pixels;
61     float percent;
62 };
63
64 class CalculationValue;
65
66 class PLATFORM_EXPORT Length {
67     WTF_MAKE_FAST_ALLOCATED;
68 public:
69     Length()
70         :  m_intValue(0), m_quirk(false), m_type(Auto), m_isFloat(false)
71     {
72     }
73
74     Length(LengthType t)
75         : m_intValue(0), m_quirk(false), m_type(t), m_isFloat(false)
76     {
77         ASSERT(t != Calculated);
78     }
79
80     Length(int v, LengthType t, bool q = false)
81         : m_intValue(v), m_quirk(q), m_type(t), m_isFloat(false)
82     {
83         ASSERT(t != Calculated);
84     }
85
86     Length(LayoutUnit v, LengthType t, bool q = false)
87         : m_floatValue(v.toFloat()), m_quirk(q), m_type(t), m_isFloat(true)
88     {
89         ASSERT(t != Calculated);
90     }
91
92     Length(float v, LengthType t, bool q = false)
93         : m_floatValue(v), m_quirk(q), m_type(t), m_isFloat(true)
94     {
95         ASSERT(t != Calculated);
96     }
97
98     Length(double v, LengthType t, bool q = false)
99         : m_quirk(q), m_type(t), m_isFloat(true)
100     {
101         m_floatValue = static_cast<float>(v);
102     }
103
104     explicit Length(PassRefPtr<CalculationValue>);
105
106     Length(const Length& length)
107     {
108         memcpy(this, &length, sizeof(Length));
109         if (isCalculated())
110             incrementCalculatedRef();
111     }
112
113     Length& operator=(const Length& length)
114     {
115         if (length.isCalculated())
116             length.incrementCalculatedRef();
117         if (isCalculated())
118             decrementCalculatedRef();
119         memcpy(this, &length, sizeof(Length));
120         return *this;
121     }
122
123     ~Length()
124     {
125         if (isCalculated())
126             decrementCalculatedRef();
127     }
128
129     bool operator==(const Length& o) const { return (m_type == o.m_type) && (m_quirk == o.m_quirk) && (isUndefined() || (getFloatValue() == o.getFloatValue()) || isCalculatedEqual(o)); }
130     bool operator!=(const Length& o) const { return !(*this == o); }
131
132     const Length& operator*=(float v)
133     {
134         if (isCalculated()) {
135             ASSERT_NOT_REACHED();
136             return *this;
137         }
138
139         if (m_isFloat)
140             m_floatValue = static_cast<float>(m_floatValue * v);
141         else
142             m_intValue = static_cast<int>(m_intValue * v);
143
144         return *this;
145     }
146
147     inline float value() const
148     {
149         return getFloatValue();
150     }
151
152     int intValue() const
153     {
154         if (isCalculated()) {
155             ASSERT_NOT_REACHED();
156             return 0;
157         }
158         return getIntValue();
159     }
160
161     float percent() const
162     {
163         ASSERT(type() == Percent);
164         return getFloatValue();
165     }
166     PixelsAndPercent pixelsAndPercent() const;
167
168     CalculationValue& calculationValue() const;
169
170     LengthType type() const { return static_cast<LengthType>(m_type); }
171     bool quirk() const { return m_quirk; }
172
173     void setQuirk(bool quirk)
174     {
175         m_quirk = quirk;
176     }
177
178     void setValue(LengthType t, int value)
179     {
180         m_type = t;
181         m_intValue = value;
182         m_isFloat = false;
183     }
184
185     void setValue(int value)
186     {
187         if (isCalculated()) {
188             ASSERT_NOT_REACHED();
189             return;
190         }
191         setValue(Fixed, value);
192     }
193
194     void setValue(LengthType t, float value)
195     {
196         m_type = t;
197         m_floatValue = value;
198         m_isFloat = true;
199     }
200
201     void setValue(LengthType t, LayoutUnit value)
202     {
203         m_type = t;
204         m_floatValue = value.toFloat();
205         m_isFloat = true;
206     }
207
208     void setValue(float value)
209     {
210         *this = Length(value, Fixed);
211     }
212
213     bool isUndefined() const { return type() == Undefined; }
214
215     // FIXME calc: https://bugs.webkit.org/show_bug.cgi?id=80357. A calculated Length
216     // always contains a percentage, and without a maxValue passed to these functions
217     // it's impossible to determine the sign or zero-ness. We assume all calc values
218     // are positive and non-zero for now.
219     bool isZero() const
220     {
221         ASSERT(!isUndefined());
222         if (isCalculated())
223             return false;
224
225         return m_isFloat ? !m_floatValue : !m_intValue;
226     }
227     bool isPositive() const
228     {
229         if (isUndefined())
230             return false;
231         if (isCalculated())
232             return true;
233
234         return getFloatValue() > 0;
235     }
236     bool isNegative() const
237     {
238         if (isUndefined() || isCalculated())
239             return false;
240
241         return getFloatValue() < 0;
242     }
243
244     bool isAuto() const { return type() == Auto; }
245     bool isPercent() const { return type() == Percent || type() == Calculated; }
246     bool isFixed() const { return type() == Fixed; }
247     bool isIntrinsicOrAuto() const { return type() == Auto || isLegacyIntrinsic() || isIntrinsic(); }
248     bool isLegacyIntrinsic() const { return type() == Intrinsic || type() == MinIntrinsic; }
249     bool isIntrinsic() const { return type() == MinContent || type() == MaxContent || type() == FillAvailable || type() == FitContent; }
250     bool isSpecified() const { return type() == Fixed || type() == Percent || type() == Calculated; }
251     bool isSpecifiedOrIntrinsic() const { return isSpecified() || isIntrinsic(); }
252     bool isCalculated() const { return type() == Calculated; }
253     bool isCalculatedEqual(const Length&) const;
254     bool isMinContent() const { return type() == MinContent; }
255     bool isMaxContent() const { return type() == MaxContent; }
256     bool isFillAvailable() const { return type() == FillAvailable; }
257     bool isFitContent() const { return type() == FitContent; }
258
259     Length blend(const Length& from, double progress, ValueRange range) const
260     {
261         ASSERT(isSpecified() && from.isSpecified());
262
263         if (progress == 0.0)
264             return from;
265
266         if (progress == 1.0)
267             return *this;
268
269         if (from.type() == Calculated || type() == Calculated)
270             return blendMixedTypes(from, progress, range);
271
272         if (!from.isZero() && !isZero() && from.type() != type())
273             return blendMixedTypes(from, progress, range);
274
275         if (from.isZero() && isZero())
276             return *this;
277
278         LengthType resultType = type();
279         if (isZero())
280             resultType = from.type();
281
282         float blendedValue = WebCore::blend(from.value(), value(), progress);
283         if (range == ValueRangeNonNegative)
284             blendedValue = clampTo<float>(blendedValue, 0);
285         return Length(blendedValue, resultType);
286     }
287
288     float getFloatValue() const
289     {
290         ASSERT(!isUndefined());
291         return m_isFloat ? m_floatValue : m_intValue;
292     }
293     float nonNanCalculatedValue(int maxValue) const;
294
295     Length subtractFromOneHundredPercent() const;
296
297 private:
298     int getIntValue() const
299     {
300         ASSERT(!isUndefined());
301         return m_isFloat ? static_cast<int>(m_floatValue) : m_intValue;
302     }
303
304     Length blendMixedTypes(const Length& from, double progress, ValueRange) const;
305
306     int calculationHandle() const
307     {
308         ASSERT(isCalculated());
309         return getIntValue();
310     }
311     void incrementCalculatedRef() const;
312     void decrementCalculatedRef() const;
313
314     union {
315         int m_intValue;
316         float m_floatValue;
317     };
318     bool m_quirk;
319     unsigned char m_type;
320     bool m_isFloat;
321 };
322
323 PLATFORM_EXPORT Vector<Length> parseHTMLAreaElementCoords(const String&);
324
325 } // namespace WebCore
326
327 #endif // Length_h