• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
LengthLength37     Length()
38         : m_value(0)
39     {
40     }
41 
LengthLength42     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 
valueLength62     int value() const {
63         ASSERT(type() != Percent);
64         return rawValue();
65     }
66 
rawValueLength67     int rawValue() const { return (m_value & ~0xF) / 16; }
68 
percentLength69     double percent() const
70     {
71         ASSERT(type() == Percent);
72         return static_cast<double>(rawValue()) / percentScaleFactor;
73     }
74 
typeLength75     LengthType type() const { return static_cast<LengthType>(m_value & 7); }
quirkLength76     bool quirk() const { return (m_value >> 3) & 1; }
77 
setValueLength78     void setValue(LengthType t, int value)
79     {
80         ASSERT(t != Percent);
81         setRawValue(t, value);
82     }
83 
setRawValueLength84     void setRawValue(LengthType t, int value) { m_value = value * 16 | (m_value & 0x8) | t; }
85 
setValueLength86     void setValue(int value)
87     {
88         ASSERT(!value || type() != Percent);
89         setRawValue(value);
90     }
91 
setRawValueLength92     void setRawValue(int value) { m_value = value * 16 | (m_value & 0xF); }
93 
setValueLength94     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 
setValueLength100     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 
calcFloatValueLength138     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 
isUndefinedLength152     bool isUndefined() const { return rawValue() == undefinedLength; }
isZeroLength153     bool isZero() const { return !(m_value & ~0xF); }
isPositiveLength154     bool isPositive() const { return rawValue() > 0; }
isNegativeLength155     bool isNegative() const { return rawValue() < 0; }
156 
isAutoLength157     bool isAuto() const { return type() == Auto; }
isRelativeLength158     bool isRelative() const { return type() == Relative; }
isPercentLength159     bool isPercent() const { return type() == Percent; }
isFixedLength160     bool isFixed() const { return type() == Fixed; }
isStaticLength161     bool isStatic() const { return type() == Static; }
isIntrinsicOrAutoLength162     bool isIntrinsicOrAuto() const { return type() == Auto || type() == MinIntrinsic || type() == Intrinsic; }
163 
blendLength164     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
198