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 #ifndef MOZILLA_GFX_BASEMARGIN_H_ 8 #define MOZILLA_GFX_BASEMARGIN_H_ 9 10 #include <ostream> 11 12 #include "Types.h" 13 14 namespace mozilla { 15 16 /** 17 * Sides represents a set of physical sides. 18 */ 19 struct Sides final { Sidesfinal20 Sides() : mBits(0) {} Sidesfinal21 explicit Sides(SideBits aSideBits) { 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 MOZ_ASSERT((aSideBits & ~eSideBitsAll) == 0, "illegal side bits"); 32 return (mBits & aSideBits) == aSideBits; 33 } 34 Sides operator|(Sides aOther) const { 35 return Sides(SideBits(mBits | aOther.mBits)); 36 } 37 Sides operator|(SideBits aSideBits) const { return *this | Sides(aSideBits); } 38 Sides& operator|=(Sides aOther) { 39 mBits |= aOther.mBits; 40 return *this; 41 } 42 Sides& operator|=(SideBits aSideBits) { return *this |= Sides(aSideBits); } 43 bool operator==(Sides aOther) const { return mBits == aOther.mBits; } 44 bool operator!=(Sides aOther) const { return !(*this == aOther); } 45 46 private: 47 uint8_t mBits; 48 }; 49 50 namespace gfx { 51 52 /** 53 * Do not use this class directly. Subclass it, pass that subclass as the 54 * Sub parameter, and only use that subclass. 55 */ 56 template <class T, class Sub> 57 struct BaseMargin { 58 typedef mozilla::Side SideT; // because we have a method named Side 59 60 // Do not change the layout of these members; the Side() methods below 61 // depend on this order. 62 T top, right, bottom, left; 63 64 // Constructors BaseMarginBaseMargin65 BaseMargin() : top(0), right(0), bottom(0), left(0) {} BaseMarginBaseMargin66 BaseMargin(T aTop, T aRight, T aBottom, T aLeft) 67 : top(aTop), right(aRight), bottom(aBottom), left(aLeft) {} 68 SizeToBaseMargin69 void SizeTo(T aTop, T aRight, T aBottom, T aLeft) { 70 top = aTop; 71 right = aRight; 72 bottom = aBottom; 73 left = aLeft; 74 } 75 LeftRightBaseMargin76 T LeftRight() const { return left + right; } TopBottomBaseMargin77 T TopBottom() const { return top + bottom; } 78 SideBaseMargin79 T& Side(SideT aSide) { 80 // This is ugly! 81 return *(&top + int(aSide)); 82 } SideBaseMargin83 T Side(SideT aSide) const { 84 // This is ugly! 85 return *(&top + int(aSide)); 86 } 87 ApplySkipSidesBaseMargin88 void ApplySkipSides(Sides aSkipSides) { 89 if (aSkipSides.Top()) { 90 top = 0; 91 } 92 if (aSkipSides.Right()) { 93 right = 0; 94 } 95 if (aSkipSides.Bottom()) { 96 bottom = 0; 97 } 98 if (aSkipSides.Left()) { 99 left = 0; 100 } 101 } 102 103 // Overloaded operators. Note that '=' isn't defined so we'll get the 104 // compiler generated default assignment operator 105 bool operator==(const Sub& aMargin) const { 106 return top == aMargin.top && right == aMargin.right && 107 bottom == aMargin.bottom && left == aMargin.left; 108 } 109 bool operator!=(const Sub& aMargin) const { return !(*this == aMargin); } 110 Sub operator+(const Sub& aMargin) const { 111 return Sub(top + aMargin.top, right + aMargin.right, 112 bottom + aMargin.bottom, left + aMargin.left); 113 } 114 Sub operator-(const Sub& aMargin) const { 115 return Sub(top - aMargin.top, right - aMargin.right, 116 bottom - aMargin.bottom, left - aMargin.left); 117 } 118 Sub& operator+=(const Sub& aMargin) { 119 top += aMargin.top; 120 right += aMargin.right; 121 bottom += aMargin.bottom; 122 left += aMargin.left; 123 return *static_cast<Sub*>(this); 124 } 125 126 friend std::ostream& operator<<(std::ostream& aStream, 127 const BaseMargin& aMargin) { 128 return aStream << '(' << aMargin.top << ',' << aMargin.right << ',' 129 << aMargin.bottom << ',' << aMargin.left << ')'; 130 } 131 }; 132 133 } // namespace gfx 134 } // namespace mozilla 135 136 #endif /* MOZILLA_GFX_BASEMARGIN_H_ */ 137