12256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez// Use of this source code is governed by a BSD-style license that can be 32256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez// found in the LICENSE file. 42256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 52256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#ifndef UI_GFX_GEOMETRY_POINT_H_ 62256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#define UI_GFX_GEOMETRY_POINT_H_ 72256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 82256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#include <iosfwd> 92256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#include <string> 102256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#include <tuple> 112256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 122256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#include "base/numerics/saturated_arithmetic.h" 132256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#include "build/build_config.h" 142256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#include "ui/gfx/geometry/vector2d.h" 152256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#include "ui/gfx/gfx_export.h" 162256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 172256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#if defined(OS_WIN) 182256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chaveztypedef unsigned long DWORD; 192256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chaveztypedef struct tagPOINT POINT; 202256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#elif defined(OS_MACOSX) 212256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chaveztypedef struct CGPoint CGPoint; 222256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#endif 232256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 242256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chaveznamespace gfx { 252256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 262256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez// A point has an x and y coordinate. 272256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavezclass GFX_EXPORT Point { 282256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez public: 292256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez constexpr Point() : x_(0), y_(0) {} 302256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez constexpr Point(int x, int y) : x_(x), y_(y) {} 312256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#if defined(OS_WIN) 322256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez // |point| is a DWORD value that contains a coordinate. The x-coordinate is 332256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez // the low-order short and the y-coordinate is the high-order short. This 342256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez // value is commonly acquired from GetMessagePos/GetCursorPos. 352256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez explicit Point(DWORD point); 362256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez explicit Point(const POINT& point); 372256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez Point& operator=(const POINT& point); 382256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#elif defined(OS_MACOSX) 392256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez explicit Point(const CGPoint& point); 402256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#endif 412256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 422256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#if defined(OS_WIN) 432256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez POINT ToPOINT() const; 442256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#elif defined(OS_MACOSX) 452256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez CGPoint ToCGPoint() const; 462256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#endif 472256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 482256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez constexpr int x() const { return x_; } 492256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez constexpr int y() const { return y_; } 502256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez void set_x(int x) { x_ = x; } 512256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez void set_y(int y) { y_ = y; } 522256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 532256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez void SetPoint(int x, int y) { 542256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez x_ = x; 552256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez y_ = y; 562256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez } 572256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 582256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez void Offset(int delta_x, int delta_y) { 592256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez x_ = base::SaturatedAddition(x_, delta_x); 602256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez y_ = base::SaturatedAddition(y_, delta_y); 612256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez } 622256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 632256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez void operator+=(const Vector2d& vector) { 642256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez x_ = base::SaturatedAddition(x_, vector.x()); 652256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez y_ = base::SaturatedAddition(y_, vector.y()); 662256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez } 672256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 682256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez void operator-=(const Vector2d& vector) { 692256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez x_ = base::SaturatedSubtraction(x_, vector.x()); 702256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez y_ = base::SaturatedSubtraction(y_, vector.y()); 712256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez } 722256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 732256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez void SetToMin(const Point& other); 742256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez void SetToMax(const Point& other); 752256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 762256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez bool IsOrigin() const { return x_ == 0 && y_ == 0; } 772256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 782256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez Vector2d OffsetFromOrigin() const { return Vector2d(x_, y_); } 792256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 802256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez // A point is less than another point if its y-value is closer 812256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez // to the origin. If the y-values are the same, then point with 822256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez // the x-value closer to the origin is considered less than the 832256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez // other. 842256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez // This comparison is required to use Point in sets, or sorted 852256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez // vectors. 862256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez bool operator<(const Point& rhs) const { 872256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez return std::tie(y_, x_) < std::tie(rhs.y_, rhs.x_); 882256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez } 892256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 902256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez // Returns a string representation of point. 912256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez std::string ToString() const; 922256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 932256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez private: 942256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez int x_; 952256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez int y_; 962256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez}; 972256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 982256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavezinline bool operator==(const Point& lhs, const Point& rhs) { 992256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez return lhs.x() == rhs.x() && lhs.y() == rhs.y(); 1002256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez} 1012256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 1022256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavezinline bool operator!=(const Point& lhs, const Point& rhs) { 1032256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez return !(lhs == rhs); 1042256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez} 1052256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 1062256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavezinline Point operator+(const Point& lhs, const Vector2d& rhs) { 1072256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez Point result(lhs); 1082256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez result += rhs; 1092256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez return result; 1102256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez} 1112256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 1122256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavezinline Point operator-(const Point& lhs, const Vector2d& rhs) { 1132256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez Point result(lhs); 1142256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez result -= rhs; 1152256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez return result; 1162256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez} 1172256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 1182256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavezinline Vector2d operator-(const Point& lhs, const Point& rhs) { 1192256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez return Vector2d(base::SaturatedSubtraction(lhs.x(), rhs.x()), 1202256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez base::SaturatedSubtraction(lhs.y(), rhs.y())); 1212256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez} 1222256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 1232256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavezinline Point PointAtOffsetFromOrigin(const Vector2d& offset_from_origin) { 1242256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez return Point(offset_from_origin.x(), offset_from_origin.y()); 1252256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez} 1262256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 1272256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez// This is declared here for use in gtest-based unit tests but is defined in 1282256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez// the //ui/gfx:test_support target. Depend on that to use this in your unit 1292256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez// test. This should not be used in production code - call ToString() instead. 1302256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavezvoid PrintTo(const Point& point, ::std::ostream* os); 1312256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 1322256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez// Helper methods to scale a gfx::Point to a new gfx::Point. 1332256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector ChavezGFX_EXPORT Point ScaleToCeiledPoint(const Point& point, 1342256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez float x_scale, 1352256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez float y_scale); 1362256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector ChavezGFX_EXPORT Point ScaleToCeiledPoint(const Point& point, float x_scale); 1372256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector ChavezGFX_EXPORT Point ScaleToFlooredPoint(const Point& point, 1382256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez float x_scale, 1392256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez float y_scale); 1402256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector ChavezGFX_EXPORT Point ScaleToFlooredPoint(const Point& point, float x_scale); 1412256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector ChavezGFX_EXPORT Point ScaleToRoundedPoint(const Point& point, 1422256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez float x_scale, 1432256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez float y_scale); 1442256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector ChavezGFX_EXPORT Point ScaleToRoundedPoint(const Point& point, float x_scale); 1452256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 1462256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez} // namespace gfx 1472256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez 1482256d987b3a5bffb7da4a7212a2e482d45785957Luis Hector Chavez#endif // UI_GFX_GEOMETRY_POINT_H_ 149