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