Line data Source code
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 :
29 299 : constexpr ScaleFactors2D() : xScale(1.0), yScale(1.0) {}
30 409 : constexpr ScaleFactors2D(const ScaleFactors2D<src, dst>& aCopy)
31 409 : : xScale(aCopy.xScale), yScale(aCopy.yScale) {}
32 425 : constexpr ScaleFactors2D(float aXScale, float aYScale)
33 425 : : xScale(aXScale), yScale(aYScale) {}
34 : // Layout code often uses gfxSize to represent a pair of x/y scales.
35 90 : explicit constexpr ScaleFactors2D(const gfxSize& aSize)
36 90 : : 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.
42 157 : explicit constexpr ScaleFactors2D(const ScaleFactor<src, dst>& aScale)
43 157 : : xScale(aScale.scale), yScale(aScale.scale) {}
44 :
45 56 : bool AreScalesSame() const {
46 56 : return FuzzyEqualsMultiplicative(xScale, yScale);
47 : }
48 :
49 : // Convert to a ScaleFactor. Asserts that the scales are, in fact, equal.
50 56 : ScaleFactor<src, dst> ToScaleFactor() const {
51 56 : MOZ_ASSERT(AreScalesSame());
52 56 : return ScaleFactor<src, dst>(xScale);
53 : }
54 :
55 247 : bool operator==(const ScaleFactors2D<src, dst>& aOther) const {
56 247 : return xScale == aOther.xScale && yScale == aOther.yScale;
57 : }
58 :
59 2 : bool operator!=(const ScaleFactors2D<src, dst>& aOther) const {
60 2 : 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 93 : ScaleFactors2D<other, dst> operator/(const ScaleFactors2D<src, other>& aOther) const {
74 93 : return ScaleFactors2D<other, dst>(xScale / aOther.xScale, yScale / aOther.yScale);
75 : }
76 :
77 : template<class other>
78 31 : ScaleFactors2D<src, other> operator/(const ScaleFactors2D<other, dst>& aOther) const {
79 31 : return ScaleFactors2D<src, other>(xScale / aOther.xScale, yScale / aOther.yScale);
80 : }
81 :
82 : template<class other>
83 120 : ScaleFactors2D<src, other> operator*(const ScaleFactors2D<dst, other>& aOther) const {
84 120 : return ScaleFactors2D<src, other>(xScale * aOther.xScale, yScale * aOther.yScale);
85 : }
86 :
87 : template<class other>
88 27 : ScaleFactors2D<other, dst> operator*(const ScaleFactors2D<other, src>& aOther) const {
89 27 : return ScaleFactors2D<other, dst>(xScale * aOther.xScale, yScale * aOther.yScale);
90 : }
91 :
92 : template<class other>
93 58 : ScaleFactors2D<src, other> operator*(const ScaleFactor<dst, other>& aOther) const {
94 58 : return *this * ScaleFactors2D<dst, other>(aOther);
95 : }
96 :
97 : template<class other>
98 27 : ScaleFactors2D<other, dst> operator*(const ScaleFactor<other, src>& aOther) const {
99 27 : 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 10 : ScaleFactors2D<other, dst> operator/(const ScaleFactor<src, other>& aOther) const {
109 10 : return *this / ScaleFactors2D<src, other>(aOther);
110 : }
111 :
112 : template<class other>
113 62 : friend ScaleFactors2D<other, dst> operator*(const ScaleFactor<other, src>& aA,
114 : const ScaleFactors2D<src, dst>& aB) {
115 62 : 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 8 : gfxSize operator/(const ScaleFactors2D& aOther) const {
128 8 : return gfxSize(xScale / aOther.xScale, yScale / aOther.yScale);
129 : }
130 : };
131 :
132 : } // namespace gfx
133 : } // namespace mozilla
134 :
135 : #endif /* MOZILLA_GFX_SCALEFACTORS2D_H_ */
|