Bumping manifests a=b2g-bump
[gecko.git] / layout / style / nsStyleCoord.h
blob1827a68ac78ce9ea0bbcffa1f4ab6b24d8d10c36
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/. */
6 /* representation of length values in computed style data */
8 #ifndef nsStyleCoord_h___
9 #define nsStyleCoord_h___
11 #include "nsCoord.h"
12 #include "nsStyleConsts.h"
14 enum nsStyleUnit : uint8_t {
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
30 // The following are reference counted allocated types.
31 eStyleUnit_Calc = 40, // (Calc*) calc() toplevel; always present
32 // to distinguish 50% from calc(50%), etc.
34 eStyleUnit_MAX = 40 // highest valid nsStyleUnit value
37 typedef union {
38 int32_t mInt; // nscoord is a int32_t for now
39 float mFloat;
40 // An mPointer is a reference counted pointer. Currently this can only
41 // ever be an nsStyleCoord::Calc*.
42 void* mPointer;
43 } nsStyleUnion;
45 /**
46 * Class that hold a single size specification used by the style
47 * system. The size specification consists of two parts -- a number
48 * and a unit. The number is an integer, a floating point value, an
49 * nscoord, or undefined, and the unit is an nsStyleUnit. Checking
50 * the unit is a must before asking for the value in any particular
51 * form.
53 class nsStyleCoord {
54 public:
55 // Non-reference counted calc() value. See nsStyleStruct.h for some uses
56 // of this.
57 struct CalcValue {
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
63 bool operator==(const CalcValue& aOther) const {
64 return mLength == aOther.mLength &&
65 mPercent == aOther.mPercent &&
66 mHasPercent == aOther.mHasPercent;
68 bool operator!=(const CalcValue& aOther) const {
69 return !(*this == aOther);
73 // Reference counted calc() value. This is the type that is used to store
74 // the calc() value in nsStyleCoord.
75 struct Calc MOZ_FINAL : public CalcValue {
76 NS_INLINE_DECL_REFCOUNTING(Calc)
77 Calc() {}
79 private:
80 Calc(const Calc&) = delete;
81 ~Calc() {}
82 Calc& operator=(const Calc&) = delete;
85 explicit nsStyleCoord(nsStyleUnit aUnit = eStyleUnit_Null);
86 enum CoordConstructorType { CoordConstructor };
87 inline nsStyleCoord(nscoord aValue, CoordConstructorType);
88 nsStyleCoord(int32_t aValue, nsStyleUnit aUnit);
89 nsStyleCoord(float aValue, nsStyleUnit aUnit);
90 inline nsStyleCoord(const nsStyleCoord& aCopy);
91 inline nsStyleCoord(const nsStyleUnion& aValue, nsStyleUnit aUnit);
92 ~nsStyleCoord() { Reset(); }
94 nsStyleCoord& operator=(const nsStyleCoord& aOther)
96 if (this != &aOther) {
97 SetValue(mUnit, mValue, aOther);
99 return *this;
101 bool operator==(const nsStyleCoord& aOther) const;
102 bool operator!=(const nsStyleCoord& aOther) const;
104 nsStyleUnit GetUnit() const {
105 NS_ASSERTION(mUnit != eStyleUnit_Null, "reading uninitialized value");
106 return mUnit;
109 bool IsAngleValue() const {
110 return eStyleUnit_Degree <= mUnit && mUnit <= eStyleUnit_Turn;
113 static bool IsCalcUnit(nsStyleUnit aUnit) {
114 return aUnit == eStyleUnit_Calc;
117 static bool IsPointerUnit(nsStyleUnit aUnit) {
118 return IsCalcUnit(aUnit);
121 bool IsCalcUnit() const {
122 return IsCalcUnit(mUnit);
125 bool IsPointerValue() const {
126 return IsPointerUnit(mUnit);
129 bool IsCoordPercentCalcUnit() const {
130 return mUnit == eStyleUnit_Coord ||
131 mUnit == eStyleUnit_Percent ||
132 IsCalcUnit();
135 // Does this calc() expression have any percentages inside it? Can be
136 // called only when IsCalcUnit() is true.
137 bool CalcHasPercent() const {
138 return GetCalcValue()->mHasPercent;
141 bool HasPercent() const {
142 return mUnit == eStyleUnit_Percent ||
143 (IsCalcUnit() && CalcHasPercent());
146 bool ConvertsToLength() const {
147 return mUnit == eStyleUnit_Coord ||
148 (IsCalcUnit() && !CalcHasPercent());
151 nscoord GetCoordValue() const;
152 int32_t GetIntValue() const;
153 float GetPercentValue() const;
154 float GetFactorValue() const;
155 float GetFactorOrPercentValue() const;
156 float GetAngleValue() const;
157 double GetAngleValueInDegrees() const;
158 double GetAngleValueInRadians() const;
159 float GetFlexFractionValue() const;
160 Calc* GetCalcValue() const;
161 uint32_t HashValue(uint32_t aHash) const;
163 // Sets to null and releases any refcounted objects. Only use this if the
164 // object is initialized (i.e. don't use it in nsStyleCoord constructors).
165 void Reset();
167 void SetCoordValue(nscoord aValue);
168 void SetIntValue(int32_t aValue, nsStyleUnit aUnit);
169 void SetPercentValue(float aValue);
170 void SetFactorValue(float aValue);
171 void SetAngleValue(float aValue, nsStyleUnit aUnit);
172 void SetFlexFractionValue(float aValue);
173 void SetNormalValue();
174 void SetAutoValue();
175 void SetNoneValue();
176 void SetCalcValue(Calc* aValue);
178 // Resets a coord represented by a unit/value pair.
179 static inline void Reset(nsStyleUnit& aUnit, nsStyleUnion& aValue);
181 // Sets a coord represented by a unit/value pair from a second
182 // unit/value pair.
183 static inline void SetValue(nsStyleUnit& aUnit,
184 nsStyleUnion& aValue,
185 nsStyleUnit aOtherUnit,
186 const nsStyleUnion& aOtherValue);
188 // Sets a coord represented by a unit/value pair from an nsStyleCoord.
189 static inline void SetValue(nsStyleUnit& aUnit, nsStyleUnion& aValue,
190 const nsStyleCoord& aOther);
192 private:
193 nsStyleUnit mUnit;
194 nsStyleUnion mValue;
198 * Class that represents a set of top/right/bottom/left nsStyleCoords.
199 * This is commonly used to hold the widths of the borders, margins,
200 * or paddings of a box.
202 class nsStyleSides {
203 public:
204 nsStyleSides();
205 nsStyleSides(const nsStyleSides&);
206 ~nsStyleSides();
208 nsStyleSides& operator=(const nsStyleSides& aCopy);
209 bool operator==(const nsStyleSides& aOther) const;
210 bool operator!=(const nsStyleSides& aOther) const;
212 inline nsStyleUnit GetUnit(mozilla::css::Side aSide) const;
213 inline nsStyleUnit GetLeftUnit() const;
214 inline nsStyleUnit GetTopUnit() const;
215 inline nsStyleUnit GetRightUnit() const;
216 inline nsStyleUnit GetBottomUnit() const;
218 inline nsStyleCoord Get(mozilla::css::Side aSide) const;
219 inline nsStyleCoord GetLeft() const;
220 inline nsStyleCoord GetTop() const;
221 inline nsStyleCoord GetRight() const;
222 inline nsStyleCoord GetBottom() const;
224 // Sets each side to null and releases any refcounted objects. Only use this
225 // if the object is initialized (i.e. don't use it in nsStyleSides
226 // constructors).
227 void Reset();
229 inline void Set(mozilla::css::Side aSide, const nsStyleCoord& aCoord);
230 inline void SetLeft(const nsStyleCoord& aCoord);
231 inline void SetTop(const nsStyleCoord& aCoord);
232 inline void SetRight(const nsStyleCoord& aCoord);
233 inline void SetBottom(const nsStyleCoord& aCoord);
235 protected:
236 nsStyleUnit mUnits[4];
237 nsStyleUnion mValues[4];
241 * Class that represents a set of top-left/top-right/bottom-left/bottom-right
242 * nsStyleCoord pairs. This is used to hold the dimensions of the
243 * corners of a box (for, e.g., border-radius and outline-radius).
245 class nsStyleCorners {
246 public:
247 nsStyleCorners();
248 nsStyleCorners(const nsStyleCorners&);
249 ~nsStyleCorners();
251 // use compiler's version
252 nsStyleCorners& operator=(const nsStyleCorners& aCopy);
253 bool operator==(const nsStyleCorners& aOther) const;
254 bool operator!=(const nsStyleCorners& aOther) const;
256 // aCorner is always one of NS_CORNER_* defined in nsStyleConsts.h
257 inline nsStyleUnit GetUnit(uint8_t aHalfCorner) const;
259 inline nsStyleCoord Get(uint8_t aHalfCorner) const;
261 // Sets each corner to null and releases any refcounted objects. Only use
262 // this if the object is initialized (i.e. don't use it in nsStyleCorners
263 // constructors).
264 void Reset();
266 inline void Set(uint8_t aHalfCorner, const nsStyleCoord& aCoord);
268 protected:
269 nsStyleUnit mUnits[8];
270 nsStyleUnion mValues[8];
274 // -------------------------
275 // nsStyleCoord inlines
277 inline nsStyleCoord::nsStyleCoord(nscoord aValue, CoordConstructorType)
278 : mUnit(eStyleUnit_Coord)
280 mValue.mInt = aValue;
283 inline nsStyleCoord::nsStyleCoord(const nsStyleCoord& aCopy)
284 : mUnit(eStyleUnit_Null)
286 SetValue(mUnit, mValue, aCopy);
289 inline nsStyleCoord::nsStyleCoord(const nsStyleUnion& aValue, nsStyleUnit aUnit)
290 : mUnit(eStyleUnit_Null)
292 SetValue(mUnit, mValue, aUnit, aValue);
295 inline bool nsStyleCoord::operator!=(const nsStyleCoord& aOther) const
297 return !((*this) == aOther);
300 inline nscoord nsStyleCoord::GetCoordValue() const
302 NS_ASSERTION((mUnit == eStyleUnit_Coord), "not a coord value");
303 if (mUnit == eStyleUnit_Coord) {
304 return mValue.mInt;
306 return 0;
309 inline int32_t nsStyleCoord::GetIntValue() const
311 NS_ASSERTION((mUnit == eStyleUnit_Enumerated) ||
312 (mUnit == eStyleUnit_Integer), "not an int value");
313 if ((mUnit == eStyleUnit_Enumerated) ||
314 (mUnit == eStyleUnit_Integer)) {
315 return mValue.mInt;
317 return 0;
320 inline float nsStyleCoord::GetPercentValue() const
322 NS_ASSERTION(mUnit == eStyleUnit_Percent, "not a percent value");
323 if (mUnit == eStyleUnit_Percent) {
324 return mValue.mFloat;
326 return 0.0f;
329 inline float nsStyleCoord::GetFactorValue() const
331 NS_ASSERTION(mUnit == eStyleUnit_Factor, "not a factor value");
332 if (mUnit == eStyleUnit_Factor) {
333 return mValue.mFloat;
335 return 0.0f;
338 inline float nsStyleCoord::GetFactorOrPercentValue() const
340 NS_ASSERTION(mUnit == eStyleUnit_Factor || mUnit == eStyleUnit_Percent,
341 "not a percent or factor value");
342 if (mUnit == eStyleUnit_Factor || mUnit == eStyleUnit_Percent) {
343 return mValue.mFloat;
345 return 0.0f;
348 inline float nsStyleCoord::GetAngleValue() const
350 NS_ASSERTION(mUnit >= eStyleUnit_Degree &&
351 mUnit <= eStyleUnit_Turn, "not an angle value");
352 if (mUnit >= eStyleUnit_Degree && mUnit <= eStyleUnit_Turn) {
353 return mValue.mFloat;
355 return 0.0f;
358 inline float nsStyleCoord::GetFlexFractionValue() const
360 NS_ASSERTION(mUnit == eStyleUnit_FlexFraction, "not a fr value");
361 if (mUnit == eStyleUnit_FlexFraction) {
362 return mValue.mFloat;
364 return 0.0f;
367 inline nsStyleCoord::Calc* nsStyleCoord::GetCalcValue() const
369 NS_ASSERTION(IsCalcUnit(), "not a pointer value");
370 if (IsCalcUnit()) {
371 return static_cast<Calc*>(mValue.mPointer);
373 return nullptr;
376 /* static */ inline void
377 nsStyleCoord::Reset(nsStyleUnit& aUnit, nsStyleUnion& aValue)
379 MOZ_ASSERT(aUnit <= eStyleUnit_MAX,
380 "calling Reset on uninitialized nsStyleCoord?");
382 switch (aUnit) {
383 case eStyleUnit_Calc:
384 static_cast<Calc*>(aValue.mPointer)->Release();
385 break;
386 default:
387 MOZ_ASSERT(!IsPointerUnit(aUnit), "check pointer refcounting logic");
390 aUnit = eStyleUnit_Null;
391 aValue.mInt = 0;
394 /* static */ inline void
395 nsStyleCoord::SetValue(nsStyleUnit& aUnit,
396 nsStyleUnion& aValue,
397 nsStyleUnit aOtherUnit,
398 const nsStyleUnion& aOtherValue)
400 Reset(aUnit, aValue);
402 aUnit = aOtherUnit;
403 aValue = aOtherValue;
405 switch (aUnit) {
406 case eStyleUnit_Calc:
407 static_cast<Calc*>(aValue.mPointer)->AddRef();
408 break;
409 default:
410 MOZ_ASSERT(!IsPointerUnit(aUnit), "check pointer refcounting logic");
414 /* static */ inline void
415 nsStyleCoord::SetValue(nsStyleUnit& aUnit, nsStyleUnion& aValue,
416 const nsStyleCoord& aOther)
418 SetValue(aUnit, aValue, aOther.mUnit, aOther.mValue);
422 // -------------------------
423 // nsStyleSides inlines
425 inline bool nsStyleSides::operator!=(const nsStyleSides& aOther) const
427 return !((*this) == aOther);
430 inline nsStyleUnit nsStyleSides::GetUnit(mozilla::css::Side aSide) const
432 return (nsStyleUnit)mUnits[aSide];
435 inline nsStyleUnit nsStyleSides::GetLeftUnit() const
437 return GetUnit(NS_SIDE_LEFT);
440 inline nsStyleUnit nsStyleSides::GetTopUnit() const
442 return GetUnit(NS_SIDE_TOP);
445 inline nsStyleUnit nsStyleSides::GetRightUnit() const
447 return GetUnit(NS_SIDE_RIGHT);
450 inline nsStyleUnit nsStyleSides::GetBottomUnit() const
452 return GetUnit(NS_SIDE_BOTTOM);
455 inline nsStyleCoord nsStyleSides::Get(mozilla::css::Side aSide) const
457 return nsStyleCoord(mValues[aSide], nsStyleUnit(mUnits[aSide]));
460 inline nsStyleCoord nsStyleSides::GetLeft() const
462 return Get(NS_SIDE_LEFT);
465 inline nsStyleCoord nsStyleSides::GetTop() const
467 return Get(NS_SIDE_TOP);
470 inline nsStyleCoord nsStyleSides::GetRight() const
472 return Get(NS_SIDE_RIGHT);
475 inline nsStyleCoord nsStyleSides::GetBottom() const
477 return Get(NS_SIDE_BOTTOM);
480 inline void nsStyleSides::Set(mozilla::css::Side aSide, const nsStyleCoord& aCoord)
482 nsStyleCoord::SetValue(mUnits[aSide], mValues[aSide], aCoord);
485 inline void nsStyleSides::SetLeft(const nsStyleCoord& aCoord)
487 Set(NS_SIDE_LEFT, aCoord);
490 inline void nsStyleSides::SetTop(const nsStyleCoord& aCoord)
492 Set(NS_SIDE_TOP, aCoord);
495 inline void nsStyleSides::SetRight(const nsStyleCoord& aCoord)
497 Set(NS_SIDE_RIGHT, aCoord);
500 inline void nsStyleSides::SetBottom(const nsStyleCoord& aCoord)
502 Set(NS_SIDE_BOTTOM, aCoord);
505 // -------------------------
506 // nsStyleCorners inlines
508 inline bool nsStyleCorners::operator!=(const nsStyleCorners& aOther) const
510 return !((*this) == aOther);
513 inline nsStyleUnit nsStyleCorners::GetUnit(uint8_t aCorner) const
515 return (nsStyleUnit)mUnits[aCorner];
518 inline nsStyleCoord nsStyleCorners::Get(uint8_t aCorner) const
520 return nsStyleCoord(mValues[aCorner], nsStyleUnit(mUnits[aCorner]));
523 inline void nsStyleCorners::Set(uint8_t aCorner, const nsStyleCoord& aCoord)
525 nsStyleCoord::SetValue(mUnits[aCorner], mValues[aCorner], aCoord);
528 #endif /* nsStyleCoord_h___ */