• 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/FastAllocBase.h>
26 #include <wtf/MathExtras.h>
27 
28 namespace WebCore {
29 
30 class String;
31 
32 const int undefinedLength = -1;
33 const int percentScaleFactor = 128;
34 
35 enum LengthType { Auto, Relative, Percent, Fixed, Static, Intrinsic, MinIntrinsic };
36 
37 struct Length : FastAllocBase {
LengthLength38     Length()
39         : m_value(0)
40     {
41     }
42 
LengthLength43     Length(LengthType t)
44         : m_value(t)
45     {
46     }
47 
48     Length(int v, LengthType t, bool q = false)
49         : m_value((v * 16) | (q << 3) | t) // FIXME: Doesn't work if the passed-in value is very large!
50     {
51         ASSERT(t != Percent);
52     }
53 
54     Length(double v, LengthType t, bool q = false)
55         : m_value(static_cast<int>(v * percentScaleFactor) * 16 | (q << 3) | t)
56     {
57         ASSERT(t == Percent);
58     }
59 
60     bool operator==(const Length& o) const { return m_value == o.m_value; }
61     bool operator!=(const Length& o) const { return m_value != o.m_value; }
62 
valueLength63     int value() const {
64         ASSERT(type() != Percent);
65         return rawValue();
66     }
67 
rawValueLength68     int rawValue() const { return (m_value & ~0xF) / 16; }
69 
percentLength70     double percent() const
71     {
72         ASSERT(type() == Percent);
73         return static_cast<double>(rawValue()) / percentScaleFactor;
74     }
75 
typeLength76     LengthType type() const { return static_cast<LengthType>(m_value & 7); }
quirkLength77     bool quirk() const { return (m_value >> 3) & 1; }
78 
setValueLength79     void setValue(LengthType t, int value)
80     {
81         ASSERT(t != Percent);
82         setRawValue(t, value);
83     }
84 
setRawValueLength85     void setRawValue(LengthType t, int value) { m_value = value * 16 | (m_value & 0x8) | t; }
86 
setValueLength87     void setValue(int value)
88     {
89         ASSERT(!value || type() != Percent);
90         setRawValue(value);
91     }
92 
setRawValueLength93     void setRawValue(int value) { m_value = value * 16 | (m_value & 0xF); }
94 
setValueLength95     void setValue(LengthType t, double value)
96     {
97         ASSERT(t == Percent);
98         m_value = static_cast<int>(value * percentScaleFactor) * 16 | (m_value & 0x8) | t;
99     }
100 
setValueLength101     void setValue(double value)
102     {
103         ASSERT(type() == Percent);
104         m_value = static_cast<int>(value * percentScaleFactor) * 16 | (m_value & 0xF);
105     }
106 
107     // note: works only for certain types, returns undefinedLength otherwise
108     int calcValue(int maxValue, bool roundPercentages = false) const
109     {
110         switch (type()) {
111             case Fixed:
112                 return value();
113             case Percent:
114                 if (roundPercentages)
115                     return static_cast<int>(round(maxValue * percent() / 100.0));
116                 return maxValue * rawValue() / (100 * percentScaleFactor);
117             case Auto:
118                 return maxValue;
119             default:
120                 return undefinedLength;
121         }
122     }
123 
124     int calcMinValue(int maxValue, bool roundPercentages = false) const
125     {
126         switch (type()) {
127             case Fixed:
128                 return value();
129             case Percent:
130                 if (roundPercentages)
131                     return static_cast<int>(round(maxValue * percent() / 100.0));
132                 return maxValue * rawValue() / (100 * percentScaleFactor);
133             case Auto:
134             default:
135                 return 0;
136         }
137     }
138 
calcFloatValueLength139     float calcFloatValue(int maxValue) const
140     {
141         switch (type()) {
142             case Fixed:
143                 return static_cast<float>(value());
144             case Percent:
145                 return static_cast<float>(maxValue * percent() / 100.0);
146             case Auto:
147                 return static_cast<float>(maxValue);
148             default:
149                 return static_cast<float>(undefinedLength);
150         }
151     }
152 
isUndefinedLength153     bool isUndefined() const { return rawValue() == undefinedLength; }
isZeroLength154     bool isZero() const { return !(m_value & ~0xF); }
isPositiveLength155     bool isPositive() const { return rawValue() > 0; }
isNegativeLength156     bool isNegative() const { return rawValue() < 0; }
157 
isAutoLength158     bool isAuto() const { return type() == Auto; }
isRelativeLength159     bool isRelative() const { return type() == Relative; }
isPercentLength160     bool isPercent() const { return type() == Percent; }
isFixedLength161     bool isFixed() const { return type() == Fixed; }
isStaticLength162     bool isStatic() const { return type() == Static; }
isIntrinsicOrAutoLength163     bool isIntrinsicOrAuto() const { return type() == Auto || type() == MinIntrinsic || type() == Intrinsic; }
164 
blendLength165     Length blend(const Length& from, double progress) const
166     {
167         // Blend two lengths to produce a new length that is in between them.  Used for animation.
168         if (!from.isZero() && !isZero() && from.type() != type())
169             return *this;
170 
171         if (from.isZero() && isZero())
172             return *this;
173 
174         LengthType resultType = type();
175         if (isZero())
176             resultType = from.type();
177 
178         if (resultType == Percent) {
179             double fromPercent = from.isZero() ? 0. : from.percent();
180             double toPercent = isZero() ? 0. : percent();
181             return Length(fromPercent + (toPercent - fromPercent) * progress, Percent);
182         }
183 
184         int fromValue = from.isZero() ? 0 : from.value();
185         int toValue = isZero() ? 0 : value();
186         return Length(int(fromValue + (toValue - fromValue) * progress), resultType);
187     }
188 
189 private:
190     int m_value;
191 };
192 
193 Length* newCoordsArray(const String&, int& len);
194 Length* newLengthArray(const String&, int& len);
195 
196 } // namespace WebCore
197 
198 #endif // Length_h
199