Line data Source code
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 : #ifndef MOZILLA_GFX_BASEMARGIN_H_
7 : #define MOZILLA_GFX_BASEMARGIN_H_
8 :
9 : #include <ostream>
10 :
11 : #include "Types.h"
12 :
13 : namespace mozilla {
14 :
15 : /**
16 : * Sides represents a set of physical sides.
17 : */
18 : struct Sides final {
19 2656 : Sides() : mBits(0) {}
20 0 : explicit Sides(SideBits aSideBits)
21 0 : {
22 0 : MOZ_ASSERT((aSideBits & ~eSideBitsAll) == 0, "illegal side bits");
23 0 : mBits = aSideBits;
24 0 : }
25 744 : bool IsEmpty() const { return mBits == 0; }
26 1289 : bool Top() const { return (mBits & eSideBitsTop) != 0; }
27 1289 : bool Right() const { return (mBits & eSideBitsRight) != 0; }
28 1289 : bool Bottom() const { return (mBits & eSideBitsBottom) != 0; }
29 1289 : bool Left() const { return (mBits & eSideBitsLeft) != 0; }
30 : bool Contains(SideBits aSideBits) const
31 : {
32 : MOZ_ASSERT((aSideBits & ~eSideBitsAll) == 0, "illegal side bits");
33 : return (mBits & aSideBits) == aSideBits;
34 : }
35 : Sides operator|(Sides aOther) const
36 : {
37 : return Sides(SideBits(mBits | aOther.mBits));
38 : }
39 : Sides operator|(SideBits aSideBits) const
40 : {
41 : return *this | Sides(aSideBits);
42 : }
43 0 : Sides& operator|=(Sides aOther)
44 : {
45 0 : mBits |= aOther.mBits;
46 0 : return *this;
47 : }
48 0 : Sides& operator|=(SideBits aSideBits)
49 : {
50 0 : return *this |= Sides(aSideBits);
51 : }
52 : bool operator==(Sides aOther) const
53 : {
54 : return mBits == aOther.mBits;
55 : }
56 : bool operator!=(Sides aOther) const
57 : {
58 : return !(*this == aOther);
59 : }
60 :
61 : private:
62 : uint8_t mBits;
63 : };
64 :
65 : namespace gfx {
66 :
67 : /**
68 : * Do not use this class directly. Subclass it, pass that subclass as the
69 : * Sub parameter, and only use that subclass.
70 : */
71 : template <class T, class Sub>
72 : struct BaseMargin {
73 : typedef mozilla::Side SideT; // because we have a method named Side
74 :
75 : // Do not change the layout of these members; the Side() methods below
76 : // depend on this order.
77 : T top, right, bottom, left;
78 :
79 : // Constructors
80 23022 : BaseMargin() : top(0), right(0), bottom(0), left(0) {}
81 22929 : BaseMargin(T aTop, T aRight, T aBottom, T aLeft) :
82 22929 : top(aTop), right(aRight), bottom(aBottom), left(aLeft) {}
83 :
84 29251 : void SizeTo(T aTop, T aRight, T aBottom, T aLeft)
85 : {
86 29251 : top = aTop; right = aRight; bottom = aBottom; left = aLeft;
87 29251 : }
88 :
89 10812 : T LeftRight() const { return left + right; }
90 8637 : T TopBottom() const { return top + bottom; }
91 :
92 83850 : T& Side(SideT aSide) {
93 : // This is ugly!
94 83850 : return *(&top + int(aSide));
95 : }
96 8352 : T Side(SideT aSide) const {
97 : // This is ugly!
98 8352 : return *(&top + int(aSide));
99 : }
100 :
101 817 : void ApplySkipSides(Sides aSkipSides)
102 : {
103 817 : if (aSkipSides.Top()) {
104 0 : top = 0;
105 : }
106 817 : if (aSkipSides.Right()) {
107 0 : right = 0;
108 : }
109 817 : if (aSkipSides.Bottom()) {
110 0 : bottom = 0;
111 : }
112 817 : if (aSkipSides.Left()) {
113 0 : left = 0;
114 : }
115 817 : }
116 :
117 : // Overloaded operators. Note that '=' isn't defined so we'll get the
118 : // compiler generated default assignment operator
119 7067 : bool operator==(const Sub& aMargin) const {
120 20723 : return top == aMargin.top && right == aMargin.right &&
121 20651 : bottom == aMargin.bottom && left == aMargin.left;
122 : }
123 6905 : bool operator!=(const Sub& aMargin) const {
124 6905 : return !(*this == aMargin);
125 : }
126 536 : Sub operator+(const Sub& aMargin) const {
127 1072 : return Sub(top + aMargin.top, right + aMargin.right,
128 1608 : bottom + aMargin.bottom, left + aMargin.left);
129 : }
130 127 : Sub operator-(const Sub& aMargin) const {
131 254 : return Sub(top - aMargin.top, right - aMargin.right,
132 381 : bottom - aMargin.bottom, left - aMargin.left);
133 : }
134 6824 : Sub& operator+=(const Sub& aMargin) {
135 6824 : top += aMargin.top;
136 6824 : right += aMargin.right;
137 6824 : bottom += aMargin.bottom;
138 6824 : left += aMargin.left;
139 6824 : return *static_cast<Sub*>(this);
140 : }
141 :
142 : friend std::ostream& operator<<(std::ostream& aStream,
143 : const BaseMargin& aMargin) {
144 : return aStream << '(' << aMargin.top << ',' << aMargin.right << ','
145 : << aMargin.bottom << ',' << aMargin.left << ')';
146 : }
147 : };
148 :
149 : } // namespace gfx
150 : } // namespace mozilla
151 :
152 : #endif /* MOZILLA_GFX_BASEMARGIN_H_ */
|