diff options
Diffstat (limited to 'gfx/2d/ScaleFactors2D.h')
-rw-r--r-- | gfx/2d/ScaleFactors2D.h | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/gfx/2d/ScaleFactors2D.h b/gfx/2d/ScaleFactors2D.h new file mode 100644 index 000000000..6de32d7f2 --- /dev/null +++ b/gfx/2d/ScaleFactors2D.h @@ -0,0 +1,135 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_GFX_SCALEFACTORS2D_H_ +#define MOZILLA_GFX_SCALEFACTORS2D_H_ + +#include <ostream> + +#include "mozilla/Attributes.h" +#include "mozilla/FloatingPoint.h" +#include "mozilla/gfx/ScaleFactor.h" + +#include "gfxPoint.h" + +namespace mozilla { +namespace gfx { + +/* + * This class is like ScaleFactor, but allows different scales on the x and + * y axes. + */ +template<class src, class dst> +struct ScaleFactors2D { + float xScale; + float yScale; + + constexpr ScaleFactors2D() : xScale(1.0), yScale(1.0) {} + constexpr ScaleFactors2D(const ScaleFactors2D<src, dst>& aCopy) + : xScale(aCopy.xScale), yScale(aCopy.yScale) {} + constexpr ScaleFactors2D(float aXScale, float aYScale) + : xScale(aXScale), yScale(aYScale) {} + // Layout code often uses gfxSize to represent a pair of x/y scales. + explicit constexpr ScaleFactors2D(const gfxSize& aSize) + : xScale(aSize.width), yScale(aSize.height) {} + + // "Upgrade" from a ScaleFactor. + // This is deliberately 'explicit' so that the treatment of a single scale + // number as both the x- and y-scale in a context where they are allowed to + // be different, is more visible. + explicit constexpr ScaleFactors2D(const ScaleFactor<src, dst>& aScale) + : xScale(aScale.scale), yScale(aScale.scale) {} + + bool AreScalesSame() const { + return FuzzyEqualsMultiplicative(xScale, yScale); + } + + // Convert to a ScaleFactor. Asserts that the scales are, in fact, equal. + ScaleFactor<src, dst> ToScaleFactor() const { + MOZ_ASSERT(AreScalesSame()); + return ScaleFactor<src, dst>(xScale); + } + + bool operator==(const ScaleFactors2D<src, dst>& aOther) const { + return xScale == aOther.xScale && yScale == aOther.yScale; + } + + bool operator!=(const ScaleFactors2D<src, dst>& aOther) const { + return !(*this == aOther); + } + + friend std::ostream& operator<<(std::ostream& aStream, + const ScaleFactors2D<src, dst>& aScale) { + if (aScale.AreScalesSame()) { + return aStream << aScale.xScale; + } else { + return aStream << '(' << aScale.xScale << ',' << aScale.yScale << ')'; + } + } + + template<class other> + ScaleFactors2D<other, dst> operator/(const ScaleFactors2D<src, other>& aOther) const { + return ScaleFactors2D<other, dst>(xScale / aOther.xScale, yScale / aOther.yScale); + } + + template<class other> + ScaleFactors2D<src, other> operator/(const ScaleFactors2D<other, dst>& aOther) const { + return ScaleFactors2D<src, other>(xScale / aOther.xScale, yScale / aOther.yScale); + } + + template<class other> + ScaleFactors2D<src, other> operator*(const ScaleFactors2D<dst, other>& aOther) const { + return ScaleFactors2D<src, other>(xScale * aOther.xScale, yScale * aOther.yScale); + } + + template<class other> + ScaleFactors2D<other, dst> operator*(const ScaleFactors2D<other, src>& aOther) const { + return ScaleFactors2D<other, dst>(xScale * aOther.xScale, yScale * aOther.yScale); + } + + template<class other> + ScaleFactors2D<src, other> operator*(const ScaleFactor<dst, other>& aOther) const { + return *this * ScaleFactors2D<dst, other>(aOther); + } + + template<class other> + ScaleFactors2D<other, dst> operator*(const ScaleFactor<other, src>& aOther) const { + return *this * ScaleFactors2D<other, src>(aOther); + } + + template<class other> + ScaleFactors2D<src, other> operator/(const ScaleFactor<other, dst>& aOther) const { + return *this / ScaleFactors2D<other, dst>(aOther); + } + + template<class other> + ScaleFactors2D<other, dst> operator/(const ScaleFactor<src, other>& aOther) const { + return *this / ScaleFactors2D<src, other>(aOther); + } + + template<class other> + friend ScaleFactors2D<other, dst> operator*(const ScaleFactor<other, src>& aA, + const ScaleFactors2D<src, dst>& aB) { + return ScaleFactors2D<other, src>(aA) * aB; + } + + template<class other> + friend ScaleFactors2D<other, src> operator/(const ScaleFactor<other, dst>& aA, + const ScaleFactors2D<src, dst>& aB) { + return ScaleFactors2D<other, src>(aA) / aB; + } + + // Divide two scales of the same units, yielding a scale with no units, + // represented as a gfxSize. This can mean e.g. the cahnge in a particular + // scale from one frame to the next. + gfxSize operator/(const ScaleFactors2D& aOther) const { + return gfxSize(xScale / aOther.xScale, yScale / aOther.yScale); + } +}; + +} // namespace gfx +} // namespace mozilla + +#endif /* MOZILLA_GFX_SCALEFACTORS2D_H_ */ |