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
, class Coord
= T
>
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 Coord top
, right
, bottom
, left
;
68 BaseMargin() : top(0), right(0), bottom(0), left(0) {}
69 BaseMargin(Coord aTop
, Coord aRight
, Coord aBottom
, Coord aLeft
)
70 : top(aTop
), right(aRight
), bottom(aBottom
), left(aLeft
) {}
72 void SizeTo(Coord aTop
, Coord aRight
, Coord aBottom
, Coord aLeft
) {
79 Coord
LeftRight() const { return left
+ right
; }
80 Coord
TopBottom() const { return top
+ bottom
; }
82 Coord
& Side(SideT aSide
) {
84 return *(&top
+ int(aSide
));
86 Coord
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 // Ensures that all our sides are at least as big as the argument.
108 void EnsureAtLeast(const BaseMargin
& aMargin
) {
109 top
= std::max(top
, aMargin
.top
);
110 right
= std::max(right
, aMargin
.right
);
111 bottom
= std::max(bottom
, aMargin
.bottom
);
112 left
= std::max(left
, aMargin
.left
);
115 // Ensures that all our sides are at most as big as the argument.
116 void EnsureAtMost(const BaseMargin
& aMargin
) {
117 top
= std::min(top
, aMargin
.top
);
118 right
= std::min(right
, aMargin
.right
);
119 bottom
= std::min(bottom
, aMargin
.bottom
);
120 left
= std::min(left
, aMargin
.left
);
123 // Overloaded operators. Note that '=' isn't defined so we'll get the
124 // compiler generated default assignment operator
125 bool operator==(const Sub
& aMargin
) const {
126 return top
== aMargin
.top
&& right
== aMargin
.right
&&
127 bottom
== aMargin
.bottom
&& left
== aMargin
.left
;
129 bool operator!=(const Sub
& aMargin
) const { return !(*this == aMargin
); }
130 Sub
operator+(const Sub
& aMargin
) const {
131 return Sub(top
+ aMargin
.top
, right
+ aMargin
.right
,
132 bottom
+ aMargin
.bottom
, left
+ aMargin
.left
);
134 Sub
operator-(const Sub
& aMargin
) const {
135 return Sub(top
- aMargin
.top
, right
- aMargin
.right
,
136 bottom
- aMargin
.bottom
, left
- aMargin
.left
);
138 Sub
operator-() const { return Sub(-top
, -right
, -bottom
, -left
); }
139 Sub
& operator+=(const Sub
& aMargin
) {
141 right
+= aMargin
.right
;
142 bottom
+= aMargin
.bottom
;
143 left
+= aMargin
.left
;
144 return *static_cast<Sub
*>(this);
146 Sub
& operator-=(const Sub
& aMargin
) {
148 right
-= aMargin
.right
;
149 bottom
-= aMargin
.bottom
;
150 left
-= aMargin
.left
;
151 return *static_cast<Sub
*>(this);
154 friend std::ostream
& operator<<(std::ostream
& aStream
,
155 const BaseMargin
& aMargin
) {
156 return aStream
<< "(t=" << aMargin
.top
<< ", r=" << aMargin
.right
157 << ", b=" << aMargin
.bottom
<< ", l=" << aMargin
.left
<< ')';
162 } // namespace mozilla
164 #endif /* MOZILLA_GFX_BASEMARGIN_H_ */