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 { Sidesfinal19 Sides() : mBits(0) {} Sidesfinal20 explicit Sides(SideBits aSideBits) 21 { 22 MOZ_ASSERT((aSideBits & ~eSideBitsAll) == 0, "illegal side bits"); 23 mBits = aSideBits; 24 } IsEmptyfinal25 bool IsEmpty() const { return mBits == 0; } Topfinal26 bool Top() const { return (mBits & eSideBitsTop) != 0; } Rightfinal27 bool Right() const { return (mBits & eSideBitsRight) != 0; } Bottomfinal28 bool Bottom() const { return (mBits & eSideBitsBottom) != 0; } Leftfinal29 bool Left() const { return (mBits & eSideBitsLeft) != 0; } Containsfinal30 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 Sides& operator|=(Sides aOther) 44 { 45 mBits |= aOther.mBits; 46 return *this; 47 } 48 Sides& operator|=(SideBits aSideBits) 49 { 50 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 BaseMarginBaseMargin80 BaseMargin() : top(0), right(0), bottom(0), left(0) {} BaseMarginBaseMargin81 BaseMargin(T aTop, T aRight, T aBottom, T aLeft) : 82 top(aTop), right(aRight), bottom(aBottom), left(aLeft) {} 83 SizeToBaseMargin84 void SizeTo(T aTop, T aRight, T aBottom, T aLeft) 85 { 86 top = aTop; right = aRight; bottom = aBottom; left = aLeft; 87 } 88 LeftRightBaseMargin89 T LeftRight() const { return left + right; } TopBottomBaseMargin90 T TopBottom() const { return top + bottom; } 91 SideBaseMargin92 T& Side(SideT aSide) { 93 // This is ugly! 94 return *(&top + int(aSide)); 95 } SideBaseMargin96 T Side(SideT aSide) const { 97 // This is ugly! 98 return *(&top + int(aSide)); 99 } 100 ApplySkipSidesBaseMargin101 void ApplySkipSides(Sides aSkipSides) 102 { 103 if (aSkipSides.Top()) { 104 top = 0; 105 } 106 if (aSkipSides.Right()) { 107 right = 0; 108 } 109 if (aSkipSides.Bottom()) { 110 bottom = 0; 111 } 112 if (aSkipSides.Left()) { 113 left = 0; 114 } 115 } 116 117 // Overloaded operators. Note that '=' isn't defined so we'll get the 118 // compiler generated default assignment operator 119 bool operator==(const Sub& aMargin) const { 120 return top == aMargin.top && right == aMargin.right && 121 bottom == aMargin.bottom && left == aMargin.left; 122 } 123 bool operator!=(const Sub& aMargin) const { 124 return !(*this == aMargin); 125 } 126 Sub operator+(const Sub& aMargin) const { 127 return Sub(top + aMargin.top, right + aMargin.right, 128 bottom + aMargin.bottom, left + aMargin.left); 129 } 130 Sub operator-(const Sub& aMargin) const { 131 return Sub(top - aMargin.top, right - aMargin.right, 132 bottom - aMargin.bottom, left - aMargin.left); 133 } 134 Sub& operator+=(const Sub& aMargin) { 135 top += aMargin.top; 136 right += aMargin.right; 137 bottom += aMargin.bottom; 138 left += aMargin.left; 139 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_ */ 153