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/. */
7 #ifndef MOZILLA_GFX_BASEMARGIN_H_
8 #define MOZILLA_GFX_BASEMARGIN_H_
17 * Sides represents a set of physical sides.
20 Sides() : mBits(SideBits::eNone
) {}
21 explicit Sides(SideBits aSideBits
) {
22 MOZ_ASSERT((aSideBits
& ~SideBits::eAll
) == SideBits::eNone
,
26 bool IsEmpty() const { return mBits
== SideBits::eNone
; }
27 bool Top() const { return (mBits
& SideBits::eTop
) == SideBits::eTop
; }
28 bool Right() const { return (mBits
& SideBits::eRight
) == SideBits::eRight
; }
30 return (mBits
& SideBits::eBottom
) == SideBits::eBottom
;
32 bool Left() const { return (mBits
& SideBits::eLeft
) == SideBits::eLeft
; }
33 bool Contains(SideBits aSideBits
) const {
34 MOZ_ASSERT(!(aSideBits
& ~SideBits::eAll
), "illegal side bits");
35 return (mBits
& aSideBits
) == aSideBits
;
37 Sides
operator|(Sides aOther
) const {
38 return Sides(SideBits(mBits
| aOther
.mBits
));
40 Sides
operator|(SideBits aSideBits
) const { return *this | Sides(aSideBits
); }
41 Sides
& operator|=(Sides aOther
) {
42 mBits
|= aOther
.mBits
;
45 Sides
& operator|=(SideBits aSideBits
) { return *this |= Sides(aSideBits
); }
46 bool operator==(Sides aOther
) const { return mBits
== aOther
.mBits
; }
47 bool operator!=(Sides aOther
) const { return !(*this == aOther
); }
56 * Do not use this class directly. Subclass it, pass that subclass as the
57 * Sub parameter, and only use that subclass.
59 template <class T
, class Sub
>
61 typedef mozilla::Side SideT
; // because we have a method named Side
63 // Do not change the layout of these members; the Side() methods below
64 // depend on this order.
65 T top
, right
, bottom
, left
;
68 BaseMargin() : top(0), right(0), bottom(0), left(0) {}
69 BaseMargin(T aTop
, T aRight
, T aBottom
, T aLeft
)
70 : top(aTop
), right(aRight
), bottom(aBottom
), left(aLeft
) {}
72 void SizeTo(T aTop
, T aRight
, T aBottom
, T aLeft
) {
79 T
LeftRight() const { return left
+ right
; }
80 T
TopBottom() const { return top
+ bottom
; }
82 T
& Side(SideT aSide
) {
84 return *(&top
+ int(aSide
));
86 T
Side(SideT aSide
) const {
88 return *(&top
+ int(aSide
));
91 Sub
& ApplySkipSides(Sides aSkipSides
) {
92 if (aSkipSides
.Top()) {
95 if (aSkipSides
.Right()) {
98 if (aSkipSides
.Bottom()) {
101 if (aSkipSides
.Left()) {
104 return *static_cast<Sub
*>(this);
107 // Overloaded operators. Note that '=' isn't defined so we'll get the
108 // compiler generated default assignment operator
109 bool operator==(const Sub
& aMargin
) const {
110 return top
== aMargin
.top
&& right
== aMargin
.right
&&
111 bottom
== aMargin
.bottom
&& left
== aMargin
.left
;
113 bool operator!=(const Sub
& aMargin
) const { return !(*this == aMargin
); }
114 Sub
operator+(const Sub
& aMargin
) const {
115 return Sub(top
+ aMargin
.top
, right
+ aMargin
.right
,
116 bottom
+ aMargin
.bottom
, left
+ aMargin
.left
);
118 Sub
operator-(const Sub
& aMargin
) const {
119 return Sub(top
- aMargin
.top
, right
- aMargin
.right
,
120 bottom
- aMargin
.bottom
, left
- aMargin
.left
);
122 Sub
& operator+=(const Sub
& aMargin
) {
124 right
+= aMargin
.right
;
125 bottom
+= aMargin
.bottom
;
126 left
+= aMargin
.left
;
127 return *static_cast<Sub
*>(this);
130 friend std::ostream
& operator<<(std::ostream
& aStream
,
131 const BaseMargin
& aMargin
) {
132 return aStream
<< '(' << aMargin
.top
<< ',' << aMargin
.right
<< ','
133 << aMargin
.bottom
<< ',' << aMargin
.left
<< ')';
138 } // namespace mozilla
140 #endif /* MOZILLA_GFX_BASEMARGIN_H_ */