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/. */
7 #ifndef MOZILLA_GFX_SCALEFACTORS2D_H_
8 #define MOZILLA_GFX_SCALEFACTORS2D_H_
12 #include "mozilla/Attributes.h"
13 #include "mozilla/FloatingPoint.h"
14 #include "mozilla/gfx/ScaleFactor.h"
15 #include "mozilla/gfx/Point.h"
23 * This class is like ScaleFactor, but allows different scales on the x and
26 template <class Src
, class Dst
, class T
>
27 struct BaseScaleFactors2D
{
31 constexpr BaseScaleFactors2D() : xScale(1.0), yScale(1.0) {}
32 constexpr BaseScaleFactors2D(const BaseScaleFactors2D
& aCopy
)
33 : xScale(aCopy
.xScale
), yScale(aCopy
.yScale
) {}
34 constexpr BaseScaleFactors2D(T aXScale
, T aYScale
)
35 : xScale(aXScale
), yScale(aYScale
) {}
36 // Layout code often uses gfxSize to represent a pair of x/y scales.
37 explicit constexpr BaseScaleFactors2D(const gfxSize
& aSize
)
38 : xScale(aSize
.width
), yScale(aSize
.height
) {}
40 // "Upgrade" from a ScaleFactor.
41 // This is deliberately 'explicit' so that the treatment of a single scale
42 // number as both the x- and y-scale in a context where they are allowed to
43 // be different, is more visible.
44 explicit constexpr BaseScaleFactors2D(const ScaleFactor
<Src
, Dst
>& aScale
)
45 : xScale(aScale
.scale
), yScale(aScale
.scale
) {}
47 bool AreScalesSame() const {
48 return FuzzyEqualsMultiplicative(xScale
, yScale
);
51 // Convert the underlying floating point type storing the scale factors
53 template <typename NewT
>
54 BaseScaleFactors2D
<Src
, Dst
, NewT
> ConvertTo() const {
55 return BaseScaleFactors2D
<Src
, Dst
, NewT
>(NewT(xScale
), NewT(yScale
));
58 // Convert to a ScaleFactor. Asserts that the scales are, in fact, equal.
59 ScaleFactor
<Src
, Dst
> ToScaleFactor() const {
60 // Avoid implicit narrowing from double to float. An explicit conversion
61 // may be done with `scales.ConvertTo<float>().ToScaleFactor()` if desired.
62 static_assert(std::is_same_v
<T
, float>);
63 MOZ_ASSERT(AreScalesSame());
64 return ScaleFactor
<Src
, Dst
>(xScale
);
67 // Convert to a SizeTyped. Eventually, we should replace all uses of SizeTyped
68 // to represent scales with ScaleFactors2D, and remove this function.
69 SizeTyped
<UnknownUnits
, T
> ToSize() const {
70 return SizeTyped
<UnknownUnits
, T
>(xScale
, yScale
);
73 BaseScaleFactors2D
& operator=(const BaseScaleFactors2D
&) = default;
75 bool operator==(const BaseScaleFactors2D
& aOther
) const {
76 return xScale
== aOther
.xScale
&& yScale
== aOther
.yScale
;
79 bool operator!=(const BaseScaleFactors2D
& aOther
) const {
80 return !(*this == aOther
);
83 friend std::ostream
& operator<<(std::ostream
& aStream
,
84 const BaseScaleFactors2D
& aScale
) {
85 if (aScale
.AreScalesSame()) {
86 return aStream
<< aScale
.xScale
;
88 return aStream
<< '(' << aScale
.xScale
<< ',' << aScale
.yScale
<< ')';
92 template <class Other
>
93 BaseScaleFactors2D
<Other
, Dst
, T
> operator/(
94 const BaseScaleFactors2D
<Src
, Other
, T
>& aOther
) const {
95 return BaseScaleFactors2D
<Other
, Dst
, T
>(xScale
/ aOther
.xScale
,
96 yScale
/ aOther
.yScale
);
99 template <class Other
>
100 BaseScaleFactors2D
<Src
, Other
, T
> operator/(
101 const BaseScaleFactors2D
<Other
, Dst
, T
>& aOther
) const {
102 return BaseScaleFactors2D
<Src
, Other
, T
>(xScale
/ aOther
.xScale
,
103 yScale
/ aOther
.yScale
);
106 template <class Other
>
107 BaseScaleFactors2D
<Src
, Other
, T
> operator*(
108 const BaseScaleFactors2D
<Dst
, Other
, T
>& aOther
) const {
109 return BaseScaleFactors2D
<Src
, Other
, T
>(xScale
* aOther
.xScale
,
110 yScale
* aOther
.yScale
);
113 template <class Other
>
114 BaseScaleFactors2D
<Other
, Dst
, T
> operator*(
115 const BaseScaleFactors2D
<Other
, Src
, T
>& aOther
) const {
116 return BaseScaleFactors2D
<Other
, Dst
, T
>(xScale
* aOther
.xScale
,
117 yScale
* aOther
.yScale
);
120 BaseScaleFactors2D
<Src
, Src
, T
> operator*(
121 const BaseScaleFactors2D
<Dst
, Src
, T
>& aOther
) const {
122 return BaseScaleFactors2D
<Src
, Src
, T
>(xScale
* aOther
.xScale
,
123 yScale
* aOther
.yScale
);
126 template <class Other
>
127 BaseScaleFactors2D
<Src
, Other
, T
> operator*(
128 const ScaleFactor
<Dst
, Other
>& aOther
) const {
129 return *this * BaseScaleFactors2D
<Dst
, Other
, T
>(aOther
);
132 template <class Other
>
133 BaseScaleFactors2D
<Other
, Dst
, T
> operator*(
134 const ScaleFactor
<Other
, Src
>& aOther
) const {
135 return *this * BaseScaleFactors2D
<Other
, Src
, T
>(aOther
);
138 BaseScaleFactors2D
<Src
, Src
, T
> operator*(
139 const ScaleFactor
<Dst
, Src
>& aOther
) const {
140 return *this * BaseScaleFactors2D
<Dst
, Src
, T
>(aOther
);
143 template <class Other
>
144 BaseScaleFactors2D
<Src
, Other
, T
> operator/(
145 const ScaleFactor
<Other
, Dst
>& aOther
) const {
146 return *this / BaseScaleFactors2D
<Other
, Dst
, T
>(aOther
);
149 template <class Other
>
150 BaseScaleFactors2D
<Other
, Dst
, T
> operator/(
151 const ScaleFactor
<Src
, Other
>& aOther
) const {
152 return *this / BaseScaleFactors2D
<Src
, Other
, T
>(aOther
);
155 template <class Other
>
156 friend BaseScaleFactors2D
<Other
, Dst
, T
> operator*(
157 const ScaleFactor
<Other
, Src
>& aA
, const BaseScaleFactors2D
& aB
) {
158 return BaseScaleFactors2D
<Other
, Src
, T
>(aA
) * aB
;
161 template <class Other
>
162 friend BaseScaleFactors2D
<Other
, Src
, T
> operator/(
163 const ScaleFactor
<Other
, Dst
>& aA
, const BaseScaleFactors2D
& aB
) {
164 return BaseScaleFactors2D
<Other
, Src
, T
>(aA
) / aB
;
167 static BaseScaleFactors2D
<Src
, Dst
, T
> FromUnknownScale(
168 const BaseScaleFactors2D
<UnknownUnits
, UnknownUnits
, T
>& scale
) {
169 return BaseScaleFactors2D
<Src
, Dst
, T
>(scale
.xScale
, scale
.yScale
);
172 BaseScaleFactors2D
<UnknownUnits
, UnknownUnits
, T
> ToUnknownScale() const {
173 return BaseScaleFactors2D
<UnknownUnits
, UnknownUnits
, T
>(xScale
, yScale
);
176 friend BaseScaleFactors2D
Min(const BaseScaleFactors2D
& aA
,
177 const BaseScaleFactors2D
& aB
) {
178 return BaseScaleFactors2D(std::min(aA
.xScale
, aB
.xScale
),
179 std::min(aA
.yScale
, aB
.yScale
));
182 friend BaseScaleFactors2D
Max(const BaseScaleFactors2D
& aA
,
183 const BaseScaleFactors2D
& aB
) {
184 return BaseScaleFactors2D(std::max(aA
.xScale
, aB
.xScale
),
185 std::max(aA
.yScale
, aB
.yScale
));
189 template <class Src
, class Dst
>
190 using ScaleFactors2D
= BaseScaleFactors2D
<Src
, Dst
, float>;
192 template <class Src
, class Dst
>
193 using ScaleFactors2DDouble
= BaseScaleFactors2D
<Src
, Dst
, double>;
196 } // namespace mozilla
198 #endif /* MOZILLA_GFX_SCALEFACTORS2D_H_ */