BaseSize.h (3410B)
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_BASESIZE_H_ 8 #define MOZILLA_GFX_BASESIZE_H_ 9 10 #include <algorithm> 11 #include <ostream> 12 13 #include "mozilla/Attributes.h" 14 15 namespace mozilla::gfx { 16 17 /** 18 * Do not use this class directly. Subclass it, pass that subclass as the 19 * Sub parameter, and only use that subclass. This allows methods to safely 20 * cast 'this' to 'Sub*'. 21 */ 22 template <class T, class Sub, class Coord = T> 23 struct BaseSize { 24 union { 25 struct { 26 T width, height; 27 }; 28 T components[2]; 29 }; 30 31 // Constructors 32 constexpr BaseSize() : width(0), height(0) {} 33 constexpr BaseSize(Coord aWidth, Coord aHeight) 34 : width(aWidth), height(aHeight) {} 35 36 void SizeTo(T aWidth, T aHeight) { 37 width = aWidth; 38 height = aHeight; 39 } 40 41 bool IsEmpty() const { return width <= 0 || height <= 0; } 42 43 bool IsSquare() const { return width == height; } 44 45 MOZ_ALWAYS_INLINE T Width() const { return width; } 46 MOZ_ALWAYS_INLINE T Height() const { return height; } 47 48 // Note that '=' isn't defined so we'll get the 49 // compiler generated default assignment operator 50 51 bool operator==(const Sub& aSize) const { 52 return width == aSize.width && height == aSize.height; 53 } 54 bool operator!=(const Sub& aSize) const { 55 return width != aSize.width || height != aSize.height; 56 } 57 bool operator<=(const Sub& aSize) const { 58 return width <= aSize.width && height <= aSize.height; 59 } 60 bool operator<(const Sub& aSize) const { 61 return *this <= aSize && *this != aSize; 62 } 63 64 Sub operator+(const Sub& aSize) const { 65 return Sub(width + aSize.width, height + aSize.height); 66 } 67 Sub operator-(const Sub& aSize) const { 68 return Sub(width - aSize.width, height - aSize.height); 69 } 70 Sub& operator+=(const Sub& aSize) { 71 width += aSize.width; 72 height += aSize.height; 73 return *static_cast<Sub*>(this); 74 } 75 Sub& operator-=(const Sub& aSize) { 76 width -= aSize.width; 77 height -= aSize.height; 78 return *static_cast<Sub*>(this); 79 } 80 81 Sub operator*(T aScale) const { return Sub(width * aScale, height * aScale); } 82 Sub operator/(T aScale) const { return Sub(width / aScale, height / aScale); } 83 friend Sub operator*(T aScale, const Sub& aSize) { 84 return Sub(aScale * aSize.width, aScale * aSize.height); 85 } 86 void Scale(T aXScale, T aYScale) { 87 width *= aXScale; 88 height *= aYScale; 89 } 90 91 Sub operator*(const Sub& aSize) const { 92 return Sub(width * aSize.width, height * aSize.height); 93 } 94 Sub operator/(const Sub& aSize) const { 95 return Sub(width / aSize.width, height / aSize.height); 96 } 97 98 friend Sub Min(const Sub& aA, const Sub& aB) { 99 return Sub(std::min(aA.width, aB.width), std::min(aA.height, aB.height)); 100 } 101 102 friend Sub Max(const Sub& aA, const Sub& aB) { 103 return Sub(std::max(aA.width, aB.width), std::max(aA.height, aB.height)); 104 } 105 106 friend std::ostream& operator<<(std::ostream& aStream, 107 const BaseSize<T, Sub, Coord>& aSize) { 108 return aStream << '(' << aSize.width << " x " << aSize.height << ')'; 109 } 110 }; 111 112 } // namespace mozilla::gfx 113 114 #endif /* MOZILLA_GFX_BASESIZE_H_ */