1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 /* representation of length values in computed style data */
8 
9 #ifndef nsStyleCoord_h___
10 #define nsStyleCoord_h___
11 
12 #include <type_traits>
13 
14 #include "mozilla/EnumTypeTraits.h"
15 #include "mozilla/gfx/Types.h"
16 #include "nsCoord.h"
17 #include "nsISupportsImpl.h"
18 #include "nsStyleConsts.h"
19 
20 namespace mozilla {
21 
22 class WritingMode;
23 
24 // Logical axis, edge, side and corner constants for use in various places.
25 enum LogicalAxis { eLogicalAxisBlock = 0x0, eLogicalAxisInline = 0x1 };
26 enum LogicalEdge { eLogicalEdgeStart = 0x0, eLogicalEdgeEnd = 0x1 };
27 enum LogicalSide {
28   eLogicalSideBStart = (eLogicalAxisBlock << 1) | eLogicalEdgeStart,   // 0x0
29   eLogicalSideBEnd = (eLogicalAxisBlock << 1) | eLogicalEdgeEnd,       // 0x1
30   eLogicalSideIStart = (eLogicalAxisInline << 1) | eLogicalEdgeStart,  // 0x2
31   eLogicalSideIEnd = (eLogicalAxisInline << 1) | eLogicalEdgeEnd       // 0x3
32 };
33 
34 enum LogicalCorner {
35   eLogicalCornerBStartIStart = 0,
36   eLogicalCornerBStartIEnd = 1,
37   eLogicalCornerBEndIEnd = 2,
38   eLogicalCornerBEndIStart = 3
39 };
40 
41 }  // namespace mozilla
42 
43 enum nsStyleUnit : uint8_t {
44   eStyleUnit_Null = 0,           // (no value) value is not specified
45   eStyleUnit_Normal = 1,         // (no value)
46   eStyleUnit_Auto = 2,           // (no value)
47   eStyleUnit_None = 3,           // (no value)
48   eStyleUnit_Percent = 10,       // (float) 1.0 == 100%
49   eStyleUnit_Factor = 11,        // (float) a multiplier
50   eStyleUnit_Degree = 12,        // (float) angle in degrees
51   eStyleUnit_Grad = 13,          // (float) angle in grads
52   eStyleUnit_Radian = 14,        // (float) angle in radians
53   eStyleUnit_Turn = 15,          // (float) angle in turns
54   eStyleUnit_FlexFraction = 16,  // (float) <flex> in fr units
55   eStyleUnit_Coord = 20,         // (nscoord) value is twips
56   eStyleUnit_Integer = 30,       // (int) value is simple integer
57   eStyleUnit_Enumerated = 32,    // (int) value has enumerated meaning
58 
59   // The following are reference counted allocated types.
60   eStyleUnit_Calc = 40,  // (Calc*) calc() toplevel; always present
61                          // to distinguish 50% from calc(50%), etc.
62 
63   eStyleUnit_MAX = 40  // highest valid nsStyleUnit value
64 };
65 
66 typedef union {
67   int32_t mInt;  // nscoord is a int32_t for now
68   float mFloat;
69   // An mPointer is a reference counted pointer.  Currently this can only
70   // ever be an nsStyleCoord::Calc*.
71   void* mPointer;
72 } nsStyleUnion;
73 
74 /**
75  * Class that hold a single size specification used by the style
76  * system.  The size specification consists of two parts -- a number
77  * and a unit.  The number is an integer, a floating point value, an
78  * nscoord, or undefined, and the unit is an nsStyleUnit.  Checking
79  * the unit is a must before asking for the value in any particular
80  * form.
81  */
82 /** <div rustbindgen private accessor="unsafe"></div> */
83 class nsStyleCoord {
84  public:
85   // Non-reference counted calc() value.  See nsStyleStruct.h for some uses
86   // of this.
87   struct CalcValue {
88     // Every calc() expression evaluates to a length plus a percentage.
89     nscoord mLength;
90     float mPercent;
91     bool mHasPercent;  // whether there was any % syntax, even if 0
92 
93     bool operator==(const CalcValue& aOther) const {
94       return mLength == aOther.mLength && mPercent == aOther.mPercent &&
95              mHasPercent == aOther.mHasPercent;
96     }
97     bool operator!=(const CalcValue& aOther) const {
98       return !(*this == aOther);
99     }
100 
ToLengthCalcValue101     nscoord ToLength() const {
102       MOZ_ASSERT(!mHasPercent);
103       return mLength;
104     }
105 
106     // If this returns true the value is definitely zero. It it returns false
107     // it might be zero. So it's best used for conservative optimization.
IsDefinitelyZeroCalcValue108     bool IsDefinitelyZero() const { return mLength == 0 && mPercent == 0; }
109   };
110 
111   // Reference counted calc() value.  This is the type that is used to store
112   // the calc() value in nsStyleCoord.
113   struct Calc final : public CalcValue {
114     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Calc)
Calcfinal115     Calc() {}
116 
117    private:
118     Calc(const Calc&) = delete;
~Calcfinal119     ~Calc() {}
120     Calc& operator=(const Calc&) = delete;
121   };
122 
123   explicit nsStyleCoord(nsStyleUnit aUnit = eStyleUnit_Null);
124   enum CoordConstructorType { CoordConstructor };
125   inline nsStyleCoord(nscoord aValue, CoordConstructorType);
126   nsStyleCoord(int32_t aValue, nsStyleUnit aUnit);
127   nsStyleCoord(float aValue, nsStyleUnit aUnit);
128   inline nsStyleCoord(const nsStyleCoord& aCopy);
129   inline nsStyleCoord(const nsStyleUnion& aValue, nsStyleUnit aUnit);
~nsStyleCoord()130   ~nsStyleCoord() { Reset(); }
131 
132   nsStyleCoord& operator=(const nsStyleCoord& aOther) {
133     if (this != &aOther) {
134       SetValue(mUnit, mValue, aOther);
135     }
136     return *this;
137   }
138   bool operator==(const nsStyleCoord& aOther) const;
139   bool operator!=(const nsStyleCoord& aOther) const;
140 
GetUnit()141   nsStyleUnit GetUnit() const {
142     NS_ASSERTION(mUnit != eStyleUnit_Null, "reading uninitialized value");
143     return mUnit;
144   }
145 
IsAngleValue()146   bool IsAngleValue() const {
147     return eStyleUnit_Degree <= mUnit && mUnit <= eStyleUnit_Turn;
148   }
149 
IsCalcUnit(nsStyleUnit aUnit)150   static bool IsCalcUnit(nsStyleUnit aUnit) { return aUnit == eStyleUnit_Calc; }
151 
IsPointerUnit(nsStyleUnit aUnit)152   static bool IsPointerUnit(nsStyleUnit aUnit) { return IsCalcUnit(aUnit); }
153 
IsCalcUnit()154   bool IsCalcUnit() const { return IsCalcUnit(mUnit); }
155 
IsPointerValue()156   bool IsPointerValue() const { return IsPointerUnit(mUnit); }
157 
IsCoordPercentCalcUnit()158   bool IsCoordPercentCalcUnit() const {
159     return mUnit == eStyleUnit_Coord || mUnit == eStyleUnit_Percent ||
160            IsCalcUnit();
161   }
162 
163   // Does this calc() expression have any percentages inside it?  Can be
164   // called only when IsCalcUnit() is true.
CalcHasPercent()165   bool CalcHasPercent() const { return GetCalcValue()->mHasPercent; }
166 
HasPercent()167   bool HasPercent() const {
168     return mUnit == eStyleUnit_Percent || (IsCalcUnit() && CalcHasPercent());
169   }
170 
ConvertsToLength(const nsStyleUnit aUnit,const nsStyleUnion aValue)171   static bool ConvertsToLength(const nsStyleUnit aUnit,
172                                const nsStyleUnion aValue) {
173     return aUnit == eStyleUnit_Coord ||
174            (IsCalcUnit(aUnit) && !AsCalcValue(aValue)->mHasPercent);
175   }
176 
ConvertsToLength()177   bool ConvertsToLength() const { return ConvertsToLength(mUnit, mValue); }
178 
ToLength(nsStyleUnit aUnit,nsStyleUnion aValue)179   static nscoord ToLength(nsStyleUnit aUnit, nsStyleUnion aValue) {
180     MOZ_ASSERT(ConvertsToLength(aUnit, aValue));
181     if (IsCalcUnit(aUnit)) {
182       return AsCalcValue(aValue)
183           ->ToLength();  // Note: This asserts !mHasPercent
184     }
185     MOZ_ASSERT(aUnit == eStyleUnit_Coord);
186     return aValue.mInt;
187   }
188 
ToLength()189   nscoord ToLength() const { return ToLength(GetUnit(), mValue); }
190 
191   // Callers must verify IsCalcUnit before calling this function.
AsCalcValue(nsStyleUnion aValue)192   static Calc* AsCalcValue(nsStyleUnion aValue) {
193     return static_cast<Calc*>(aValue.mPointer);
194   }
195 
196   // Compute the value that IsCalcUnit().
197   // @note the caller is expected to handle percentage of an indefinite size
198   // and NOT call this method with aPercentageBasis == NS_UNCONSTRAINEDSIZE.
199   // @note the return value may be negative, e.g. for "calc(a - b%)"
200   nscoord ComputeComputedCalc(nscoord aPercentageBasis) const;
201 
202   // Compute the value that is either a coord, a percent, or a calc expression.
203   // @note the caller is expected to handle percentage of an indefinite size
204   // and NOT call this method with aPercentageBasis == NS_UNCONSTRAINEDSIZE.
205   // @note the return value may be negative, e.g. for "calc(a - b%)"
206   nscoord ComputeCoordPercentCalc(nscoord aPercentageBasis) const;
207 
208   nscoord GetCoordValue() const;
209   int32_t GetIntValue() const;
210   float GetPercentValue() const;
211   float GetFactorValue() const;
212   float GetFactorOrPercentValue() const;
213   float GetAngleValue() const;
214   double GetAngleValueInDegrees() const;
215   double GetAngleValueInRadians() const;
216   float GetFlexFractionValue() const;
217   Calc* GetCalcValue() const;
218   template <typename T,
219             typename = typename std::enable_if<std::is_enum<T>::value>::type>
GetEnumValue()220   T GetEnumValue() const {
221     MOZ_ASSERT(GetUnit() == eStyleUnit_Enumerated,
222                "The unit must be eStyleUnit_Enumerated!");
223     return static_cast<T>(GetIntValue());
224   }
225 
226   // Sets to null and releases any refcounted objects.  Only use this if the
227   // object is initialized (i.e. don't use it in nsStyleCoord constructors).
228   void Reset();
229 
230   void SetCoordValue(nscoord aValue);
231   void SetIntValue(int32_t aValue, nsStyleUnit aUnit);
232   void SetPercentValue(float aValue);
233   void SetFactorValue(float aValue);
234   void SetAngleValue(float aValue, nsStyleUnit aUnit);
235   void SetFlexFractionValue(float aValue);
236   void SetNormalValue();
237   void SetAutoValue();
238   void SetNoneValue();
239   void SetCalcValue(Calc* aValue);
240   template <typename T,
241             typename = typename std::enable_if<std::is_enum<T>::value>::type>
SetEnumValue(T aValue)242   void SetEnumValue(T aValue) {
243     static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
244                   "aValue must be an enum that fits within mValue.mInt!");
245     SetIntValue(static_cast<int32_t>(aValue), eStyleUnit_Enumerated);
246   }
247 
248   // Resets a coord represented by a unit/value pair.
249   static inline void Reset(nsStyleUnit& aUnit, nsStyleUnion& aValue);
250 
251   // Sets a coord represented by a unit/value pair from a second
252   // unit/value pair.
253   static inline void SetValue(nsStyleUnit& aUnit, nsStyleUnion& aValue,
254                               nsStyleUnit aOtherUnit,
255                               const nsStyleUnion& aOtherValue);
256 
257   // Sets a coord represented by a unit/value pair from an nsStyleCoord.
258   static inline void SetValue(nsStyleUnit& aUnit, nsStyleUnion& aValue,
259                               const nsStyleCoord& aOther);
260 
261   // Like the above, but do not reset before setting.
262   static inline void InitWithValue(nsStyleUnit& aUnit, nsStyleUnion& aValue,
263                                    nsStyleUnit aOtherUnit,
264                                    const nsStyleUnion& aOtherValue);
265 
266   static inline void InitWithValue(nsStyleUnit& aUnit, nsStyleUnion& aValue,
267                                    const nsStyleCoord& aOther);
268 
269  private:
270   nsStyleUnit mUnit;
271   nsStyleUnion mValue;
272 };
273 
274 /**
275  * Class that represents a set of top/right/bottom/left nsStyleCoords.
276  * This is commonly used to hold the widths of the borders, margins,
277  * or paddings of a box.
278  */
279 /** <div rustbindgen private accessor="unsafe"></div> */
280 class nsStyleSides {
281  public:
282   nsStyleSides();
283   nsStyleSides(const nsStyleSides&);
284   ~nsStyleSides();
285 
286   nsStyleSides& operator=(const nsStyleSides& aCopy);
287   bool operator==(const nsStyleSides& aOther) const;
288   bool operator!=(const nsStyleSides& aOther) const;
289 
290   inline nsStyleUnit GetUnit(mozilla::Side aSide) const;
291   inline nsStyleUnit GetLeftUnit() const;
292   inline nsStyleUnit GetTopUnit() const;
293   inline nsStyleUnit GetRightUnit() const;
294   inline nsStyleUnit GetBottomUnit() const;
295 
296   inline nsStyleCoord Get(mozilla::Side aSide) const;
297   inline nsStyleCoord GetLeft() const;
298   inline nsStyleCoord GetTop() const;
299   inline nsStyleCoord GetRight() const;
300   inline nsStyleCoord GetBottom() const;
301 
302   // Methods to access the units and values in terms of logical sides
303   // for a given writing mode.
304   // NOTE: The definitions are in WritingModes.h (after we have the full
305   // declaration of WritingMode available).
306   inline nsStyleUnit GetUnit(mozilla::WritingMode aWritingMode,
307                              mozilla::LogicalSide aSide) const;
308   inline nsStyleUnit GetIStartUnit(mozilla::WritingMode aWritingMode) const;
309   inline nsStyleUnit GetBStartUnit(mozilla::WritingMode aWritingMode) const;
310   inline nsStyleUnit GetIEndUnit(mozilla::WritingMode aWritingMode) const;
311   inline nsStyleUnit GetBEndUnit(mozilla::WritingMode aWritingMode) const;
312 
313   // Return true if either the start or end side in the axis is 'auto'.
314   inline bool HasBlockAxisAuto(mozilla::WritingMode aWritingMode) const;
315   inline bool HasInlineAxisAuto(mozilla::WritingMode aWritingMode) const;
316 
317   inline nsStyleCoord Get(mozilla::WritingMode aWritingMode,
318                           mozilla::LogicalSide aSide) const;
319   inline nsStyleCoord GetIStart(mozilla::WritingMode aWritingMode) const;
320   inline nsStyleCoord GetBStart(mozilla::WritingMode aWritingMode) const;
321   inline nsStyleCoord GetIEnd(mozilla::WritingMode aWritingMode) const;
322   inline nsStyleCoord GetBEnd(mozilla::WritingMode aWritingMode) const;
323 
324   // Sets each side to null and releases any refcounted objects.  Only use this
325   // if the object is initialized (i.e. don't use it in nsStyleSides
326   // constructors).
327   void Reset();
328 
329   inline void Set(mozilla::Side aSide, const nsStyleCoord& aCoord);
330   inline void SetLeft(const nsStyleCoord& aCoord);
331   inline void SetTop(const nsStyleCoord& aCoord);
332   inline void SetRight(const nsStyleCoord& aCoord);
333   inline void SetBottom(const nsStyleCoord& aCoord);
334 
ToLength(mozilla::Side aSide)335   nscoord ToLength(mozilla::Side aSide) const {
336     return nsStyleCoord::ToLength(mUnits[aSide], mValues[aSide]);
337   }
338 
ConvertsToLength()339   bool ConvertsToLength() const {
340     NS_FOR_CSS_SIDES(side) {
341       if (!nsStyleCoord::ConvertsToLength(mUnits[side], mValues[side])) {
342         return false;
343       }
344     }
345     return true;
346   }
347 
348  protected:
349   nsStyleUnit mUnits[4];
350   nsStyleUnion mValues[4];
351 };
352 
353 /**
354  * Class that represents a set of top-left/top-right/bottom-right/bottom-left
355  * nsStyleCoord pairs.  This is used to hold the dimensions of the
356  * corners of a box (for, e.g., border-radius and outline-radius).
357  */
358 /** <div rustbindgen private accessor="unsafe"></div> */
359 class nsStyleCorners {
360  public:
361   nsStyleCorners();
362   nsStyleCorners(const nsStyleCorners&);
363   ~nsStyleCorners();
364 
365   // use compiler's version
366   nsStyleCorners& operator=(const nsStyleCorners& aCopy);
367   bool operator==(const nsStyleCorners& aOther) const;
368   bool operator!=(const nsStyleCorners& aOther) const;
369 
370   // aHalfCorner is always one of enum HalfCorner in gfx/2d/Types.h.
371   inline nsStyleUnit GetUnit(uint8_t aHalfCorner) const;
372 
373   inline nsStyleCoord Get(uint8_t aHalfCorner) const;
374 
375   // Sets each corner to null and releases any refcounted objects.  Only use
376   // this if the object is initialized (i.e. don't use it in nsStyleCorners
377   // constructors).
378   void Reset();
379 
380   inline void Set(uint8_t aHalfCorner, const nsStyleCoord& aCoord);
381 
382  protected:
383   // Stored as:
384   // top-left.x, top-left.y,
385   // top-right.x, top-right.y,
386   // bottom-right.x, bottom-right.y,
387   // bottom-left.x, bottom-left.y
388   nsStyleUnit mUnits[8];
389   nsStyleUnion mValues[8];
390 };
391 
392 // -------------------------
393 // nsStyleCoord inlines
394 //
nsStyleCoord(nscoord aValue,CoordConstructorType)395 inline nsStyleCoord::nsStyleCoord(nscoord aValue, CoordConstructorType)
396     : mUnit(eStyleUnit_Coord) {
397   mValue.mInt = aValue;
398 }
399 
nsStyleCoord(const nsStyleCoord & aCopy)400 inline nsStyleCoord::nsStyleCoord(const nsStyleCoord& aCopy)
401     : mUnit(eStyleUnit_Null) {
402   InitWithValue(mUnit, mValue, aCopy);
403 }
404 
nsStyleCoord(const nsStyleUnion & aValue,nsStyleUnit aUnit)405 inline nsStyleCoord::nsStyleCoord(const nsStyleUnion& aValue, nsStyleUnit aUnit)
406     : mUnit(eStyleUnit_Null) {
407   InitWithValue(mUnit, mValue, aUnit, aValue);
408 }
409 
410 inline bool nsStyleCoord::operator!=(const nsStyleCoord& aOther) const {
411   return !((*this) == aOther);
412 }
413 
GetCoordValue()414 inline nscoord nsStyleCoord::GetCoordValue() const {
415   NS_ASSERTION((mUnit == eStyleUnit_Coord), "not a coord value");
416   if (mUnit == eStyleUnit_Coord) {
417     return mValue.mInt;
418   }
419   return 0;
420 }
421 
GetIntValue()422 inline int32_t nsStyleCoord::GetIntValue() const {
423   NS_ASSERTION(
424       (mUnit == eStyleUnit_Enumerated) || (mUnit == eStyleUnit_Integer),
425       "not an int value");
426   if ((mUnit == eStyleUnit_Enumerated) || (mUnit == eStyleUnit_Integer)) {
427     return mValue.mInt;
428   }
429   return 0;
430 }
431 
GetPercentValue()432 inline float nsStyleCoord::GetPercentValue() const {
433   NS_ASSERTION(mUnit == eStyleUnit_Percent, "not a percent value");
434   if (mUnit == eStyleUnit_Percent) {
435     return mValue.mFloat;
436   }
437   return 0.0f;
438 }
439 
GetFactorValue()440 inline float nsStyleCoord::GetFactorValue() const {
441   NS_ASSERTION(mUnit == eStyleUnit_Factor, "not a factor value");
442   if (mUnit == eStyleUnit_Factor) {
443     return mValue.mFloat;
444   }
445   return 0.0f;
446 }
447 
GetFactorOrPercentValue()448 inline float nsStyleCoord::GetFactorOrPercentValue() const {
449   NS_ASSERTION(mUnit == eStyleUnit_Factor || mUnit == eStyleUnit_Percent,
450                "not a percent or factor value");
451   if (mUnit == eStyleUnit_Factor || mUnit == eStyleUnit_Percent) {
452     return mValue.mFloat;
453   }
454   return 0.0f;
455 }
456 
GetAngleValue()457 inline float nsStyleCoord::GetAngleValue() const {
458   NS_ASSERTION(mUnit >= eStyleUnit_Degree && mUnit <= eStyleUnit_Turn,
459                "not an angle value");
460   if (mUnit >= eStyleUnit_Degree && mUnit <= eStyleUnit_Turn) {
461     return mValue.mFloat;
462   }
463   return 0.0f;
464 }
465 
GetFlexFractionValue()466 inline float nsStyleCoord::GetFlexFractionValue() const {
467   NS_ASSERTION(mUnit == eStyleUnit_FlexFraction, "not a fr value");
468   if (mUnit == eStyleUnit_FlexFraction) {
469     return mValue.mFloat;
470   }
471   return 0.0f;
472 }
473 
GetCalcValue()474 inline nsStyleCoord::Calc* nsStyleCoord::GetCalcValue() const {
475   NS_ASSERTION(IsCalcUnit(), "not a pointer value");
476   if (IsCalcUnit()) {
477     return AsCalcValue(mValue);
478   }
479   return nullptr;
480 }
481 
Reset(nsStyleUnit & aUnit,nsStyleUnion & aValue)482 /* static */ inline void nsStyleCoord::Reset(nsStyleUnit& aUnit,
483                                              nsStyleUnion& aValue) {
484   MOZ_ASSERT(aUnit <= eStyleUnit_MAX,
485              "calling Reset on uninitialized nsStyleCoord?");
486 
487   switch (aUnit) {
488     case eStyleUnit_Calc:
489       static_cast<Calc*>(aValue.mPointer)->Release();
490       break;
491     default:
492       MOZ_ASSERT(!IsPointerUnit(aUnit), "check pointer refcounting logic");
493   }
494 
495   aUnit = eStyleUnit_Null;
496   aValue.mInt = 0;
497 }
498 
SetValue(nsStyleUnit & aUnit,nsStyleUnion & aValue,nsStyleUnit aOtherUnit,const nsStyleUnion & aOtherValue)499 /* static */ inline void nsStyleCoord::SetValue(
500     nsStyleUnit& aUnit, nsStyleUnion& aValue, nsStyleUnit aOtherUnit,
501     const nsStyleUnion& aOtherValue) {
502   Reset(aUnit, aValue);
503   InitWithValue(aUnit, aValue, aOtherUnit, aOtherValue);
504 }
505 
InitWithValue(nsStyleUnit & aUnit,nsStyleUnion & aValue,nsStyleUnit aOtherUnit,const nsStyleUnion & aOtherValue)506 /* static */ inline void nsStyleCoord::InitWithValue(
507     nsStyleUnit& aUnit, nsStyleUnion& aValue, nsStyleUnit aOtherUnit,
508     const nsStyleUnion& aOtherValue) {
509   aUnit = aOtherUnit;
510   aValue = aOtherValue;
511 
512   switch (aUnit) {
513     case eStyleUnit_Calc:
514       static_cast<Calc*>(aValue.mPointer)->AddRef();
515       break;
516     default:
517       MOZ_ASSERT(!IsPointerUnit(aUnit), "check pointer refcounting logic");
518   }
519 }
520 
SetValue(nsStyleUnit & aUnit,nsStyleUnion & aValue,const nsStyleCoord & aOther)521 /* static */ inline void nsStyleCoord::SetValue(nsStyleUnit& aUnit,
522                                                 nsStyleUnion& aValue,
523                                                 const nsStyleCoord& aOther) {
524   SetValue(aUnit, aValue, aOther.mUnit, aOther.mValue);
525 }
526 
InitWithValue(nsStyleUnit & aUnit,nsStyleUnion & aValue,const nsStyleCoord & aOther)527 /* static */ inline void nsStyleCoord::InitWithValue(
528     nsStyleUnit& aUnit, nsStyleUnion& aValue, const nsStyleCoord& aOther) {
529   InitWithValue(aUnit, aValue, aOther.mUnit, aOther.mValue);
530 }
531 
532 // -------------------------
533 // nsStyleSides inlines
534 //
535 inline bool nsStyleSides::operator!=(const nsStyleSides& aOther) const {
536   return !((*this) == aOther);
537 }
538 
GetUnit(mozilla::Side aSide)539 inline nsStyleUnit nsStyleSides::GetUnit(mozilla::Side aSide) const {
540   return (nsStyleUnit)mUnits[aSide];
541 }
542 
GetLeftUnit()543 inline nsStyleUnit nsStyleSides::GetLeftUnit() const {
544   return GetUnit(mozilla::eSideLeft);
545 }
546 
GetTopUnit()547 inline nsStyleUnit nsStyleSides::GetTopUnit() const {
548   return GetUnit(mozilla::eSideTop);
549 }
550 
GetRightUnit()551 inline nsStyleUnit nsStyleSides::GetRightUnit() const {
552   return GetUnit(mozilla::eSideRight);
553 }
554 
GetBottomUnit()555 inline nsStyleUnit nsStyleSides::GetBottomUnit() const {
556   return GetUnit(mozilla::eSideBottom);
557 }
558 
Get(mozilla::Side aSide)559 inline nsStyleCoord nsStyleSides::Get(mozilla::Side aSide) const {
560   return nsStyleCoord(mValues[aSide], nsStyleUnit(mUnits[aSide]));
561 }
562 
GetLeft()563 inline nsStyleCoord nsStyleSides::GetLeft() const {
564   return Get(mozilla::eSideLeft);
565 }
566 
GetTop()567 inline nsStyleCoord nsStyleSides::GetTop() const {
568   return Get(mozilla::eSideTop);
569 }
570 
GetRight()571 inline nsStyleCoord nsStyleSides::GetRight() const {
572   return Get(mozilla::eSideRight);
573 }
574 
GetBottom()575 inline nsStyleCoord nsStyleSides::GetBottom() const {
576   return Get(mozilla::eSideBottom);
577 }
578 
Set(mozilla::Side aSide,const nsStyleCoord & aCoord)579 inline void nsStyleSides::Set(mozilla::Side aSide, const nsStyleCoord& aCoord) {
580   nsStyleCoord::SetValue(mUnits[aSide], mValues[aSide], aCoord);
581 }
582 
SetLeft(const nsStyleCoord & aCoord)583 inline void nsStyleSides::SetLeft(const nsStyleCoord& aCoord) {
584   Set(mozilla::eSideLeft, aCoord);
585 }
586 
SetTop(const nsStyleCoord & aCoord)587 inline void nsStyleSides::SetTop(const nsStyleCoord& aCoord) {
588   Set(mozilla::eSideTop, aCoord);
589 }
590 
SetRight(const nsStyleCoord & aCoord)591 inline void nsStyleSides::SetRight(const nsStyleCoord& aCoord) {
592   Set(mozilla::eSideRight, aCoord);
593 }
594 
SetBottom(const nsStyleCoord & aCoord)595 inline void nsStyleSides::SetBottom(const nsStyleCoord& aCoord) {
596   Set(mozilla::eSideBottom, aCoord);
597 }
598 
599 // -------------------------
600 // nsStyleCorners inlines
601 //
602 inline bool nsStyleCorners::operator!=(const nsStyleCorners& aOther) const {
603   return !((*this) == aOther);
604 }
605 
GetUnit(uint8_t aCorner)606 inline nsStyleUnit nsStyleCorners::GetUnit(uint8_t aCorner) const {
607   return (nsStyleUnit)mUnits[aCorner];
608 }
609 
Get(uint8_t aCorner)610 inline nsStyleCoord nsStyleCorners::Get(uint8_t aCorner) const {
611   return nsStyleCoord(mValues[aCorner], nsStyleUnit(mUnits[aCorner]));
612 }
613 
Set(uint8_t aCorner,const nsStyleCoord & aCoord)614 inline void nsStyleCorners::Set(uint8_t aCorner, const nsStyleCoord& aCoord) {
615   nsStyleCoord::SetValue(mUnits[aCorner], mValues[aCorner], aCoord);
616 }
617 
618 #endif /* nsStyleCoord_h___ */
619