|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 /* representation of length values in computed style data */ |
|
7 |
|
8 #ifndef nsStyleCoord_h___ |
|
9 #define nsStyleCoord_h___ |
|
10 |
|
11 #include "nsCoord.h" |
|
12 #include "nsStyleConsts.h" |
|
13 |
|
14 enum nsStyleUnit { |
|
15 eStyleUnit_Null = 0, // (no value) value is not specified |
|
16 eStyleUnit_Normal = 1, // (no value) |
|
17 eStyleUnit_Auto = 2, // (no value) |
|
18 eStyleUnit_None = 3, // (no value) |
|
19 eStyleUnit_Percent = 10, // (float) 1.0 == 100% |
|
20 eStyleUnit_Factor = 11, // (float) a multiplier |
|
21 eStyleUnit_Degree = 12, // (float) angle in degrees |
|
22 eStyleUnit_Grad = 13, // (float) angle in grads |
|
23 eStyleUnit_Radian = 14, // (float) angle in radians |
|
24 eStyleUnit_Turn = 15, // (float) angle in turns |
|
25 eStyleUnit_FlexFraction = 16, // (float) <flex> in fr units |
|
26 eStyleUnit_Coord = 20, // (nscoord) value is twips |
|
27 eStyleUnit_Integer = 30, // (int) value is simple integer |
|
28 eStyleUnit_Enumerated = 32, // (int) value has enumerated meaning |
|
29 |
|
30 // The following are allocated types. They are weak pointers to |
|
31 // values allocated by nsStyleContext::Alloc. |
|
32 eStyleUnit_Calc = 40 // (Calc*) calc() toplevel; always present |
|
33 // to distinguish 50% from calc(50%), etc. |
|
34 }; |
|
35 |
|
36 typedef union { |
|
37 int32_t mInt; // nscoord is a int32_t for now |
|
38 float mFloat; |
|
39 // An mPointer is a weak pointer to a value that is guaranteed to |
|
40 // outlive the nsStyleCoord. In the case of nsStyleCoord::Calc*, it |
|
41 // is a pointer owned by the style context, allocated through |
|
42 // nsStyleContext::Alloc (and, therefore, is never stored in the rule |
|
43 // tree). |
|
44 void* mPointer; |
|
45 } nsStyleUnion; |
|
46 |
|
47 /** |
|
48 * Class that hold a single size specification used by the style |
|
49 * system. The size specification consists of two parts -- a number |
|
50 * and a unit. The number is an integer, a floating point value, an |
|
51 * nscoord, or undefined, and the unit is an nsStyleUnit. Checking |
|
52 * the unit is a must before asking for the value in any particular |
|
53 * form. |
|
54 */ |
|
55 class nsStyleCoord { |
|
56 public: |
|
57 struct Calc { |
|
58 // Every calc() expression evaluates to a length plus a percentage. |
|
59 nscoord mLength; |
|
60 float mPercent; |
|
61 bool mHasPercent; // whether there was any % syntax, even if 0 |
|
62 |
|
63 bool operator==(const Calc& aOther) const { |
|
64 return mLength == aOther.mLength && |
|
65 mPercent == aOther.mPercent && |
|
66 mHasPercent == aOther.mHasPercent; |
|
67 } |
|
68 bool operator!=(const Calc& aOther) const { return !(*this == aOther); } |
|
69 }; |
|
70 |
|
71 nsStyleCoord(nsStyleUnit aUnit = eStyleUnit_Null); |
|
72 enum CoordConstructorType { CoordConstructor }; |
|
73 inline nsStyleCoord(nscoord aValue, CoordConstructorType); |
|
74 nsStyleCoord(int32_t aValue, nsStyleUnit aUnit); |
|
75 nsStyleCoord(float aValue, nsStyleUnit aUnit); |
|
76 inline nsStyleCoord(const nsStyleCoord& aCopy); |
|
77 inline nsStyleCoord(const nsStyleUnion& aValue, nsStyleUnit aUnit); |
|
78 |
|
79 nsStyleCoord& operator=(const nsStyleCoord& aOther) |
|
80 { |
|
81 mUnit = aOther.mUnit; |
|
82 mValue = aOther.mValue; |
|
83 return *this; |
|
84 } |
|
85 bool operator==(const nsStyleCoord& aOther) const; |
|
86 bool operator!=(const nsStyleCoord& aOther) const; |
|
87 |
|
88 nsStyleUnit GetUnit() const { |
|
89 NS_ASSERTION(mUnit != eStyleUnit_Null, "reading uninitialized value"); |
|
90 return mUnit; |
|
91 } |
|
92 |
|
93 bool IsAngleValue() const { |
|
94 return eStyleUnit_Degree <= mUnit && mUnit <= eStyleUnit_Turn; |
|
95 } |
|
96 |
|
97 bool IsCalcUnit() const { |
|
98 return eStyleUnit_Calc == mUnit; |
|
99 } |
|
100 |
|
101 bool IsPointerValue() const { |
|
102 return IsCalcUnit(); |
|
103 } |
|
104 |
|
105 bool IsCoordPercentCalcUnit() const { |
|
106 return mUnit == eStyleUnit_Coord || |
|
107 mUnit == eStyleUnit_Percent || |
|
108 IsCalcUnit(); |
|
109 } |
|
110 |
|
111 // Does this calc() expression have any percentages inside it? Can be |
|
112 // called only when IsCalcUnit() is true. |
|
113 bool CalcHasPercent() const { |
|
114 return GetCalcValue()->mHasPercent; |
|
115 } |
|
116 |
|
117 bool HasPercent() const { |
|
118 return mUnit == eStyleUnit_Percent || |
|
119 (IsCalcUnit() && CalcHasPercent()); |
|
120 } |
|
121 |
|
122 bool ConvertsToLength() const { |
|
123 return mUnit == eStyleUnit_Coord || |
|
124 (IsCalcUnit() && !CalcHasPercent()); |
|
125 } |
|
126 |
|
127 nscoord GetCoordValue() const; |
|
128 int32_t GetIntValue() const; |
|
129 float GetPercentValue() const; |
|
130 float GetFactorValue() const; |
|
131 float GetAngleValue() const; |
|
132 double GetAngleValueInRadians() const; |
|
133 float GetFlexFractionValue() const; |
|
134 Calc* GetCalcValue() const; |
|
135 void GetUnionValue(nsStyleUnion& aValue) const; |
|
136 uint32_t HashValue(uint32_t aHash) const; |
|
137 |
|
138 void Reset(); // sets to null |
|
139 void SetCoordValue(nscoord aValue); |
|
140 void SetIntValue(int32_t aValue, nsStyleUnit aUnit); |
|
141 void SetPercentValue(float aValue); |
|
142 void SetFactorValue(float aValue); |
|
143 void SetAngleValue(float aValue, nsStyleUnit aUnit); |
|
144 void SetFlexFractionValue(float aValue); |
|
145 void SetNormalValue(); |
|
146 void SetAutoValue(); |
|
147 void SetNoneValue(); |
|
148 void SetCalcValue(Calc* aValue); |
|
149 |
|
150 private: |
|
151 nsStyleUnit mUnit; |
|
152 nsStyleUnion mValue; |
|
153 }; |
|
154 |
|
155 /** |
|
156 * Class that represents a set of top/right/bottom/left nsStyleCoords. |
|
157 * This is commonly used to hold the widths of the borders, margins, |
|
158 * or paddings of a box. |
|
159 */ |
|
160 class nsStyleSides { |
|
161 public: |
|
162 nsStyleSides(); |
|
163 |
|
164 // nsStyleSides& operator=(const nsStyleSides& aCopy); // use compiler's version |
|
165 bool operator==(const nsStyleSides& aOther) const; |
|
166 bool operator!=(const nsStyleSides& aOther) const; |
|
167 |
|
168 inline nsStyleUnit GetUnit(mozilla::css::Side aSide) const; |
|
169 inline nsStyleUnit GetLeftUnit() const; |
|
170 inline nsStyleUnit GetTopUnit() const; |
|
171 inline nsStyleUnit GetRightUnit() const; |
|
172 inline nsStyleUnit GetBottomUnit() const; |
|
173 |
|
174 inline nsStyleCoord Get(mozilla::css::Side aSide) const; |
|
175 inline nsStyleCoord GetLeft() const; |
|
176 inline nsStyleCoord GetTop() const; |
|
177 inline nsStyleCoord GetRight() const; |
|
178 inline nsStyleCoord GetBottom() const; |
|
179 |
|
180 void Reset(); |
|
181 |
|
182 inline void Set(mozilla::css::Side aSide, const nsStyleCoord& aCoord); |
|
183 inline void SetLeft(const nsStyleCoord& aCoord); |
|
184 inline void SetTop(const nsStyleCoord& aCoord); |
|
185 inline void SetRight(const nsStyleCoord& aCoord); |
|
186 inline void SetBottom(const nsStyleCoord& aCoord); |
|
187 |
|
188 protected: |
|
189 uint8_t mUnits[4]; |
|
190 nsStyleUnion mValues[4]; |
|
191 }; |
|
192 |
|
193 /** |
|
194 * Class that represents a set of top-left/top-right/bottom-left/bottom-right |
|
195 * nsStyleCoord pairs. This is used to hold the dimensions of the |
|
196 * corners of a box (for, e.g., border-radius and outline-radius). |
|
197 */ |
|
198 class nsStyleCorners { |
|
199 public: |
|
200 nsStyleCorners(); |
|
201 |
|
202 // use compiler's version |
|
203 //nsStyleCorners& operator=(const nsStyleCorners& aCopy); |
|
204 bool operator==(const nsStyleCorners& aOther) const; |
|
205 bool operator!=(const nsStyleCorners& aOther) const; |
|
206 |
|
207 // aCorner is always one of NS_CORNER_* defined in nsStyleConsts.h |
|
208 inline nsStyleUnit GetUnit(uint8_t aHalfCorner) const; |
|
209 |
|
210 inline nsStyleCoord Get(uint8_t aHalfCorner) const; |
|
211 |
|
212 void Reset(); |
|
213 |
|
214 inline void Set(uint8_t aHalfCorner, const nsStyleCoord& aCoord); |
|
215 |
|
216 protected: |
|
217 uint8_t mUnits[8]; |
|
218 nsStyleUnion mValues[8]; |
|
219 }; |
|
220 |
|
221 |
|
222 // ------------------------- |
|
223 // nsStyleCoord inlines |
|
224 // |
|
225 inline nsStyleCoord::nsStyleCoord(nscoord aValue, CoordConstructorType) |
|
226 : mUnit(eStyleUnit_Coord) |
|
227 { |
|
228 mValue.mInt = aValue; |
|
229 } |
|
230 |
|
231 // FIXME: In C++0x we can rely on the default copy constructor since |
|
232 // default copy construction is defined properly for unions. But when |
|
233 // can we actually use that? (It seems to work in gcc 4.4.) |
|
234 inline nsStyleCoord::nsStyleCoord(const nsStyleCoord& aCopy) |
|
235 : mUnit(aCopy.mUnit) |
|
236 { |
|
237 if ((eStyleUnit_Percent <= mUnit) && (mUnit < eStyleUnit_Coord)) { |
|
238 mValue.mFloat = aCopy.mValue.mFloat; |
|
239 } |
|
240 else if (IsPointerValue()) { |
|
241 mValue.mPointer = aCopy.mValue.mPointer; |
|
242 } |
|
243 else { |
|
244 mValue.mInt = aCopy.mValue.mInt; |
|
245 } |
|
246 } |
|
247 |
|
248 inline nsStyleCoord::nsStyleCoord(const nsStyleUnion& aValue, nsStyleUnit aUnit) |
|
249 : mUnit(aUnit), mValue(aValue) |
|
250 { |
|
251 } |
|
252 |
|
253 inline bool nsStyleCoord::operator!=(const nsStyleCoord& aOther) const |
|
254 { |
|
255 return !((*this) == aOther); |
|
256 } |
|
257 |
|
258 inline nscoord nsStyleCoord::GetCoordValue() const |
|
259 { |
|
260 NS_ASSERTION((mUnit == eStyleUnit_Coord), "not a coord value"); |
|
261 if (mUnit == eStyleUnit_Coord) { |
|
262 return mValue.mInt; |
|
263 } |
|
264 return 0; |
|
265 } |
|
266 |
|
267 inline int32_t nsStyleCoord::GetIntValue() const |
|
268 { |
|
269 NS_ASSERTION((mUnit == eStyleUnit_Enumerated) || |
|
270 (mUnit == eStyleUnit_Integer), "not an int value"); |
|
271 if ((mUnit == eStyleUnit_Enumerated) || |
|
272 (mUnit == eStyleUnit_Integer)) { |
|
273 return mValue.mInt; |
|
274 } |
|
275 return 0; |
|
276 } |
|
277 |
|
278 inline float nsStyleCoord::GetPercentValue() const |
|
279 { |
|
280 NS_ASSERTION(mUnit == eStyleUnit_Percent, "not a percent value"); |
|
281 if (mUnit == eStyleUnit_Percent) { |
|
282 return mValue.mFloat; |
|
283 } |
|
284 return 0.0f; |
|
285 } |
|
286 |
|
287 inline float nsStyleCoord::GetFactorValue() const |
|
288 { |
|
289 NS_ASSERTION(mUnit == eStyleUnit_Factor, "not a factor value"); |
|
290 if (mUnit == eStyleUnit_Factor) { |
|
291 return mValue.mFloat; |
|
292 } |
|
293 return 0.0f; |
|
294 } |
|
295 |
|
296 inline float nsStyleCoord::GetAngleValue() const |
|
297 { |
|
298 NS_ASSERTION(mUnit >= eStyleUnit_Degree && |
|
299 mUnit <= eStyleUnit_Turn, "not an angle value"); |
|
300 if (mUnit >= eStyleUnit_Degree && mUnit <= eStyleUnit_Turn) { |
|
301 return mValue.mFloat; |
|
302 } |
|
303 return 0.0f; |
|
304 } |
|
305 |
|
306 inline float nsStyleCoord::GetFlexFractionValue() const |
|
307 { |
|
308 NS_ASSERTION(mUnit == eStyleUnit_FlexFraction, "not a fr value"); |
|
309 if (mUnit == eStyleUnit_FlexFraction) { |
|
310 return mValue.mFloat; |
|
311 } |
|
312 return 0.0f; |
|
313 } |
|
314 |
|
315 inline nsStyleCoord::Calc* nsStyleCoord::GetCalcValue() const |
|
316 { |
|
317 NS_ASSERTION(IsCalcUnit(), "not a pointer value"); |
|
318 if (IsCalcUnit()) { |
|
319 return static_cast<Calc*>(mValue.mPointer); |
|
320 } |
|
321 return nullptr; |
|
322 } |
|
323 |
|
324 |
|
325 inline void nsStyleCoord::GetUnionValue(nsStyleUnion& aValue) const |
|
326 { |
|
327 aValue = mValue; |
|
328 } |
|
329 |
|
330 // ------------------------- |
|
331 // nsStyleSides inlines |
|
332 // |
|
333 inline bool nsStyleSides::operator!=(const nsStyleSides& aOther) const |
|
334 { |
|
335 return !((*this) == aOther); |
|
336 } |
|
337 |
|
338 inline nsStyleUnit nsStyleSides::GetUnit(mozilla::css::Side aSide) const |
|
339 { |
|
340 return (nsStyleUnit)mUnits[aSide]; |
|
341 } |
|
342 |
|
343 inline nsStyleUnit nsStyleSides::GetLeftUnit() const |
|
344 { |
|
345 return GetUnit(NS_SIDE_LEFT); |
|
346 } |
|
347 |
|
348 inline nsStyleUnit nsStyleSides::GetTopUnit() const |
|
349 { |
|
350 return GetUnit(NS_SIDE_TOP); |
|
351 } |
|
352 |
|
353 inline nsStyleUnit nsStyleSides::GetRightUnit() const |
|
354 { |
|
355 return GetUnit(NS_SIDE_RIGHT); |
|
356 } |
|
357 |
|
358 inline nsStyleUnit nsStyleSides::GetBottomUnit() const |
|
359 { |
|
360 return GetUnit(NS_SIDE_BOTTOM); |
|
361 } |
|
362 |
|
363 inline nsStyleCoord nsStyleSides::Get(mozilla::css::Side aSide) const |
|
364 { |
|
365 return nsStyleCoord(mValues[aSide], nsStyleUnit(mUnits[aSide])); |
|
366 } |
|
367 |
|
368 inline nsStyleCoord nsStyleSides::GetLeft() const |
|
369 { |
|
370 return Get(NS_SIDE_LEFT); |
|
371 } |
|
372 |
|
373 inline nsStyleCoord nsStyleSides::GetTop() const |
|
374 { |
|
375 return Get(NS_SIDE_TOP); |
|
376 } |
|
377 |
|
378 inline nsStyleCoord nsStyleSides::GetRight() const |
|
379 { |
|
380 return Get(NS_SIDE_RIGHT); |
|
381 } |
|
382 |
|
383 inline nsStyleCoord nsStyleSides::GetBottom() const |
|
384 { |
|
385 return Get(NS_SIDE_BOTTOM); |
|
386 } |
|
387 |
|
388 inline void nsStyleSides::Set(mozilla::css::Side aSide, const nsStyleCoord& aCoord) |
|
389 { |
|
390 mUnits[aSide] = aCoord.GetUnit(); |
|
391 aCoord.GetUnionValue(mValues[aSide]); |
|
392 } |
|
393 |
|
394 inline void nsStyleSides::SetLeft(const nsStyleCoord& aCoord) |
|
395 { |
|
396 Set(NS_SIDE_LEFT, aCoord); |
|
397 } |
|
398 |
|
399 inline void nsStyleSides::SetTop(const nsStyleCoord& aCoord) |
|
400 { |
|
401 Set(NS_SIDE_TOP, aCoord); |
|
402 } |
|
403 |
|
404 inline void nsStyleSides::SetRight(const nsStyleCoord& aCoord) |
|
405 { |
|
406 Set(NS_SIDE_RIGHT, aCoord); |
|
407 } |
|
408 |
|
409 inline void nsStyleSides::SetBottom(const nsStyleCoord& aCoord) |
|
410 { |
|
411 Set(NS_SIDE_BOTTOM, aCoord); |
|
412 } |
|
413 |
|
414 // ------------------------- |
|
415 // nsStyleCorners inlines |
|
416 // |
|
417 inline bool nsStyleCorners::operator!=(const nsStyleCorners& aOther) const |
|
418 { |
|
419 return !((*this) == aOther); |
|
420 } |
|
421 |
|
422 inline nsStyleUnit nsStyleCorners::GetUnit(uint8_t aCorner) const |
|
423 { |
|
424 return (nsStyleUnit)mUnits[aCorner]; |
|
425 } |
|
426 |
|
427 inline nsStyleCoord nsStyleCorners::Get(uint8_t aCorner) const |
|
428 { |
|
429 return nsStyleCoord(mValues[aCorner], nsStyleUnit(mUnits[aCorner])); |
|
430 } |
|
431 |
|
432 inline void nsStyleCorners::Set(uint8_t aCorner, const nsStyleCoord& aCoord) |
|
433 { |
|
434 mUnits[aCorner] = aCoord.GetUnit(); |
|
435 aCoord.GetUnionValue(mValues[aCorner]); |
|
436 } |
|
437 |
|
438 #endif /* nsStyleCoord_h___ */ |