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_SCALEFACTORS2D_H_ 8 #define MOZILLA_GFX_SCALEFACTORS2D_H_ 9 10 #include <ostream> 11 12 #include "mozilla/Attributes.h" 13 #include "mozilla/FloatingPoint.h" 14 #include "mozilla/gfx/ScaleFactor.h" 15 16 #include "gfxPoint.h" 17 18 namespace mozilla { 19 namespace gfx { 20 21 /* 22 * This class is like ScaleFactor, but allows different scales on the x and 23 * y axes. 24 */ 25 template <class src, class dst> 26 struct ScaleFactors2D { 27 float xScale; 28 float yScale; 29 ScaleFactors2DScaleFactors2D30 constexpr ScaleFactors2D() : xScale(1.0), yScale(1.0) {} ScaleFactors2DScaleFactors2D31 constexpr ScaleFactors2D(const ScaleFactors2D<src, dst>& aCopy) 32 : xScale(aCopy.xScale), yScale(aCopy.yScale) {} ScaleFactors2DScaleFactors2D33 constexpr ScaleFactors2D(float aXScale, float aYScale) 34 : xScale(aXScale), yScale(aYScale) {} 35 // Layout code often uses gfxSize to represent a pair of x/y scales. ScaleFactors2DScaleFactors2D36 explicit constexpr ScaleFactors2D(const gfxSize& aSize) 37 : xScale(aSize.width), yScale(aSize.height) {} 38 39 // "Upgrade" from a ScaleFactor. 40 // This is deliberately 'explicit' so that the treatment of a single scale 41 // number as both the x- and y-scale in a context where they are allowed to 42 // be different, is more visible. ScaleFactors2DScaleFactors2D43 explicit constexpr ScaleFactors2D(const ScaleFactor<src, dst>& aScale) 44 : xScale(aScale.scale), yScale(aScale.scale) {} 45 AreScalesSameScaleFactors2D46 bool AreScalesSame() const { 47 return FuzzyEqualsMultiplicative(xScale, yScale); 48 } 49 50 // Convert to a ScaleFactor. Asserts that the scales are, in fact, equal. ToScaleFactorScaleFactors2D51 ScaleFactor<src, dst> ToScaleFactor() const { 52 MOZ_ASSERT(AreScalesSame()); 53 return ScaleFactor<src, dst>(xScale); 54 } 55 56 ScaleFactors2D<src, dst>& operator=(const ScaleFactors2D<src, dst>&) = 57 default; 58 59 bool operator==(const ScaleFactors2D<src, dst>& aOther) const { 60 return xScale == aOther.xScale && yScale == aOther.yScale; 61 } 62 63 bool operator!=(const ScaleFactors2D<src, dst>& aOther) const { 64 return !(*this == aOther); 65 } 66 67 friend std::ostream& operator<<(std::ostream& aStream, 68 const ScaleFactors2D<src, dst>& aScale) { 69 if (aScale.AreScalesSame()) { 70 return aStream << aScale.xScale; 71 } else { 72 return aStream << '(' << aScale.xScale << ',' << aScale.yScale << ')'; 73 } 74 } 75 76 template <class other> 77 ScaleFactors2D<other, dst> operator/( 78 const ScaleFactors2D<src, other>& aOther) const { 79 return ScaleFactors2D<other, dst>(xScale / aOther.xScale, 80 yScale / aOther.yScale); 81 } 82 83 template <class other> 84 ScaleFactors2D<src, other> operator/( 85 const ScaleFactors2D<other, dst>& aOther) const { 86 return ScaleFactors2D<src, other>(xScale / aOther.xScale, 87 yScale / aOther.yScale); 88 } 89 90 template <class other> 91 ScaleFactors2D<src, other> operator*( 92 const ScaleFactors2D<dst, other>& aOther) const { 93 return ScaleFactors2D<src, other>(xScale * aOther.xScale, 94 yScale * aOther.yScale); 95 } 96 97 template <class other> 98 ScaleFactors2D<other, dst> operator*( 99 const ScaleFactors2D<other, src>& aOther) const { 100 return ScaleFactors2D<other, dst>(xScale * aOther.xScale, 101 yScale * aOther.yScale); 102 } 103 104 template <class other> 105 ScaleFactors2D<src, other> operator*( 106 const ScaleFactor<dst, other>& aOther) const { 107 return *this * ScaleFactors2D<dst, other>(aOther); 108 } 109 110 template <class other> 111 ScaleFactors2D<other, dst> operator*( 112 const ScaleFactor<other, src>& aOther) const { 113 return *this * ScaleFactors2D<other, src>(aOther); 114 } 115 116 template <class other> 117 ScaleFactors2D<src, other> operator/( 118 const ScaleFactor<other, dst>& aOther) const { 119 return *this / ScaleFactors2D<other, dst>(aOther); 120 } 121 122 template <class other> 123 ScaleFactors2D<other, dst> operator/( 124 const ScaleFactor<src, other>& aOther) const { 125 return *this / ScaleFactors2D<src, other>(aOther); 126 } 127 128 template <class other> 129 friend ScaleFactors2D<other, dst> operator*( 130 const ScaleFactor<other, src>& aA, const ScaleFactors2D<src, dst>& aB) { 131 return ScaleFactors2D<other, src>(aA) * aB; 132 } 133 134 template <class other> 135 friend ScaleFactors2D<other, src> operator/( 136 const ScaleFactor<other, dst>& aA, const ScaleFactors2D<src, dst>& aB) { 137 return ScaleFactors2D<other, src>(aA) / aB; 138 } 139 140 // Divide two scales of the same units, yielding a scale with no units, 141 // represented as a gfxSize. This can mean e.g. the change in a particular 142 // scale from one frame to the next. 143 gfxSize operator/(const ScaleFactors2D& aOther) const { 144 return gfxSize(xScale / aOther.xScale, yScale / aOther.yScale); 145 } 146 }; 147 148 } // namespace gfx 149 } // namespace mozilla 150 151 #endif /* MOZILLA_GFX_SCALEFACTORS2D_H_ */ 152