ScaleFactors2D.h (7089B)
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/FloatingPoint.h" 13 #include "mozilla/gfx/ScaleFactor.h" 14 #include "mozilla/gfx/Point.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, class T> 26 struct BaseScaleFactors2D { 27 T xScale; 28 T yScale; 29 30 constexpr BaseScaleFactors2D() : xScale(1.0), yScale(1.0) {} 31 constexpr BaseScaleFactors2D(const BaseScaleFactors2D& aCopy) 32 : xScale(aCopy.xScale), yScale(aCopy.yScale) {} 33 constexpr BaseScaleFactors2D(T aXScale, T aYScale) 34 : xScale(aXScale), yScale(aYScale) {} 35 // Layout code often uses gfxSize to represent a pair of x/y scales. 36 explicit constexpr BaseScaleFactors2D(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. 43 explicit constexpr BaseScaleFactors2D(const ScaleFactor<Src, Dst>& aScale) 44 : xScale(aScale.scale), yScale(aScale.scale) {} 45 46 bool AreScalesSame() const { 47 return FuzzyEqualsMultiplicative(xScale, yScale); 48 } 49 50 // Convert the underlying floating point type storing the scale factors 51 // to that of NewT. 52 template <typename NewT> 53 BaseScaleFactors2D<Src, Dst, NewT> ConvertTo() const { 54 return BaseScaleFactors2D<Src, Dst, NewT>(NewT(xScale), NewT(yScale)); 55 } 56 57 // Convert to a ScaleFactor. Asserts that the scales are, in fact, equal. 58 ScaleFactor<Src, Dst> ToScaleFactor() const { 59 // Avoid implicit narrowing from double to float. An explicit conversion 60 // may be done with `scales.ConvertTo<float>().ToScaleFactor()` if desired. 61 static_assert(std::is_same_v<T, float>); 62 MOZ_ASSERT(AreScalesSame()); 63 return ScaleFactor<Src, Dst>(xScale); 64 } 65 66 // Convert to a SizeTyped. Eventually, we should replace all uses of SizeTyped 67 // to represent scales with ScaleFactors2D, and remove this function. 68 SizeTyped<UnknownUnits, T> ToSize() const { 69 return SizeTyped<UnknownUnits, T>(xScale, yScale); 70 } 71 72 BaseScaleFactors2D& operator=(const BaseScaleFactors2D&) = default; 73 74 bool operator==(const BaseScaleFactors2D& aOther) const { 75 return xScale == aOther.xScale && yScale == aOther.yScale; 76 } 77 78 bool operator!=(const BaseScaleFactors2D& aOther) const { 79 return !(*this == aOther); 80 } 81 82 friend std::ostream& operator<<(std::ostream& aStream, 83 const BaseScaleFactors2D& aScale) { 84 if (aScale.AreScalesSame()) { 85 return aStream << aScale.xScale; 86 } else { 87 return aStream << '(' << aScale.xScale << ',' << aScale.yScale << ')'; 88 } 89 } 90 91 template <class Other> 92 BaseScaleFactors2D<Other, Dst, T> operator/( 93 const BaseScaleFactors2D<Src, Other, T>& aOther) const { 94 return BaseScaleFactors2D<Other, Dst, T>(xScale / aOther.xScale, 95 yScale / aOther.yScale); 96 } 97 98 template <class Other> 99 BaseScaleFactors2D<Src, Other, T> operator/( 100 const BaseScaleFactors2D<Other, Dst, T>& aOther) const { 101 return BaseScaleFactors2D<Src, Other, T>(xScale / aOther.xScale, 102 yScale / aOther.yScale); 103 } 104 105 template <class Other> 106 BaseScaleFactors2D<Src, Other, T> operator*( 107 const BaseScaleFactors2D<Dst, Other, T>& aOther) const { 108 return BaseScaleFactors2D<Src, Other, T>(xScale * aOther.xScale, 109 yScale * aOther.yScale); 110 } 111 112 template <class Other> 113 BaseScaleFactors2D<Other, Dst, T> operator*( 114 const BaseScaleFactors2D<Other, Src, T>& aOther) const { 115 return BaseScaleFactors2D<Other, Dst, T>(xScale * aOther.xScale, 116 yScale * aOther.yScale); 117 } 118 119 BaseScaleFactors2D<Src, Src, T> operator*( 120 const BaseScaleFactors2D<Dst, Src, T>& aOther) const { 121 return BaseScaleFactors2D<Src, Src, T>(xScale * aOther.xScale, 122 yScale * aOther.yScale); 123 } 124 125 template <class Other> 126 BaseScaleFactors2D<Src, Other, T> operator*( 127 const ScaleFactor<Dst, Other>& aOther) const { 128 return *this * BaseScaleFactors2D<Dst, Other, T>(aOther); 129 } 130 131 template <class Other> 132 BaseScaleFactors2D<Other, Dst, T> operator*( 133 const ScaleFactor<Other, Src>& aOther) const { 134 return *this * BaseScaleFactors2D<Other, Src, T>(aOther); 135 } 136 137 BaseScaleFactors2D<Src, Src, T> operator*( 138 const ScaleFactor<Dst, Src>& aOther) const { 139 return *this * BaseScaleFactors2D<Dst, Src, T>(aOther); 140 } 141 142 template <class Other> 143 BaseScaleFactors2D<Src, Other, T> operator/( 144 const ScaleFactor<Other, Dst>& aOther) const { 145 return *this / BaseScaleFactors2D<Other, Dst, T>(aOther); 146 } 147 148 template <class Other> 149 BaseScaleFactors2D<Other, Dst, T> operator/( 150 const ScaleFactor<Src, Other>& aOther) const { 151 return *this / BaseScaleFactors2D<Src, Other, T>(aOther); 152 } 153 154 template <class Other> 155 friend BaseScaleFactors2D<Other, Dst, T> operator*( 156 const ScaleFactor<Other, Src>& aA, const BaseScaleFactors2D& aB) { 157 return BaseScaleFactors2D<Other, Src, T>(aA) * aB; 158 } 159 160 template <class Other> 161 friend BaseScaleFactors2D<Other, Src, T> operator/( 162 const ScaleFactor<Other, Dst>& aA, const BaseScaleFactors2D& aB) { 163 return BaseScaleFactors2D<Other, Src, T>(aA) / aB; 164 } 165 166 static BaseScaleFactors2D<Src, Dst, T> FromUnknownScale( 167 const BaseScaleFactors2D<UnknownUnits, UnknownUnits, T>& scale) { 168 return BaseScaleFactors2D<Src, Dst, T>(scale.xScale, scale.yScale); 169 } 170 171 BaseScaleFactors2D<UnknownUnits, UnknownUnits, T> ToUnknownScale() const { 172 return BaseScaleFactors2D<UnknownUnits, UnknownUnits, T>(xScale, yScale); 173 } 174 175 friend BaseScaleFactors2D Min(const BaseScaleFactors2D& aA, 176 const BaseScaleFactors2D& aB) { 177 return BaseScaleFactors2D(std::min(aA.xScale, aB.xScale), 178 std::min(aA.yScale, aB.yScale)); 179 } 180 181 friend BaseScaleFactors2D Max(const BaseScaleFactors2D& aA, 182 const BaseScaleFactors2D& aB) { 183 return BaseScaleFactors2D(std::max(aA.xScale, aB.xScale), 184 std::max(aA.yScale, aB.yScale)); 185 } 186 }; 187 188 template <class Src, class Dst> 189 using ScaleFactors2D = BaseScaleFactors2D<Src, Dst, float>; 190 191 template <class Src, class Dst> 192 using ScaleFactors2DDouble = BaseScaleFactors2D<Src, Dst, double>; 193 194 } // namespace gfx 195 } // namespace mozilla 196 197 #endif /* MOZILLA_GFX_SCALEFACTORS2D_H_ */