152
153 class CalculationValueHandleMap {
154 public:
155 CalculationValueHandleMap()
156 : m_index(1)
157 {
158 }
159
160 int insert(PassRefPtr<CalculationValue> calcValue)
161 {
162 ASSERT(m_index);
163 // FIXME calc(): https://bugs.webkit.org/show_bug.cgi?id=80489
164 // This monotonically increasing handle generation scheme is potentially wasteful
165 // of the handle space. Consider reusing empty handles.
166 while (m_map.contains(m_index))
167 m_index++;
168
169 m_map.set(m_index, calcValue);
170
171 return m_index;
172 }
173
174 void remove(int index)
175 {
176 ASSERT(m_map.contains(index));
177 m_map.remove(index);
178 }
179
180 PassRefPtr<CalculationValue> get(int index)
181 {
182 ASSERT(m_map.contains(index));
183 return m_map.get(index);
184 }
185
186 private:
187 int m_index;
188 HashMap<int, RefPtr<CalculationValue> > m_map;
189 };
190
191 static CalculationValueHandleMap& calcHandles()
192 {
193 DEFINE_STATIC_LOCAL(CalculationValueHandleMap, handleMap, ());
194 return handleMap;
195 }
196
197 Length::Length(PassRefPtr<CalculationValue> calc)
198 : m_quirk(false)
199 , m_type(Calculated)
200 , m_isFloat(false)
201 {
202 m_intValue = calcHandles().insert(calc);
203 }
204
205 PassRefPtr<CalculationValue> Length::calculationValue() const
206 {
207 ASSERT(isCalculated());
208 return calcHandles().get(calculationHandle());
209 }
210
211 void Length::incrementCalculatedRef() const
212 {
213 ASSERT(isCalculated());
214 calculationValue()->ref();
215 }
216
217 void Length::decrementCalculatedRef() const
218 {
219 ASSERT(isCalculated());
220 RefPtr<CalculationValue> calcLength = calculationValue();
221 if (calcLength->hasOneRef())
222 calcHandles().remove(calculationHandle());
223 calcLength->deref();
224 }
225
226 float Length::nonNanCalculatedValue(int maxValue) const
227 {
228 ASSERT(isCalculated());
229 float result = calculationValue()->evaluate(maxValue);
230 if (isnan(result))
231 return 0;
232 return result;
233 }