зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1157984 - Part 1: Extend gfx::2d classes to support both float and double precision,r=jrmuizel
- Implemented templates for Coord, Point, Point3D, Point4D, Size, Margin and Rect to create double precision versions. --HG-- extra : rebase_source : 91e16a7b970026346b6e90a23427fd0f70491765
This commit is contained in:
Родитель
87aa5dec6e
Коммит
0f397fb78d
|
@ -7,6 +7,7 @@
|
|||
#define MOZILLA_GFX_COORD_H_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/TypeTraits.h" // For IsSame
|
||||
#include "Types.h"
|
||||
#include "BaseCoord.h"
|
||||
|
||||
|
@ -19,7 +20,7 @@ template <typename> struct IsPixel;
|
|||
namespace gfx {
|
||||
|
||||
template <class units> struct IntCoordTyped;
|
||||
template <class units> struct CoordTyped;
|
||||
template <class units, class F = Float> struct CoordTyped;
|
||||
|
||||
// CommonType<coord, primitive> is a metafunction that returns the type of the
|
||||
// result of an arithmetic operation on the underlying type of a strongly-typed
|
||||
|
@ -37,9 +38,9 @@ struct CommonType<IntCoordTyped<units>, primitive> {
|
|||
typedef decltype(int32_t() + primitive()) type;
|
||||
};
|
||||
|
||||
template <class units, class primitive>
|
||||
struct CommonType<CoordTyped<units>, primitive> {
|
||||
typedef decltype(Float() + primitive()) type;
|
||||
template <class units, class F, class primitive>
|
||||
struct CommonType<CoordTyped<units, F>, primitive> {
|
||||
typedef decltype(F() + primitive()) type;
|
||||
};
|
||||
|
||||
// This is a base class that provides mixed-type operator overloads between
|
||||
|
@ -48,8 +49,15 @@ struct CommonType<CoordTyped<units>, primitive> {
|
|||
// convertible to their underlying value type. As we transition more of our code
|
||||
// to strongly-typed classes, we may be able to remove some or all of these
|
||||
// overloads.
|
||||
template <class coord, class primitive>
|
||||
|
||||
template <bool B, class coord, class primitive>
|
||||
struct CoordOperatorsHelper {
|
||||
// Using SFINAE (Substitution Failure Is Not An Error) to suppress redundant
|
||||
// operators
|
||||
};
|
||||
|
||||
template <class coord, class primitive>
|
||||
struct CoordOperatorsHelper<true, coord, primitive> {
|
||||
friend bool operator==(coord aA, primitive aB) {
|
||||
return aA.value == aB;
|
||||
}
|
||||
|
@ -95,8 +103,8 @@ struct CoordOperatorsHelper {
|
|||
template<class units>
|
||||
struct IntCoordTyped :
|
||||
public BaseCoord< int32_t, IntCoordTyped<units> >,
|
||||
public CoordOperatorsHelper< IntCoordTyped<units>, float >,
|
||||
public CoordOperatorsHelper< IntCoordTyped<units>, double > {
|
||||
public CoordOperatorsHelper< true, IntCoordTyped<units>, float >,
|
||||
public CoordOperatorsHelper< true, IntCoordTyped<units>, double > {
|
||||
static_assert(IsPixel<units>::value,
|
||||
"'units' must be a coordinate system tag");
|
||||
|
||||
|
@ -106,20 +114,21 @@ struct IntCoordTyped :
|
|||
MOZ_CONSTEXPR MOZ_IMPLICIT IntCoordTyped(int32_t aValue) : Super(aValue) {}
|
||||
};
|
||||
|
||||
template<class units>
|
||||
template<class units, class F>
|
||||
struct CoordTyped :
|
||||
public BaseCoord< Float, CoordTyped<units> >,
|
||||
public CoordOperatorsHelper< CoordTyped<units>, int32_t >,
|
||||
public CoordOperatorsHelper< CoordTyped<units>, uint32_t >,
|
||||
public CoordOperatorsHelper< CoordTyped<units>, double > {
|
||||
public BaseCoord< F, CoordTyped<units, F> >,
|
||||
public CoordOperatorsHelper< !IsSame<F, int32_t>::value, CoordTyped<units, F>, int32_t >,
|
||||
public CoordOperatorsHelper< !IsSame<F, uint32_t>::value, CoordTyped<units, F>, uint32_t >,
|
||||
public CoordOperatorsHelper< !IsSame<F, double>::value, CoordTyped<units, F>, double >,
|
||||
public CoordOperatorsHelper< !IsSame<F, float>::value, CoordTyped<units, F>, float > {
|
||||
static_assert(IsPixel<units>::value,
|
||||
"'units' must be a coordinate system tag");
|
||||
|
||||
typedef BaseCoord< Float, CoordTyped<units> > Super;
|
||||
typedef BaseCoord< F, CoordTyped<units, F> > Super;
|
||||
|
||||
MOZ_CONSTEXPR CoordTyped() : Super() {}
|
||||
MOZ_CONSTEXPR MOZ_IMPLICIT CoordTyped(Float aValue) : Super(aValue) {}
|
||||
explicit MOZ_CONSTEXPR CoordTyped(const IntCoordTyped<units>& aCoord) : Super(float(aCoord.value)) {}
|
||||
MOZ_CONSTEXPR MOZ_IMPLICIT CoordTyped(F aValue) : Super(aValue) {}
|
||||
explicit MOZ_CONSTEXPR CoordTyped(const IntCoordTyped<units>& aCoord) : Super(F(aCoord.value)) {}
|
||||
|
||||
void Round() {
|
||||
this->value = floor(this->value + 0.5);
|
||||
|
|
|
@ -64,37 +64,38 @@ struct IntPointTyped :
|
|||
};
|
||||
typedef IntPointTyped<UnknownUnits> IntPoint;
|
||||
|
||||
template<class units>
|
||||
template<class units, class F = Float>
|
||||
struct PointTyped :
|
||||
public BasePoint< Float, PointTyped<units>, CoordTyped<units> >,
|
||||
public BasePoint< F, PointTyped<units, F>, CoordTyped<units, F> >,
|
||||
public units {
|
||||
static_assert(IsPixel<units>::value,
|
||||
"'units' must be a coordinate system tag");
|
||||
|
||||
typedef CoordTyped<units> Coord;
|
||||
typedef BasePoint< Float, PointTyped<units>, CoordTyped<units> > Super;
|
||||
typedef CoordTyped<units, F> Coord;
|
||||
typedef BasePoint< F, PointTyped<units, F>, CoordTyped<units, F> > Super;
|
||||
|
||||
MOZ_CONSTEXPR PointTyped() : Super() {}
|
||||
MOZ_CONSTEXPR PointTyped(Float aX, Float aY) : Super(Coord(aX), Coord(aY)) {}
|
||||
MOZ_CONSTEXPR PointTyped(F aX, F aY) : Super(Coord(aX), Coord(aY)) {}
|
||||
// The mixed-type constructors (Float, Coord) and (Coord, Float) are needed to
|
||||
// avoid ambiguities because Coord is implicitly convertible to Float.
|
||||
MOZ_CONSTEXPR PointTyped(Float aX, Coord aY) : Super(Coord(aX), aY) {}
|
||||
MOZ_CONSTEXPR PointTyped(Coord aX, Float aY) : Super(aX, Coord(aY)) {}
|
||||
MOZ_CONSTEXPR PointTyped(F aX, Coord aY) : Super(Coord(aX), aY) {}
|
||||
MOZ_CONSTEXPR PointTyped(Coord aX, F aY) : Super(aX, Coord(aY)) {}
|
||||
MOZ_CONSTEXPR PointTyped(Coord aX, Coord aY) : Super(aX.value, aY.value) {}
|
||||
MOZ_CONSTEXPR MOZ_IMPLICIT PointTyped(const IntPointTyped<units>& point) : Super(float(point.x), float(point.y)) {}
|
||||
MOZ_CONSTEXPR MOZ_IMPLICIT PointTyped(const IntPointTyped<units>& point) : Super(F(point.x), F(point.y)) {}
|
||||
|
||||
// XXX When all of the code is ported, the following functions to convert to and from
|
||||
// unknown types should be removed.
|
||||
|
||||
static PointTyped<units> FromUnknownPoint(const PointTyped<UnknownUnits>& aPoint) {
|
||||
return PointTyped<units>(aPoint.x, aPoint.y);
|
||||
static PointTyped<units, F> FromUnknownPoint(const PointTyped<UnknownUnits, F>& aPoint) {
|
||||
return PointTyped<units, F>(aPoint.x, aPoint.y);
|
||||
}
|
||||
|
||||
PointTyped<UnknownUnits> ToUnknownPoint() const {
|
||||
return PointTyped<UnknownUnits>(this->x, this->y);
|
||||
PointTyped<UnknownUnits, F> ToUnknownPoint() const {
|
||||
return PointTyped<UnknownUnits, F>(this->x, this->y);
|
||||
}
|
||||
};
|
||||
typedef PointTyped<UnknownUnits> Point;
|
||||
typedef PointTyped<UnknownUnits, double> PointDouble;
|
||||
|
||||
template<class units>
|
||||
IntPointTyped<units> RoundedToInt(const PointTyped<units>& aPoint) {
|
||||
|
@ -108,57 +109,59 @@ IntPointTyped<units> TruncatedToInt(const PointTyped<units>& aPoint) {
|
|||
int32_t(aPoint.y));
|
||||
}
|
||||
|
||||
template<class units>
|
||||
template<class units, class F = Float>
|
||||
struct Point3DTyped :
|
||||
public BasePoint3D< Float, Point3DTyped<units> > {
|
||||
public BasePoint3D< F, Point3DTyped<units, F> > {
|
||||
static_assert(IsPixel<units>::value,
|
||||
"'units' must be a coordinate system tag");
|
||||
|
||||
typedef BasePoint3D< Float, Point3DTyped<units> > Super;
|
||||
typedef BasePoint3D< F, Point3DTyped<units, F> > Super;
|
||||
|
||||
Point3DTyped() : Super() {}
|
||||
Point3DTyped(Float aX, Float aY, Float aZ) : Super(aX, aY, aZ) {}
|
||||
Point3DTyped(F aX, F aY, F aZ) : Super(aX, aY, aZ) {}
|
||||
|
||||
// XXX When all of the code is ported, the following functions to convert to and from
|
||||
// unknown types should be removed.
|
||||
|
||||
static Point3DTyped<units> FromUnknownPoint(const Point3DTyped<UnknownUnits>& aPoint) {
|
||||
return Point3DTyped<units>(aPoint.x, aPoint.y, aPoint.z);
|
||||
static Point3DTyped<units, F> FromUnknownPoint(const Point3DTyped<UnknownUnits, F>& aPoint) {
|
||||
return Point3DTyped<units, F>(aPoint.x, aPoint.y, aPoint.z);
|
||||
}
|
||||
|
||||
Point3DTyped<UnknownUnits> ToUnknownPoint() const {
|
||||
return Point3DTyped<UnknownUnits>(this->x, this->y, this->z);
|
||||
Point3DTyped<UnknownUnits, F> ToUnknownPoint() const {
|
||||
return Point3DTyped<UnknownUnits, F>(this->x, this->y, this->z);
|
||||
}
|
||||
};
|
||||
typedef Point3DTyped<UnknownUnits> Point3D;
|
||||
typedef Point3DTyped<UnknownUnits, double> PointDouble3D;
|
||||
|
||||
template<class units>
|
||||
template<class units, class F = Float>
|
||||
struct Point4DTyped :
|
||||
public BasePoint4D< Float, Point4DTyped<units> > {
|
||||
public BasePoint4D< F, Point4DTyped<units, F> > {
|
||||
static_assert(IsPixel<units>::value,
|
||||
"'units' must be a coordinate system tag");
|
||||
|
||||
typedef BasePoint4D< Float, Point4DTyped<units> > Super;
|
||||
typedef BasePoint4D< F, Point4DTyped<units, F> > Super;
|
||||
|
||||
Point4DTyped() : Super() {}
|
||||
Point4DTyped(Float aX, Float aY, Float aZ, Float aW) : Super(aX, aY, aZ, aW) {}
|
||||
Point4DTyped(F aX, F aY, F aZ, F aW) : Super(aX, aY, aZ, aW) {}
|
||||
|
||||
// XXX When all of the code is ported, the following functions to convert to and from
|
||||
// unknown types should be removed.
|
||||
|
||||
static Point4DTyped<units> FromUnknownPoint(const Point4DTyped<UnknownUnits>& aPoint) {
|
||||
return Point4DTyped<units>(aPoint.x, aPoint.y, aPoint.z, aPoint.w);
|
||||
static Point4DTyped<units, F> FromUnknownPoint(const Point4DTyped<UnknownUnits, F>& aPoint) {
|
||||
return Point4DTyped<units, F>(aPoint.x, aPoint.y, aPoint.z, aPoint.w);
|
||||
}
|
||||
|
||||
Point4DTyped<UnknownUnits> ToUnknownPoint() const {
|
||||
return Point4DTyped<UnknownUnits>(this->x, this->y, this->z, this->w);
|
||||
Point4DTyped<UnknownUnits, F> ToUnknownPoint() const {
|
||||
return Point4DTyped<UnknownUnits, F>(this->x, this->y, this->z, this->w);
|
||||
}
|
||||
|
||||
PointTyped<units> As2DPoint() {
|
||||
return PointTyped<units>(this->x / this->w, this->y / this->w);
|
||||
PointTyped<units, F> As2DPoint() {
|
||||
return PointTyped<units, F>(this->x / this->w, this->y / this->w);
|
||||
}
|
||||
};
|
||||
typedef Point4DTyped<UnknownUnits> Point4D;
|
||||
typedef Point4DTyped<UnknownUnits, double> PointDouble4D;
|
||||
|
||||
template<class units>
|
||||
struct IntSizeTyped :
|
||||
|
@ -185,32 +188,33 @@ struct IntSizeTyped :
|
|||
};
|
||||
typedef IntSizeTyped<UnknownUnits> IntSize;
|
||||
|
||||
template<class units>
|
||||
template<class units, class F = Float>
|
||||
struct SizeTyped :
|
||||
public BaseSize< Float, SizeTyped<units> >,
|
||||
public BaseSize< F, SizeTyped<units> >,
|
||||
public units {
|
||||
static_assert(IsPixel<units>::value,
|
||||
"'units' must be a coordinate system tag");
|
||||
|
||||
typedef BaseSize< Float, SizeTyped<units> > Super;
|
||||
typedef BaseSize< F, SizeTyped<units, F> > Super;
|
||||
|
||||
MOZ_CONSTEXPR SizeTyped() : Super() {}
|
||||
MOZ_CONSTEXPR SizeTyped(Float aWidth, Float aHeight) : Super(aWidth, aHeight) {}
|
||||
MOZ_CONSTEXPR SizeTyped(F aWidth, F aHeight) : Super(aWidth, aHeight) {}
|
||||
explicit SizeTyped(const IntSizeTyped<units>& size) :
|
||||
Super(float(size.width), float(size.height)) {}
|
||||
Super(F(size.width), F(size.height)) {}
|
||||
|
||||
// XXX When all of the code is ported, the following functions to convert to and from
|
||||
// unknown types should be removed.
|
||||
|
||||
static SizeTyped<units> FromUnknownSize(const SizeTyped<UnknownUnits>& aSize) {
|
||||
return SizeTyped<units>(aSize.width, aSize.height);
|
||||
static SizeTyped<units, F> FromUnknownSize(const SizeTyped<UnknownUnits, F>& aSize) {
|
||||
return SizeTyped<units, F>(aSize.width, aSize.height);
|
||||
}
|
||||
|
||||
SizeTyped<UnknownUnits> ToUnknownSize() const {
|
||||
return SizeTyped<UnknownUnits>(this->width, this->height);
|
||||
SizeTyped<UnknownUnits, F> ToUnknownSize() const {
|
||||
return SizeTyped<UnknownUnits, F>(this->width, this->height);
|
||||
}
|
||||
};
|
||||
typedef SizeTyped<UnknownUnits> Size;
|
||||
typedef SizeTyped<UnknownUnits, double> SizeDouble;
|
||||
|
||||
template<class units>
|
||||
IntSizeTyped<units> RoundedToInt(const SizeTyped<units>& aSize) {
|
||||
|
|
|
@ -35,23 +35,24 @@ struct IntMarginTyped:
|
|||
};
|
||||
typedef IntMarginTyped<UnknownUnits> IntMargin;
|
||||
|
||||
template<class units>
|
||||
template<class units, class F = Float>
|
||||
struct MarginTyped:
|
||||
public BaseMargin<Float, MarginTyped<units> >,
|
||||
public BaseMargin<F, MarginTyped<units> >,
|
||||
public units {
|
||||
static_assert(IsPixel<units>::value,
|
||||
"'units' must be a coordinate system tag");
|
||||
|
||||
typedef BaseMargin<Float, MarginTyped<units> > Super;
|
||||
typedef BaseMargin<F, MarginTyped<units, F> > Super;
|
||||
|
||||
MarginTyped() : Super() {}
|
||||
MarginTyped(Float aTop, Float aRight, Float aBottom, Float aLeft) :
|
||||
MarginTyped(F aTop, F aRight, F aBottom, F aLeft) :
|
||||
Super(aTop, aRight, aBottom, aLeft) {}
|
||||
explicit MarginTyped(const IntMarginTyped<units>& aMargin) :
|
||||
Super(float(aMargin.top), float(aMargin.right),
|
||||
float(aMargin.bottom), float(aMargin.left)) {}
|
||||
Super(F(aMargin.top), F(aMargin.right),
|
||||
F(aMargin.bottom), F(aMargin.left)) {}
|
||||
};
|
||||
typedef MarginTyped<UnknownUnits> Margin;
|
||||
typedef MarginTyped<UnknownUnits, double> MarginDouble;
|
||||
|
||||
template<class units>
|
||||
IntMarginTyped<units> RoundedToInt(const MarginTyped<units>& aMargin)
|
||||
|
@ -124,23 +125,23 @@ struct IntRectTyped :
|
|||
};
|
||||
typedef IntRectTyped<UnknownUnits> IntRect;
|
||||
|
||||
template<class units>
|
||||
template<class units, class F = Float>
|
||||
struct RectTyped :
|
||||
public BaseRect<Float, RectTyped<units>, PointTyped<units>, SizeTyped<units>, MarginTyped<units> >,
|
||||
public BaseRect<F, RectTyped<units, F>, PointTyped<units, F>, SizeTyped<units, F>, MarginTyped<units, F> >,
|
||||
public units {
|
||||
static_assert(IsPixel<units>::value,
|
||||
"'units' must be a coordinate system tag");
|
||||
|
||||
typedef BaseRect<Float, RectTyped<units>, PointTyped<units>, SizeTyped<units>, MarginTyped<units> > Super;
|
||||
typedef BaseRect<F, RectTyped<units, F>, PointTyped<units, F>, SizeTyped<units, F>, MarginTyped<units, F> > Super;
|
||||
|
||||
RectTyped() : Super() {}
|
||||
RectTyped(const PointTyped<units>& aPos, const SizeTyped<units>& aSize) :
|
||||
RectTyped(const PointTyped<units, F>& aPos, const SizeTyped<units, F>& aSize) :
|
||||
Super(aPos, aSize) {}
|
||||
RectTyped(Float _x, Float _y, Float _width, Float _height) :
|
||||
RectTyped(F _x, F _y, F _width, F _height) :
|
||||
Super(_x, _y, _width, _height) {}
|
||||
explicit RectTyped(const IntRectTyped<units>& rect) :
|
||||
Super(float(rect.x), float(rect.y),
|
||||
float(rect.width), float(rect.height)) {}
|
||||
Super(F(rect.x), F(rect.y),
|
||||
F(rect.width), F(rect.height)) {}
|
||||
|
||||
void NudgeToIntegers()
|
||||
{
|
||||
|
@ -154,29 +155,30 @@ struct RectTyped :
|
|||
{
|
||||
*aOut = IntRectTyped<units>(int32_t(this->X()), int32_t(this->Y()),
|
||||
int32_t(this->Width()), int32_t(this->Height()));
|
||||
return RectTyped<units>(Float(aOut->x), Float(aOut->y),
|
||||
Float(aOut->width), Float(aOut->height))
|
||||
return RectTyped<units>(F(aOut->x), F(aOut->y),
|
||||
F(aOut->width), F(aOut->height))
|
||||
.IsEqualEdges(*this);
|
||||
}
|
||||
|
||||
// XXX When all of the code is ported, the following functions to convert to and from
|
||||
// unknown types should be removed.
|
||||
|
||||
static RectTyped<units> FromUnknownRect(const RectTyped<UnknownUnits>& rect) {
|
||||
return RectTyped<units>(rect.x, rect.y, rect.width, rect.height);
|
||||
static RectTyped<units, F> FromUnknownRect(const RectTyped<UnknownUnits, F>& rect) {
|
||||
return RectTyped<units, F>(rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
|
||||
RectTyped<UnknownUnits> ToUnknownRect() const {
|
||||
return RectTyped<UnknownUnits>(this->x, this->y, this->width, this->height);
|
||||
RectTyped<UnknownUnits, F> ToUnknownRect() const {
|
||||
return RectTyped<UnknownUnits, F>(this->x, this->y, this->width, this->height);
|
||||
}
|
||||
|
||||
// This is here only to keep IPDL-generated code happy. DO NOT USE.
|
||||
bool operator==(const RectTyped<units>& aRect) const
|
||||
bool operator==(const RectTyped<units, F>& aRect) const
|
||||
{
|
||||
return RectTyped<units>::IsEqualEdges(aRect);
|
||||
return RectTyped<units, F>::IsEqualEdges(aRect);
|
||||
}
|
||||
};
|
||||
typedef RectTyped<UnknownUnits> Rect;
|
||||
typedef RectTyped<UnknownUnits, double> RectDouble;
|
||||
|
||||
template<class units>
|
||||
IntRectTyped<units> RoundedToInt(const RectTyped<units>& aRect)
|
||||
|
|
|
@ -527,10 +527,10 @@ struct ParamTraits< mozilla::gfx::PointTyped<T> >
|
|||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ParamTraits< mozilla::gfx::Point3DTyped<T> >
|
||||
template<class F, class T>
|
||||
struct ParamTraits< mozilla::gfx::Point3DTyped<F, T> >
|
||||
{
|
||||
typedef mozilla::gfx::Point3DTyped<T> paramType;
|
||||
typedef mozilla::gfx::Point3DTyped<F, T> paramType;
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
|
|
|
@ -21,7 +21,7 @@ struct gfxRGBA;
|
|||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class Matrix4x4;
|
||||
template <class units> struct RectTyped;
|
||||
template <class units, class F> struct RectTyped;
|
||||
} // namespace gfx
|
||||
|
||||
enum class ImageFormat;
|
||||
|
|
|
@ -24,6 +24,11 @@ inline Rect ToRect(const gfxRect &aRect)
|
|||
Float(aRect.width), Float(aRect.height));
|
||||
}
|
||||
|
||||
inline RectDouble ToRectDouble(const gfxRect &aRect)
|
||||
{
|
||||
return RectDouble(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
}
|
||||
|
||||
inline Rect ToRect(const IntRect &aRect)
|
||||
{
|
||||
return Rect(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
|
@ -143,6 +148,11 @@ inline gfxRect ThebesRect(const Rect &aRect)
|
|||
return gfxRect(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
}
|
||||
|
||||
inline gfxRect ThebesRect(const RectDouble &aRect)
|
||||
{
|
||||
return gfxRect(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
}
|
||||
|
||||
inline gfxRGBA ThebesRGBA(const Color &aColor)
|
||||
{
|
||||
return gfxRGBA(aColor.r, aColor.g, aColor.b, aColor.a);
|
||||
|
|
Загрузка…
Ссылка в новой задаче