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.
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.
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.
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.
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"
38 // FIXME: This enum makes it hard to tell in general what values may be
39 // appropriate for any given Length.
42 Intrinsic
, MinIntrinsic
,
43 MinContent
, MaxContent
, FillAvailable
, FitContent
,
45 ExtendToZoom
, DeviceWidth
, DeviceHeight
,
54 struct PixelsAndPercent
{
55 PixelsAndPercent(float pixels
, float percent
)
64 class CalculationValue
;
66 class PLATFORM_EXPORT Length
{
67 WTF_MAKE_FAST_ALLOCATED(Length
);
70 : m_intValue(0), m_quirk(false), m_type(Auto
), m_isFloat(false)
75 : m_intValue(0), m_quirk(false), m_type(t
), m_isFloat(false)
77 ASSERT(t
!= Calculated
);
80 Length(int v
, LengthType t
, bool q
= false)
81 : m_intValue(v
), m_quirk(q
), m_type(t
), m_isFloat(false)
83 ASSERT(t
!= Calculated
);
86 Length(LayoutUnit v
, LengthType t
, bool q
= false)
87 : m_floatValue(v
.toFloat()), m_quirk(q
), m_type(t
), m_isFloat(true)
89 ASSERT(t
!= Calculated
);
92 Length(float v
, LengthType t
, bool q
= false)
93 : m_floatValue(v
), m_quirk(q
), m_type(t
), m_isFloat(true)
95 ASSERT(t
!= Calculated
);
98 Length(double v
, LengthType t
, bool q
= false)
99 : m_quirk(q
), m_type(t
), m_isFloat(true)
101 m_floatValue
= static_cast<float>(v
);
104 explicit Length(PassRefPtr
<CalculationValue
>);
106 Length(const Length
& length
)
108 memcpy(this, &length
, sizeof(Length
));
110 incrementCalculatedRef();
113 Length
& operator=(const Length
& length
)
115 if (length
.isCalculated())
116 length
.incrementCalculatedRef();
118 decrementCalculatedRef();
119 memcpy(this, &length
, sizeof(Length
));
126 decrementCalculatedRef();
129 bool operator==(const Length
& o
) const { return (m_type
== o
.m_type
) && (m_quirk
== o
.m_quirk
) && (isMaxSizeNone() || (getFloatValue() == o
.getFloatValue()) || isCalculatedEqual(o
)); }
130 bool operator!=(const Length
& o
) const { return !(*this == o
); }
132 const Length
& operator*=(float v
)
134 if (isCalculated()) {
135 ASSERT_NOT_REACHED();
140 m_floatValue
= static_cast<float>(m_floatValue
* v
);
142 m_intValue
= static_cast<int>(m_intValue
* v
);
147 // FIXME: Make this private (if possible) or at least rename it (http://crbug.com/432707).
148 inline float value() const
150 return getFloatValue();
155 if (isCalculated()) {
156 ASSERT_NOT_REACHED();
159 return getIntValue();
162 float percent() const
164 ASSERT(type() == Percent
);
165 return getFloatValue();
167 PixelsAndPercent
pixelsAndPercent() const;
169 CalculationValue
& calculationValue() const;
171 LengthType
type() const { return static_cast<LengthType
>(m_type
); }
172 bool quirk() const { return m_quirk
; }
174 void setQuirk(bool quirk
)
179 void setValue(LengthType t
, int value
)
186 void setValue(int value
)
188 if (isCalculated()) {
189 ASSERT_NOT_REACHED();
192 setValue(Fixed
, value
);
195 void setValue(LengthType t
, float value
)
198 m_floatValue
= value
;
202 void setValue(LengthType t
, LayoutUnit value
)
205 m_floatValue
= value
.toFloat();
209 void setValue(float value
)
211 *this = Length(value
, Fixed
);
214 bool isMaxSizeNone() const { return type() == MaxSizeNone
; }
216 // FIXME calc: https://bugs.webkit.org/show_bug.cgi?id=80357. A calculated Length
217 // always contains a percentage, and without a maxValue passed to these functions
218 // it's impossible to determine the sign or zero-ness. We assume all calc values
219 // are positive and non-zero for now.
222 ASSERT(!isMaxSizeNone());
226 return m_isFloat
? !m_floatValue
: !m_intValue
;
228 bool isPositive() const
235 return getFloatValue() > 0;
237 bool isNegative() const
239 if (isMaxSizeNone() || isCalculated())
242 return getFloatValue() < 0;
245 bool isAuto() const { return type() == Auto
; }
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 bool hasPercent() const { return type() == Percent
|| type() == Calculated
; }
260 Length
blend(const Length
& from
, double progress
, ValueRange range
) const
262 ASSERT(isSpecified() && from
.isSpecified());
270 if (from
.type() == Calculated
|| type() == Calculated
)
271 return blendMixedTypes(from
, progress
, range
);
273 if (!from
.isZero() && !isZero() && from
.type() != type())
274 return blendMixedTypes(from
, progress
, range
);
276 if (from
.isZero() && isZero())
279 LengthType resultType
= type();
281 resultType
= from
.type();
283 float blendedValue
= blink::blend(from
.value(), value(), progress
);
284 if (range
== ValueRangeNonNegative
)
285 blendedValue
= clampTo
<float>(blendedValue
, 0);
286 return Length(blendedValue
, resultType
);
289 float getFloatValue() const
291 ASSERT(!isMaxSizeNone());
292 return m_isFloat
? m_floatValue
: m_intValue
;
294 float nonNanCalculatedValue(LayoutUnit maxValue
) const;
296 Length
subtractFromOneHundredPercent() const;
298 Length
zoom(double factor
) const;
301 int getIntValue() const
303 ASSERT(!isMaxSizeNone());
304 return m_isFloat
? static_cast<int>(m_floatValue
) : m_intValue
;
307 Length
blendMixedTypes(const Length
& from
, double progress
, ValueRange
) const;
309 int calculationHandle() const
311 ASSERT(isCalculated());
312 return getIntValue();
314 void incrementCalculatedRef() const;
315 void decrementCalculatedRef() const;
322 unsigned char m_type
;
326 PLATFORM_EXPORT Vector
<Length
> parseHTMLAreaElementCoords(const String
&);