]> git.saurik.com Git - iphone-api.git/blob - WebCore/Length.h
Add support for new WinterBoard Settings features.
[iphone-api.git] / WebCore / Length.h
1 /*
2 Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
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 Length_h
22 #define Length_h
23
24 #include <wtf/Assertions.h>
25 #include <wtf/MathExtras.h>
26
27 namespace WebCore {
28
29 class String;
30
31 const int undefinedLength = -1;
32 const int percentScaleFactor = 128;
33
34 enum LengthType { Auto, Relative, Percent, Fixed, Static, Intrinsic, MinIntrinsic };
35
36 struct Length {
37 Length()
38 : m_value(0)
39 {
40 }
41
42 Length(LengthType t)
43 : m_value(t)
44 {
45 }
46
47 Length(int v, LengthType t, bool q = false)
48 : m_value((v * 16) | (q << 3) | t) // FIXME: Doesn't work if the passed-in value is very large!
49 {
50 ASSERT(t != Percent);
51 }
52
53 Length(double v, LengthType t, bool q = false)
54 : m_value(static_cast<int>(v * percentScaleFactor) * 16 | (q << 3) | t)
55 {
56 ASSERT(t == Percent);
57 }
58
59 bool operator==(const Length& o) const { return m_value == o.m_value; }
60 bool operator!=(const Length& o) const { return m_value != o.m_value; }
61
62 int value() const {
63 ASSERT(type() != Percent);
64 return rawValue();
65 }
66
67 int rawValue() const { return (m_value & ~0xF) / 16; }
68
69 double percent() const
70 {
71 ASSERT(type() == Percent);
72 return static_cast<double>(rawValue()) / percentScaleFactor;
73 }
74
75 LengthType type() const { return static_cast<LengthType>(m_value & 7); }
76 bool quirk() const { return (m_value >> 3) & 1; }
77
78 void setValue(LengthType t, int value)
79 {
80 ASSERT(t != Percent);
81 setRawValue(t, value);
82 }
83
84 void setRawValue(LengthType t, int value) { m_value = value * 16 | (m_value & 0x8) | t; }
85
86 void setValue(int value)
87 {
88 ASSERT(!value || type() != Percent);
89 setRawValue(value);
90 }
91
92 void setRawValue(int value) { m_value = value * 16 | (m_value & 0xF); }
93
94 void setValue(LengthType t, double value)
95 {
96 ASSERT(t == Percent);
97 m_value = static_cast<int>(value * percentScaleFactor) * 16 | (m_value & 0x8) | t;
98 }
99
100 void setValue(double value)
101 {
102 ASSERT(type() == Percent);
103 m_value = static_cast<int>(value * percentScaleFactor) * 16 | (m_value & 0xF);
104 }
105
106 // note: works only for certain types, returns undefinedLength otherwise
107 int calcValue(int maxValue, bool roundPercentages = false) const
108 {
109 switch (type()) {
110 case Fixed:
111 return value();
112 case Percent:
113 if (roundPercentages)
114 return static_cast<int>(round(maxValue * percent() / 100.0));
115 return maxValue * rawValue() / (100 * percentScaleFactor);
116 case Auto:
117 return maxValue;
118 default:
119 return undefinedLength;
120 }
121 }
122
123 int calcMinValue(int maxValue, bool roundPercentages = false) const
124 {
125 switch (type()) {
126 case Fixed:
127 return value();
128 case Percent:
129 if (roundPercentages)
130 return static_cast<int>(round(maxValue * percent() / 100.0));
131 return maxValue * rawValue() / (100 * percentScaleFactor);
132 case Auto:
133 default:
134 return 0;
135 }
136 }
137
138 float calcFloatValue(int maxValue) const
139 {
140 switch (type()) {
141 case Fixed:
142 return static_cast<float>(value());
143 case Percent:
144 return static_cast<float>(maxValue * percent() / 100.0);
145 case Auto:
146 return static_cast<float>(maxValue);
147 default:
148 return static_cast<float>(undefinedLength);
149 }
150 }
151
152 bool isUndefined() const { return rawValue() == undefinedLength; }
153 bool isZero() const { return !(m_value & ~0xF); }
154 bool isPositive() const { return rawValue() > 0; }
155 bool isNegative() const { return rawValue() < 0; }
156
157 bool isAuto() const { return type() == Auto; }
158 bool isRelative() const { return type() == Relative; }
159 bool isPercent() const { return type() == Percent; }
160 bool isFixed() const { return type() == Fixed; }
161 bool isStatic() const { return type() == Static; }
162 bool isIntrinsicOrAuto() const { return type() == Auto || type() == MinIntrinsic || type() == Intrinsic; }
163
164 Length blend(const Length& from, double progress) const
165 {
166 // Blend two lengths to produce a new length that is in between them. Used for animation.
167 if (!from.isZero() && !isZero() && from.type() != type())
168 return *this;
169
170 if (from.isZero() && isZero())
171 return *this;
172
173 LengthType resultType = type();
174 if (isZero())
175 resultType = from.type();
176
177 if (resultType == Percent) {
178 double fromPercent = from.isZero() ? 0. : from.percent();
179 double toPercent = isZero() ? 0. : percent();
180 return Length(fromPercent + (toPercent - fromPercent) * progress, Percent);
181 }
182
183 int fromValue = from.isZero() ? 0 : from.value();
184 int toValue = isZero() ? 0 : value();
185 return Length(int(fromValue + (toValue - fromValue) * progress), resultType);
186 }
187
188 private:
189 int m_value;
190 };
191
192 Length* newCoordsArray(const String&, int& len);
193 Length* newLengthArray(const String&, int& len);
194
195 } // namespace WebCore
196
197 #endif // Length_h