~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/platform/Length.h

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "AnimationUtilities.h"
 
27
#include <wtf/Assertions.h>
 
28
#include <wtf/FastAllocBase.h>
 
29
#include <wtf/Forward.h>
 
30
#include <wtf/HashMap.h>
 
31
#include <wtf/MathExtras.h>
 
32
#include <wtf/PassOwnArrayPtr.h>
 
33
 
 
34
namespace WebCore {
 
35
 
 
36
enum LengthType {
 
37
    Auto, Relative, Percent, Fixed,
 
38
    Intrinsic, MinIntrinsic,
 
39
    MinContent, MaxContent, FillAvailable, FitContent,
 
40
    Calculated,
 
41
    ViewportPercentageWidth, ViewportPercentageHeight, ViewportPercentageMin,
 
42
    Undefined
 
43
};
 
44
 
 
45
class CalculationValue;    
 
46
    
 
47
struct Length {
 
48
    WTF_MAKE_FAST_ALLOCATED;
 
49
public:
 
50
    Length()
 
51
        :  m_intValue(0), m_quirk(false), m_type(Auto), m_isFloat(false)
 
52
    {
 
53
    }
 
54
 
 
55
    Length(LengthType t)
 
56
        : m_intValue(0), m_quirk(false), m_type(t), m_isFloat(false)
 
57
    {
 
58
        ASSERT(t != Calculated);
 
59
    }
 
60
 
 
61
    Length(int v, LengthType t, bool q = false)
 
62
        : m_intValue(v), m_quirk(q), m_type(t), m_isFloat(false)
 
63
    {
 
64
        ASSERT(t != Calculated);
 
65
    }
 
66
    
 
67
    Length(LayoutUnit v, LengthType t, bool q = false)
 
68
        : m_floatValue(v.toFloat()), m_quirk(q), m_type(t), m_isFloat(true)
 
69
    {
 
70
        ASSERT(t != Calculated);
 
71
    }
 
72
    
 
73
    Length(float v, LengthType t, bool q = false)
 
74
        : m_floatValue(v), m_quirk(q), m_type(t), m_isFloat(true)
 
75
    {
 
76
        ASSERT(t != Calculated);
 
77
    }
 
78
 
 
79
    Length(double v, LengthType t, bool q = false)
 
80
        : m_quirk(q), m_type(t), m_isFloat(true)
 
81
    {
 
82
        m_floatValue = static_cast<float>(v);    
 
83
    }
 
84
 
 
85
    explicit Length(PassRefPtr<CalculationValue>);
 
86
 
 
87
    Length(const Length& length)
 
88
    {
 
89
        initFromLength(length);
 
90
    }
 
91
    
 
92
    Length& operator=(const Length& length)
 
93
    {
 
94
        initFromLength(length);
 
95
        return *this;
 
96
    }
 
97
    
 
98
    ~Length()
 
99
    {
 
100
        if (isCalculated())
 
101
            decrementCalculatedRef();
 
102
    }  
 
103
    
 
104
    bool operator==(const Length& o) const { return (m_type == o.m_type) && (m_quirk == o.m_quirk) && (isUndefined() || (getFloatValue() == o.getFloatValue()) || isCalculatedEqual(o)); }
 
105
    bool operator!=(const Length& o) const { return !(*this == o); }
 
106
 
 
107
    const Length& operator*=(float v)
 
108
    {       
 
109
        if (isCalculated()) {
 
110
            ASSERT_NOT_REACHED();
 
111
            return *this;
 
112
        }
 
113
        
 
114
        if (m_isFloat)
 
115
            m_floatValue = static_cast<float>(m_floatValue * v);
 
116
        else        
 
117
            m_intValue = static_cast<int>(m_intValue * v);
 
118
        
 
119
        return *this;
 
120
    }
 
121
    
 
122
    inline float value() const
 
123
    {
 
124
        return getFloatValue();
 
125
    }
 
126
 
 
127
     int intValue() const
 
128
     {
 
129
        if (isCalculated()) {
 
130
            ASSERT_NOT_REACHED();
 
131
            return 0;
 
132
        }
 
133
        return getIntValue();
 
134
    }
 
135
 
 
136
    float percent() const
 
137
    {
 
138
        ASSERT(type() == Percent);
 
139
        return getFloatValue();
 
140
    }
 
141
 
 
142
    PassRefPtr<CalculationValue> calculationValue() const;
 
143
 
 
144
    LengthType type() const { return static_cast<LengthType>(m_type); }
 
145
    bool quirk() const { return m_quirk; }
 
146
 
 
147
    void setQuirk(bool quirk)
 
148
    {
 
149
        m_quirk = quirk;
 
150
    }
 
151
 
 
152
    void setValue(LengthType t, int value)
 
153
    {
 
154
        m_type = t;
 
155
        m_intValue = value;
 
156
        m_isFloat = false;
 
157
    }
 
158
 
 
159
    void setValue(int value)
 
160
    {
 
161
        if (isCalculated()) {
 
162
            ASSERT_NOT_REACHED();
 
163
            return;
 
164
        }
 
165
        setValue(Fixed, value);
 
166
    }
 
167
 
 
168
    void setValue(LengthType t, float value)
 
169
    {
 
170
        m_type = t;
 
171
        m_floatValue = value;
 
172
        m_isFloat = true;    
 
173
    }
 
174
 
 
175
    void setValue(LengthType t, LayoutUnit value)
 
176
    {
 
177
        m_type = t;
 
178
        m_floatValue = value;
 
179
        m_isFloat = true;    
 
180
    }
 
181
 
 
182
    void setValue(float value)
 
183
    {
 
184
        *this = Length(value, Fixed);
 
185
    }
 
186
 
 
187
    bool isUndefined() const { return type() == Undefined; }
 
188
 
 
189
    // FIXME calc: https://bugs.webkit.org/show_bug.cgi?id=80357. A calculated Length 
 
190
    // always contains a percentage, and without a maxValue passed to these functions
 
191
    // it's impossible to determine the sign or zero-ness. We assume all calc values
 
192
    // are positive and non-zero for now.    
 
193
    bool isZero() const 
 
194
    {
 
195
        ASSERT(!isUndefined());
 
196
        if (isCalculated())
 
197
            return false;
 
198
            
 
199
        return m_isFloat ? !m_floatValue : !m_intValue;
 
200
    }
 
201
    bool isPositive() const
 
202
    {
 
203
        if (isUndefined())
 
204
            return false;
 
205
        if (isCalculated())
 
206
            return true;
 
207
                
 
208
        return getFloatValue() > 0;
 
209
    }
 
210
    bool isNegative() const
 
211
    {
 
212
        if (isUndefined() || isCalculated())
 
213
            return false;
 
214
            
 
215
        return getFloatValue() < 0;
 
216
    }
 
217
    
 
218
    bool isAuto() const { return type() == Auto; }
 
219
    bool isRelative() const { return type() == Relative; }
 
220
    bool isPercent() const { return type() == Percent || type() == Calculated; }
 
221
    bool isFixed() const { return type() == Fixed; }
 
222
    bool isIntrinsicOrAuto() const { return type() == Auto || isLegacyIntrinsic() || isIntrinsic(); }
 
223
    bool isLegacyIntrinsic() const { return type() == Intrinsic || type() == MinIntrinsic; }
 
224
    bool isIntrinsic() const { return type() == MinContent || type() == MaxContent || type() == FillAvailable || type() == FitContent; }
 
225
    bool isSpecified() const { return type() == Fixed || type() == Percent || type() == Calculated || isViewportPercentage(); }
 
226
    bool isCalculated() const { return type() == Calculated; }
 
227
    bool isCalculatedEqual(const Length&) const;
 
228
 
 
229
    Length blend(const Length& from, double progress) const
 
230
    {
 
231
        // Blend two lengths to produce a new length that is in between them.  Used for animation.
 
232
        if (from.type() == Calculated || type() == Calculated)
 
233
            return blendMixedTypes(from, progress);
 
234
        
 
235
        if (!from.isZero() && !isZero() && from.type() != type())
 
236
            return blendMixedTypes(from, progress);
 
237
 
 
238
        if (from.isZero() && isZero())
 
239
            return *this;
 
240
        
 
241
        LengthType resultType = type();
 
242
        if (isZero())
 
243
            resultType = from.type();
 
244
        
 
245
        if (resultType == Percent) {
 
246
            float fromPercent = from.isZero() ? 0 : from.percent();
 
247
            float toPercent = isZero() ? 0 : percent();
 
248
            return Length(WebCore::blend(fromPercent, toPercent, progress), Percent);
 
249
        } 
 
250
 
 
251
        float fromValue = from.isZero() ? 0 : from.value();
 
252
        float toValue = isZero() ? 0 : value();
 
253
        return Length(WebCore::blend(fromValue, toValue, progress), resultType);
 
254
    }
 
255
 
 
256
    float getFloatValue() const
 
257
    {
 
258
        ASSERT(!isUndefined());
 
259
        return m_isFloat ? m_floatValue : m_intValue;
 
260
    }
 
261
    float nonNanCalculatedValue(int maxValue) const;
 
262
 
 
263
    bool isViewportPercentage() const
 
264
    {
 
265
        LengthType lengthType = type();
 
266
        return lengthType >= ViewportPercentageWidth && lengthType <= ViewportPercentageMin;
 
267
    }
 
268
    float viewportPercentageLength() const
 
269
    {
 
270
        ASSERT(isViewportPercentage());
 
271
        return getFloatValue();
 
272
    }
 
273
private:
 
274
    int getIntValue() const
 
275
    {
 
276
        ASSERT(!isUndefined());
 
277
        return m_isFloat ? static_cast<int>(m_floatValue) : m_intValue;
 
278
    }
 
279
    void initFromLength(const Length &length) 
 
280
    {
 
281
        m_quirk = length.m_quirk;
 
282
        m_type = length.m_type;
 
283
        m_isFloat = length.m_isFloat;
 
284
        
 
285
        if (m_isFloat)
 
286
            m_floatValue = length.m_floatValue;
 
287
        else
 
288
            m_intValue = length.m_intValue;
 
289
        
 
290
        if (isCalculated())
 
291
            incrementCalculatedRef();
 
292
    }
 
293
 
 
294
    Length blendMixedTypes(const Length& from, double progress) const;
 
295
 
 
296
    int calculationHandle() const
 
297
    {
 
298
        ASSERT(isCalculated());
 
299
        return getIntValue();
 
300
    }
 
301
    void incrementCalculatedRef() const;
 
302
    void decrementCalculatedRef() const;    
 
303
    
 
304
    union {
 
305
        int m_intValue;
 
306
        float m_floatValue;
 
307
    };
 
308
    bool m_quirk;
 
309
    unsigned char m_type;
 
310
    bool m_isFloat;
 
311
};
 
312
 
 
313
PassOwnArrayPtr<Length> newCoordsArray(const String&, int& len);
 
314
PassOwnArrayPtr<Length> newLengthArray(const String&, int& len);
 
315
 
 
316
} // namespace WebCore
 
317
 
 
318
#endif // Length_h