LCOV - code coverage report
Current view: top level - gfx/2d - Point.h (source / functions) Hit Total Coverage
Test: output.info Lines: 45 67 67.2 %
Date: 2017-07-14 16:53:18 Functions: 94 154 61.0 %
Legend: Lines: hit not hit

          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_POINT_H_
       7             : #define MOZILLA_GFX_POINT_H_
       8             : 
       9             : #include "mozilla/Attributes.h"
      10             : #include "Types.h"
      11             : #include "Coord.h"
      12             : #include "BaseCoord.h"
      13             : #include "BasePoint.h"
      14             : #include "BasePoint3D.h"
      15             : #include "BasePoint4D.h"
      16             : #include "BaseSize.h"
      17             : #include "mozilla/Maybe.h"
      18             : #include "mozilla/TypeTraits.h"
      19             : 
      20             : #include <cmath>
      21             : 
      22             : namespace mozilla {
      23             : 
      24             : template <typename> struct IsPixel;
      25             : 
      26             : namespace gfx {
      27             : 
      28             : // This should only be used by the typedefs below.
      29       98133 : struct UnknownUnits {};
      30             : 
      31             : } // namespace gfx
      32             : 
      33             : template<> struct IsPixel<gfx::UnknownUnits> : TrueType {};
      34             : 
      35             : namespace gfx {
      36             : 
      37             : /// Use this for parameters of functions to allow implicit conversions to
      38             : /// integer types but not floating point types.
      39             : /// We use this wrapper to prevent IntSize and IntPoint's constructors to
      40             : /// take foating point values as parameters, and not require their constructors
      41             : /// to have implementations for each permutation of integer types.
      42             : template<typename T>
      43             : struct IntParam {
      44             :   constexpr MOZ_IMPLICIT IntParam(char val) : value(val) {}
      45             :   constexpr MOZ_IMPLICIT IntParam(unsigned char val) : value(val) {}
      46           0 :   constexpr MOZ_IMPLICIT IntParam(short val) : value(val) {}
      47           0 :   constexpr MOZ_IMPLICIT IntParam(unsigned short val) : value(val) {}
      48       70660 :   constexpr MOZ_IMPLICIT IntParam(int val) : value(val) {}
      49         198 :   constexpr MOZ_IMPLICIT IntParam(unsigned int val) : value(val) {}
      50           4 :   constexpr MOZ_IMPLICIT IntParam(long val) : value(val) {}
      51           0 :   constexpr MOZ_IMPLICIT IntParam(unsigned long val) : value(val) {}
      52             :   constexpr MOZ_IMPLICIT IntParam(long long val) : value(val) {}
      53             :   constexpr MOZ_IMPLICIT IntParam(unsigned long long val) : value(val) {}
      54             :   template<typename Unit>
      55             :   constexpr MOZ_IMPLICIT IntParam(IntCoordTyped<Unit> val) : value(val) {}
      56             : 
      57             :   // Disable the evil ones!
      58             :   MOZ_IMPLICIT IntParam(float val) = delete;
      59             :   MOZ_IMPLICIT IntParam(double val) = delete;
      60             : 
      61             :   T value;
      62             : };
      63             : 
      64             : template<class units, class> struct PointTyped;
      65             : template<class units, class> struct SizeTyped;
      66             : 
      67             : template<class units>
      68             : struct IntPointTyped :
      69             :   public BasePoint< int32_t, IntPointTyped<units>, IntCoordTyped<units> >,
      70             :   public units {
      71             :   static_assert(IsPixel<units>::value,
      72             :                 "'units' must be a coordinate system tag");
      73             : 
      74             :   typedef IntParam<int32_t> ToInt;
      75             :   typedef IntCoordTyped<units> Coord;
      76             :   typedef BasePoint< int32_t, IntPointTyped<units>, IntCoordTyped<units> > Super;
      77             : 
      78        1380 :   constexpr IntPointTyped() : Super() {}
      79        9217 :   constexpr IntPointTyped(ToInt aX, ToInt aY) : Super(Coord(aX.value), Coord(aY.value)) {}
      80             : 
      81          69 :   static IntPointTyped<units> Round(float aX, float aY) {
      82          69 :     return IntPointTyped(int32_t(floorf(aX + 0.5)), int32_t(floorf(aY + 0.5)));
      83             :   }
      84             : 
      85             :   static IntPointTyped<units> Ceil(float aX, float aY) {
      86             :     return IntPointTyped(int32_t(ceil(aX)), int32_t(ceil(aY)));
      87             :   }
      88             : 
      89             :   static IntPointTyped<units> Floor(float aX, float aY) {
      90             :     return IntPointTyped(int32_t(floorf(aX)), int32_t(floorf(aY)));
      91             :   }
      92             : 
      93         291 :   static IntPointTyped<units> Truncate(float aX, float aY) {
      94         291 :     return IntPointTyped(int32_t(aX), int32_t(aY));
      95             :   }
      96             : 
      97             :   static IntPointTyped<units> Round(const PointTyped<units, float>& aPoint);
      98             :   static IntPointTyped<units> Ceil(const PointTyped<units, float>& aPoint);
      99             :   static IntPointTyped<units> Floor(const PointTyped<units, float>& aPoint);
     100             :   static IntPointTyped<units> Truncate(const PointTyped<units, float>& aPoint);
     101             : 
     102             :   // XXX When all of the code is ported, the following functions to convert to and from
     103             :   // unknown types should be removed.
     104             : 
     105          25 :   static IntPointTyped<units> FromUnknownPoint(const IntPointTyped<UnknownUnits>& aPoint) {
     106          25 :     return IntPointTyped<units>(aPoint.x, aPoint.y);
     107             :   }
     108             : 
     109           0 :   IntPointTyped<UnknownUnits> ToUnknownPoint() const {
     110           0 :     return IntPointTyped<UnknownUnits>(this->x, this->y);
     111             :   }
     112             : };
     113             : typedef IntPointTyped<UnknownUnits> IntPoint;
     114             : 
     115             : template<class units, class F = Float>
     116             : struct PointTyped :
     117             :   public BasePoint< F, PointTyped<units, F>, CoordTyped<units, F> >,
     118             :   public units {
     119             :   static_assert(IsPixel<units>::value,
     120             :                 "'units' must be a coordinate system tag");
     121             : 
     122             :   typedef CoordTyped<units, F> Coord;
     123             :   typedef BasePoint< F, PointTyped<units, F>, CoordTyped<units, F> > Super;
     124             : 
     125        4582 :   constexpr PointTyped() : Super() {}
     126       34772 :   constexpr PointTyped(F aX, F aY) : Super(Coord(aX), Coord(aY)) {}
     127             :   // The mixed-type constructors (Float, Coord) and (Coord, Float) are needed to
     128             :   // avoid ambiguities because Coord is implicitly convertible to Float.
     129           0 :   constexpr PointTyped(F aX, Coord aY) : Super(Coord(aX), aY) {}
     130           0 :   constexpr PointTyped(Coord aX, F aY) : Super(aX, Coord(aY)) {}
     131           0 :   constexpr PointTyped(Coord aX, Coord aY) : Super(aX.value, aY.value) {}
     132         314 :   constexpr MOZ_IMPLICIT PointTyped(const IntPointTyped<units>& point) : Super(F(point.x), F(point.y)) {}
     133             : 
     134         424 :   bool WithinEpsilonOf(const PointTyped<units, F>& aPoint, F aEpsilon) {
     135         424 :     return fabs(aPoint.x - this->x) < aEpsilon && fabs(aPoint.y - this->y) < aEpsilon;
     136             :   }
     137             : 
     138             :   // XXX When all of the code is ported, the following functions to convert to and from
     139             :   // unknown types should be removed.
     140             : 
     141           0 :   static PointTyped<units, F> FromUnknownPoint(const PointTyped<UnknownUnits, F>& aPoint) {
     142           0 :     return PointTyped<units, F>(aPoint.x, aPoint.y);
     143             :   }
     144             : 
     145           0 :   PointTyped<UnknownUnits, F> ToUnknownPoint() const {
     146           0 :     return PointTyped<UnknownUnits, F>(this->x, this->y);
     147             :   }
     148             : };
     149             : typedef PointTyped<UnknownUnits> Point;
     150             : typedef PointTyped<UnknownUnits, double> PointDouble;
     151             : 
     152             : template<class units>
     153          37 : IntPointTyped<units> RoundedToInt(const PointTyped<units>& aPoint) {
     154          37 :   return IntPointTyped<units>::Round(aPoint.x, aPoint.y);
     155             : }
     156             : 
     157             : template<class units>
     158           0 : IntPointTyped<units> TruncatedToInt(const PointTyped<units>& aPoint) {
     159           0 :   return IntPointTyped<units>::Truncate(aPoint.x, aPoint.y);
     160             : }
     161             : 
     162             : template<class units, class F = Float>
     163             : struct Point3DTyped :
     164             :   public BasePoint3D< F, Point3DTyped<units, F> > {
     165             :   static_assert(IsPixel<units>::value,
     166             :                 "'units' must be a coordinate system tag");
     167             : 
     168             :   typedef BasePoint3D< F, Point3DTyped<units, F> > Super;
     169             : 
     170          36 :   Point3DTyped() : Super() {}
     171         424 :   Point3DTyped(F aX, F aY, F aZ) : Super(aX, aY, aZ) {}
     172             : 
     173             :   // XXX When all of the code is ported, the following functions to convert to and from
     174             :   // unknown types should be removed.
     175             : 
     176             :   static Point3DTyped<units, F> FromUnknownPoint(const Point3DTyped<UnknownUnits, F>& aPoint) {
     177             :     return Point3DTyped<units, F>(aPoint.x, aPoint.y, aPoint.z);
     178             :   }
     179             : 
     180             :   Point3DTyped<UnknownUnits, F> ToUnknownPoint() const {
     181             :     return Point3DTyped<UnknownUnits, F>(this->x, this->y, this->z);
     182             :   }
     183             : };
     184             : typedef Point3DTyped<UnknownUnits> Point3D;
     185             : typedef Point3DTyped<UnknownUnits, double> PointDouble3D;
     186             : 
     187             : template<typename units>
     188             : IntPointTyped<units>
     189          26 : IntPointTyped<units>::Round(const PointTyped<units, float>& aPoint)
     190             : {
     191          26 :   return IntPointTyped::Round(aPoint.x, aPoint.y);
     192             : }
     193             : 
     194             : template<typename units>
     195             : IntPointTyped<units>
     196             : IntPointTyped<units>::Ceil(const PointTyped<units, float>& aPoint)
     197             : {
     198             :   return IntPointTyped::Ceil(aPoint.x, aPoint.y);
     199             : }
     200             : 
     201             : template<typename units>
     202             : IntPointTyped<units>
     203             : IntPointTyped<units>::Floor(const PointTyped<units, float>& aPoint)
     204             : {
     205             :   return IntPointTyped::Floor(aPoint.x, aPoint.y);
     206             : }
     207             : 
     208             : template<typename units>
     209             : IntPointTyped<units>
     210         121 : IntPointTyped<units>::Truncate(const PointTyped<units, float>& aPoint)
     211             : {
     212         121 :   return IntPointTyped::Truncate(aPoint.x, aPoint.y);
     213             : }
     214             : 
     215             : template<class units, class F = Float>
     216             : struct Point4DTyped :
     217             :   public BasePoint4D< F, Point4DTyped<units, F> > {
     218             :   static_assert(IsPixel<units>::value,
     219             :                 "'units' must be a coordinate system tag");
     220             : 
     221             :   typedef BasePoint4D< F, Point4DTyped<units, F> > Super;
     222             : 
     223       54345 :   Point4DTyped() : Super() {}
     224        8461 :   Point4DTyped(F aX, F aY, F aZ, F aW) : Super(aX, aY, aZ, aW) {}
     225             : 
     226             :   explicit Point4DTyped(const Point3DTyped<units, F>& aPoint)
     227             :     : Super(aPoint.x, aPoint.y, aPoint.z, 1) {}
     228             : 
     229             :   // XXX When all of the code is ported, the following functions to convert to and from
     230             :   // unknown types should be removed.
     231             : 
     232             :   static Point4DTyped<units, F> FromUnknownPoint(const Point4DTyped<UnknownUnits, F>& aPoint) {
     233             :     return Point4DTyped<units, F>(aPoint.x, aPoint.y, aPoint.z, aPoint.w);
     234             :   }
     235             : 
     236             :   Point4DTyped<UnknownUnits, F> ToUnknownPoint() const {
     237             :     return Point4DTyped<UnknownUnits, F>(this->x, this->y, this->z, this->w);
     238             :   }
     239             : 
     240        5629 :   PointTyped<units, F> As2DPoint() const {
     241        5629 :     return PointTyped<units, F>(this->x / this->w,
     242       11258 :                                 this->y / this->w);
     243             :   }
     244             : 
     245             :   Point3DTyped<units, F> As3DPoint() const {
     246             :     return Point3DTyped<units, F>(this->x / this->w,
     247             :                                   this->y / this->w,
     248             :                                   this->z / this->w);
     249             :   }
     250             : };
     251             : typedef Point4DTyped<UnknownUnits> Point4D;
     252             : typedef Point4DTyped<UnknownUnits, double> PointDouble4D;
     253             : 
     254             : template<class units>
     255             : struct IntSizeTyped :
     256             :   public BaseSize< int32_t, IntSizeTyped<units> >,
     257             :   public units {
     258             :   static_assert(IsPixel<units>::value,
     259             :                 "'units' must be a coordinate system tag");
     260             : 
     261             :   typedef IntParam<int32_t> ToInt;
     262             :   typedef BaseSize< int32_t, IntSizeTyped<units> > Super;
     263             : 
     264         991 :   constexpr IntSizeTyped() : Super() {}
     265        1942 :   constexpr IntSizeTyped(ToInt aWidth, ToInt aHeight) : Super(aWidth.value, aHeight.value) {}
     266             : 
     267           0 :   static IntSizeTyped<units> Round(float aWidth, float aHeight) {
     268           0 :     return IntSizeTyped(int32_t(floorf(aWidth + 0.5)), int32_t(floorf(aHeight + 0.5)));
     269             :   }
     270             : 
     271          13 :   static IntSizeTyped<units> Truncate(float aWidth, float aHeight) {
     272          13 :     return IntSizeTyped(int32_t(aWidth), int32_t(aHeight));
     273             :   }
     274             : 
     275         133 :   static IntSizeTyped<units> Ceil(float aWidth, float aHeight) {
     276         133 :     return IntSizeTyped(int32_t(ceil(aWidth)), int32_t(ceil(aHeight)));
     277             :   }
     278             : 
     279             :   static IntSizeTyped<units> Floor(float aWidth, float aHeight) {
     280             :     return IntSizeTyped(int32_t(floorf(aWidth)), int32_t(floorf(aHeight)));
     281             :   }
     282             : 
     283             :   static IntSizeTyped<units> Round(const SizeTyped<units, float>& aSize);
     284             :   static IntSizeTyped<units> Ceil(const SizeTyped<units, float>& aSize);
     285             :   static IntSizeTyped<units> Floor(const SizeTyped<units, float>& aSize);
     286             :   static IntSizeTyped<units> Truncate(const SizeTyped<units, float>& aSize);
     287             : 
     288             :   // XXX When all of the code is ported, the following functions to convert to and from
     289             :   // unknown types should be removed.
     290             : 
     291             :   static IntSizeTyped<units> FromUnknownSize(const IntSizeTyped<UnknownUnits>& aSize) {
     292             :     return IntSizeTyped<units>(aSize.width, aSize.height);
     293             :   }
     294             : 
     295           0 :   IntSizeTyped<UnknownUnits> ToUnknownSize() const {
     296           0 :     return IntSizeTyped<UnknownUnits>(this->width, this->height);
     297             :   }
     298             : };
     299             : typedef IntSizeTyped<UnknownUnits> IntSize;
     300             : typedef Maybe<IntSize> MaybeIntSize;
     301             : 
     302             : template<class units, class F = Float>
     303             : struct SizeTyped :
     304             :   public BaseSize< F, SizeTyped<units, F> >,
     305             :   public units {
     306             :   static_assert(IsPixel<units>::value,
     307             :                 "'units' must be a coordinate system tag");
     308             : 
     309             :   typedef BaseSize< F, SizeTyped<units, F> > Super;
     310             : 
     311          91 :   constexpr SizeTyped() : Super() {}
     312        5086 :   constexpr SizeTyped(F aWidth, F aHeight) : Super(aWidth, aHeight) {}
     313         103 :   explicit SizeTyped(const IntSizeTyped<units>& size) :
     314         103 :     Super(F(size.width), F(size.height)) {}
     315             : 
     316             :   // XXX When all of the code is ported, the following functions to convert to and from
     317             :   // unknown types should be removed.
     318             : 
     319             :   static SizeTyped<units, F> FromUnknownSize(const SizeTyped<UnknownUnits, F>& aSize) {
     320             :     return SizeTyped<units, F>(aSize.width, aSize.height);
     321             :   }
     322             : 
     323             :   SizeTyped<UnknownUnits, F> ToUnknownSize() const {
     324             :     return SizeTyped<UnknownUnits, F>(this->width, this->height);
     325             :   }
     326             : };
     327             : typedef SizeTyped<UnknownUnits> Size;
     328             : typedef SizeTyped<UnknownUnits, double> SizeDouble;
     329             : 
     330             : template<class units>
     331           3 : IntSizeTyped<units> RoundedToInt(const SizeTyped<units>& aSize) {
     332           3 :   return IntSizeTyped<units>(int32_t(floorf(aSize.width + 0.5f)),
     333           6 :                              int32_t(floorf(aSize.height + 0.5f)));
     334             : }
     335             : 
     336             : template<typename units> IntSizeTyped<units>
     337           0 : IntSizeTyped<units>::Round(const SizeTyped<units, float>& aSize) {
     338           0 :   return IntSizeTyped::Round(aSize.width, aSize.height);
     339             : }
     340             : 
     341             : template<typename units> IntSizeTyped<units>
     342           9 : IntSizeTyped<units>::Ceil(const SizeTyped<units, float>& aSize) {
     343           9 :   return IntSizeTyped::Ceil(aSize.width, aSize.height);
     344             : }
     345             : 
     346             : template<typename units> IntSizeTyped<units>
     347             : IntSizeTyped<units>::Floor(const SizeTyped<units, float>& aSize) {
     348             :   return IntSizeTyped::Floor(aSize.width, aSize.height);
     349             : }
     350             : 
     351             : template<typename units> IntSizeTyped<units>
     352           0 : IntSizeTyped<units>::Truncate(const SizeTyped<units, float>& aSize) {
     353           0 :   return IntSizeTyped::Truncate(aSize.width, aSize.height);
     354             : }
     355             : 
     356             : } // namespace gfx
     357             : } // namespace mozilla
     358             : 
     359             : #endif /* MOZILLA_GFX_POINT_H_ */

Generated by: LCOV version 1.13