1 /*
2  * Copyright (C) 2004, 2006, 2007 Apple Inc.  All rights reserved.
3  * Copyright (C) 2005 Nokia.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_FLOAT_POINT_H_
28 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_FLOAT_POINT_H_
29 
30 #include <iosfwd>
31 #include "build/build_config.h"
32 #include "third_party/blink/renderer/platform/geometry/float_size.h"
33 #include "third_party/blink/renderer/platform/geometry/int_point.h"
34 #include "third_party/blink/renderer/platform/geometry/int_size.h"
35 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
36 #include "third_party/blink/renderer/platform/wtf/forward.h"
37 #include "third_party/blink/renderer/platform/wtf/hash_traits.h"
38 #include "third_party/skia/include/core/SkPoint.h"
39 #include "ui/gfx/geometry/point3_f.h"
40 #include "ui/gfx/geometry/point_f.h"
41 #include "ui/gfx/geometry/scroll_offset.h"
42 
43 #if defined(OS_MAC)
44 typedef struct CGPoint CGPoint;
45 
46 #ifdef __OBJC__
47 #import <Foundation/Foundation.h>
48 #endif
49 #endif
50 
51 namespace blink {
52 
53 class PLATFORM_EXPORT FloatPoint {
54   DISALLOW_NEW();
55 
56  public:
FloatPoint()57   constexpr FloatPoint() : x_(0), y_(0) {}
FloatPoint(float x,float y)58   constexpr FloatPoint(float x, float y) : x_(x), y_(y) {}
FloatPoint(const IntPoint & p)59   constexpr explicit FloatPoint(const IntPoint& p) : x_(p.X()), y_(p.Y()) {}
FloatPoint(const SkPoint & p)60   explicit FloatPoint(const SkPoint& p) : x_(p.x()), y_(p.y()) {}
FloatPoint(const FloatSize & s)61   constexpr explicit FloatPoint(const FloatSize& s)
62       : x_(s.Width()), y_(s.Height()) {}
FloatPoint(const IntSize & s)63   constexpr explicit FloatPoint(const IntSize& s)
64       : x_(s.Width()), y_(s.Height()) {}
FloatPoint(const gfx::PointF & p)65   constexpr explicit FloatPoint(const gfx::PointF& p) : x_(p.x()), y_(p.y()) {}
FloatPoint(const gfx::Vector2dF & v)66   constexpr explicit FloatPoint(const gfx::Vector2dF& v)
67       : x_(v.x()), y_(v.y()) {}
68   // We also have conversion operators to FloatPoint defined LayoutPoint,
69   // LayoutSize and DoublePoint.
70 
Zero()71   static constexpr FloatPoint Zero() { return FloatPoint(); }
72 
73   static FloatPoint NarrowPrecision(double x, double y);
74 
IsValid()75   bool IsValid() const {
76     return x_ != -std::numeric_limits<float>::infinity() &&
77            y_ != -std::numeric_limits<float>::infinity();
78   }
79 
X()80   constexpr float X() const { return x_; }
Y()81   constexpr float Y() const { return y_; }
82 
SetX(float x)83   void SetX(float x) { x_ = x; }
SetY(float y)84   void SetY(float y) { y_ = y; }
Set(float x,float y)85   void Set(float x, float y) {
86     x_ = x;
87     y_ = y;
88   }
Move(float dx,float dy)89   void Move(float dx, float dy) {
90     x_ += dx;
91     y_ += dy;
92   }
Move(const IntSize & a)93   void Move(const IntSize& a) {
94     x_ += a.Width();
95     y_ += a.Height();
96   }
Move(const FloatSize & a)97   void Move(const FloatSize& a) {
98     x_ += a.Width();
99     y_ += a.Height();
100   }
MoveBy(const IntPoint & a)101   void MoveBy(const IntPoint& a) {
102     x_ += a.X();
103     y_ += a.Y();
104   }
MoveBy(const FloatPoint & a)105   void MoveBy(const FloatPoint& a) {
106     x_ += a.X();
107     y_ += a.Y();
108   }
Scale(float sx,float sy)109   void Scale(float sx, float sy) {
110     x_ *= sx;
111     y_ *= sy;
112   }
113 
Dot(const FloatPoint & a)114   float Dot(const FloatPoint& a) const { return x_ * a.X() + y_ * a.Y(); }
115 
116   float SlopeAngleRadians() const;
117   float length() const;
LengthSquared()118   float LengthSquared() const { return x_ * x_ + y_ * y_; }
119 
120   FloatPoint ExpandedTo(const FloatPoint& other) const;
121   FloatPoint ShrunkTo(const FloatPoint& other) const;
122 
TransposedPoint()123   FloatPoint TransposedPoint() const { return FloatPoint(y_, x_); }
124 
ScaledBy(float scale)125   FloatPoint ScaledBy(float scale) const {
126     return FloatPoint(x_ * scale, y_ * scale);
127   }
128 
129 #if defined(OS_MAC)
130   FloatPoint(const CGPoint&);
131   operator CGPoint() const;
132 #endif
133 
PointF()134   constexpr operator gfx::PointF() const { return gfx::PointF(x_, y_); }
Vector2dF()135   constexpr explicit operator gfx::Vector2dF() const {
136     return gfx::Vector2dF(x_, y_);
137   }
SkPoint()138   explicit operator SkPoint() const { return SkPoint::Make(x_, y_); }
ScrollOffset()139   explicit operator gfx::ScrollOffset() const {
140     return gfx::ScrollOffset(x_, y_);
141   }
Point3F()142   operator gfx::Point3F() const { return gfx::Point3F(x_, y_, 0.f); }
143 
144   String ToString() const;
145 
146  private:
147   float x_, y_;
148 
149   friend struct ::WTF::DefaultHash<blink::FloatSize>;
150   friend struct ::WTF::HashTraits<blink::FloatSize>;
151 };
152 
153 inline FloatPoint& operator+=(FloatPoint& a, const FloatSize& b) {
154   a.Move(b.Width(), b.Height());
155   return a;
156 }
157 
158 inline FloatPoint& operator+=(FloatPoint& a, const FloatPoint& b) {
159   a.Move(b.X(), b.Y());
160   return a;
161 }
162 
163 inline FloatPoint& operator-=(FloatPoint& a, const FloatSize& b) {
164   a.Move(-b.Width(), -b.Height());
165   return a;
166 }
167 
168 constexpr FloatPoint operator+(const FloatPoint& a, const FloatSize& b) {
169   return FloatPoint(a.X() + b.Width(), a.Y() + b.Height());
170 }
171 
172 constexpr FloatPoint operator+(const FloatPoint& a, const IntSize& b) {
173   return FloatPoint(a.X() + b.Width(), a.Y() + b.Height());
174 }
175 
176 constexpr FloatPoint operator+(const IntPoint& a, const FloatSize& b) {
177   return FloatPoint(a.X() + b.Width(), a.Y() + b.Height());
178 }
179 
180 constexpr FloatPoint operator+(const FloatPoint& a, const FloatPoint& b) {
181   return FloatPoint(a.X() + b.X(), a.Y() + b.Y());
182 }
183 
184 constexpr FloatPoint operator+(const FloatPoint& a, const IntPoint& b) {
185   return FloatPoint(a.X() + b.X(), a.Y() + b.Y());
186 }
187 
188 constexpr FloatSize operator-(const FloatPoint& a, const FloatPoint& b) {
189   return FloatSize(a.X() - b.X(), a.Y() - b.Y());
190 }
191 
192 constexpr FloatSize operator-(const FloatPoint& a, const IntPoint& b) {
193   return FloatSize(a.X() - b.X(), a.Y() - b.Y());
194 }
195 
196 constexpr FloatPoint operator-(const FloatPoint& a, const FloatSize& b) {
197   return FloatPoint(a.X() - b.Width(), a.Y() - b.Height());
198 }
199 
200 constexpr FloatPoint operator-(const FloatPoint& a) {
201   return FloatPoint(-a.X(), -a.Y());
202 }
203 
204 constexpr bool operator==(const FloatPoint& a, const FloatPoint& b) {
205   return a.X() == b.X() && a.Y() == b.Y();
206 }
207 
208 constexpr bool operator!=(const FloatPoint& a, const FloatPoint& b) {
209   return !(a == b);
210 }
211 
212 inline float operator*(const FloatPoint& a, const FloatPoint& b) {
213   // dot product
214   return a.Dot(b);
215 }
216 
217 inline IntPoint RoundedIntPoint(const FloatPoint& p) {
218   return IntPoint(clampTo<int>(roundf(p.X())), clampTo<int>(roundf(p.Y())));
219 }
220 
221 inline IntSize RoundedIntSize(const FloatPoint& p) {
222   return IntSize(clampTo<int>(roundf(p.X())), clampTo<int>(roundf(p.Y())));
223 }
224 
225 inline IntPoint FlooredIntPoint(const FloatPoint& p) {
226   return IntPoint(clampTo<int>(floorf(p.X())), clampTo<int>(floorf(p.Y())));
227 }
228 
229 inline IntPoint FlooredIntPoint(const gfx::PointF& p) {
230   return IntPoint(clampTo<int>(floorf(p.x())), clampTo<int>(floorf(p.y())));
231 }
232 
233 inline IntPoint CeiledIntPoint(const FloatPoint& p) {
234   return IntPoint(clampTo<int>(ceilf(p.X())), clampTo<int>(ceilf(p.Y())));
235 }
236 
237 inline IntSize FlooredIntSize(const FloatPoint& p) {
238   return IntSize(clampTo<int>(floorf(p.X())), clampTo<int>(floorf(p.Y())));
239 }
240 
241 inline FloatSize ToFloatSize(const FloatPoint& a) {
242   return FloatSize(a.X(), a.Y());
243 }
244 
245 // Find point where lines through the two pairs of points intersect.
246 // Returns false if the lines don't intersect.
247 PLATFORM_EXPORT bool FindIntersection(const FloatPoint& p1,
248                                       const FloatPoint& p2,
249                                       const FloatPoint& d1,
250                                       const FloatPoint& d2,
251                                       FloatPoint& intersection);
252 
253 PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const FloatPoint&);
254 PLATFORM_EXPORT WTF::TextStream& operator<<(WTF::TextStream&,
255                                             const FloatPoint&);
256 
257 }  // namespace blink
258 
259 namespace WTF {
260 
261 template <>
262 struct DefaultHash<blink::FloatPoint> {
263   STATIC_ONLY(DefaultHash);
264   struct Hash {
265     STATIC_ONLY(Hash);
266     typedef typename IntTypes<sizeof(float)>::UnsignedType Bits;
267     static unsigned GetHash(const blink::FloatPoint& key) {
268       return HashInts(bit_cast<Bits>(key.X()), bit_cast<Bits>(key.Y()));
269     }
270     static bool Equal(const blink::FloatPoint& a, const blink::FloatPoint& b) {
271       return bit_cast<Bits>(a.X()) == bit_cast<Bits>(b.X()) &&
272              bit_cast<Bits>(a.Y()) == bit_cast<Bits>(b.Y());
273     }
274     static const bool safe_to_compare_to_empty_or_deleted = true;
275   };
276 };
277 
278 template <>
279 struct HashTraits<blink::FloatPoint> : GenericHashTraits<blink::FloatPoint> {
280   STATIC_ONLY(HashTraits);
281   static const bool kEmptyValueIsZero = false;
282   static blink::FloatPoint EmptyValue() {
283     return blink::FloatPoint(std::numeric_limits<float>::infinity(),
284                              std::numeric_limits<float>::infinity());
285   }
286   static void ConstructDeletedValue(blink::FloatPoint& slot, bool) {
287     slot = blink::FloatPoint(-std::numeric_limits<float>::infinity(),
288                              -std::numeric_limits<float>::infinity());
289   }
290   static bool IsDeletedValue(const blink::FloatPoint& value) {
291     return !value.IsValid();
292   }
293 };
294 
295 }  // namespace WTF
296 
297 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_FLOAT_POINT_H_
298