1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Defines a simple integer rectangle class.  The containment semantics
6// are array-like; that is, the coordinate (x, y) is considered to be
7// contained by the rectangle, but the coordinate (x + width, y) is not.
8// The class will happily let you create malformed rectangles (that is,
9// rectangles with negative width and/or height), but there will be assertions
10// in the operations (such as Contains()) to complain in this case.
11
12#ifndef UI_GFX_RECT_H_
13#define UI_GFX_RECT_H_
14
15#include <cmath>
16#include <string>
17
18#include "ui/gfx/point.h"
19#include "ui/gfx/rect_base.h"
20#include "ui/gfx/rect_f.h"
21#include "ui/gfx/size.h"
22#include "ui/gfx/vector2d.h"
23
24#if defined(OS_WIN)
25typedef struct tagRECT RECT;
26#elif defined(TOOLKIT_GTK)
27typedef struct _GdkRectangle GdkRectangle;
28#elif defined(OS_IOS)
29#include <CoreGraphics/CoreGraphics.h>
30#elif defined(OS_MACOSX)
31#include <ApplicationServices/ApplicationServices.h>
32#endif
33
34namespace gfx {
35
36class Insets;
37
38class UI_EXPORT Rect
39    : public RectBase<Rect, Point, Size, Insets, Vector2d, int> {
40 public:
41  Rect() : RectBase<Rect, Point, Size, Insets, Vector2d, int>(Point()) {}
42
43  Rect(int width, int height)
44      : RectBase<Rect, Point, Size, Insets, Vector2d, int>
45            (Size(width, height)) {}
46
47  Rect(int x, int y, int width, int height)
48      : RectBase<Rect, Point, Size, Insets, Vector2d, int>
49            (Point(x, y), Size(width, height)) {}
50
51#if defined(OS_WIN)
52  explicit Rect(const RECT& r);
53#elif defined(OS_MACOSX)
54  explicit Rect(const CGRect& r);
55#elif defined(TOOLKIT_GTK)
56  explicit Rect(const GdkRectangle& r);
57#endif
58
59  explicit Rect(const gfx::Size& size)
60      : RectBase<Rect, Point, Size, Insets, Vector2d, int>(size) {}
61
62  Rect(const gfx::Point& origin, const gfx::Size& size)
63      : RectBase<Rect, Point, Size, Insets, Vector2d, int>(origin, size) {}
64
65  ~Rect() {}
66
67#if defined(OS_WIN)
68  // Construct an equivalent Win32 RECT object.
69  RECT ToRECT() const;
70#elif defined(TOOLKIT_GTK)
71  GdkRectangle ToGdkRectangle() const;
72#elif defined(OS_MACOSX)
73  // Construct an equivalent CoreGraphics object.
74  CGRect ToCGRect() const;
75#endif
76
77  operator RectF() const {
78    return RectF(origin().x(), origin().y(), size().width(), size().height());
79  }
80
81  std::string ToString() const;
82};
83
84inline bool operator==(const Rect& lhs, const Rect& rhs) {
85  return lhs.origin() == rhs.origin() && lhs.size() == rhs.size();
86}
87
88inline bool operator!=(const Rect& lhs, const Rect& rhs) {
89  return !(lhs == rhs);
90}
91
92UI_EXPORT Rect operator+(const Rect& lhs, const Vector2d& rhs);
93UI_EXPORT Rect operator-(const Rect& lhs, const Vector2d& rhs);
94
95inline Rect operator+(const Vector2d& lhs, const Rect& rhs) {
96  return rhs + lhs;
97}
98
99UI_EXPORT Rect IntersectRects(const Rect& a, const Rect& b);
100UI_EXPORT Rect UnionRects(const Rect& a, const Rect& b);
101UI_EXPORT Rect SubtractRects(const Rect& a, const Rect& b);
102
103// Constructs a rectangle with |p1| and |p2| as opposite corners.
104//
105// This could also be thought of as "the smallest rect that contains both
106// points", except that we consider points on the right/bottom edges of the
107// rect to be outside the rect.  So technically one or both points will not be
108// contained within the rect, because they will appear on one of these edges.
109UI_EXPORT Rect BoundingRect(const Point& p1, const Point& p2);
110
111inline Rect ScaleToEnclosingRect(const Rect& rect,
112                                 float x_scale,
113                                 float y_scale) {
114  int x = std::floor(rect.x() * x_scale);
115  int y = std::floor(rect.y() * y_scale);
116  int r = rect.width() == 0 ? x : std::ceil(rect.right() * x_scale);
117  int b = rect.height() == 0 ? y : std::ceil(rect.bottom() * y_scale);
118  return Rect(x, y, r - x, b - y);
119}
120
121inline Rect ScaleToEnclosingRect(const Rect& rect, float scale) {
122  return ScaleToEnclosingRect(rect, scale, scale);
123}
124
125inline Rect ScaleToEnclosedRect(const Rect& rect,
126                                float x_scale,
127                                float y_scale) {
128  int x = std::ceil(rect.x() * x_scale);
129  int y = std::ceil(rect.y() * y_scale);
130  int r = rect.width() == 0 ? x : std::floor(rect.right() * x_scale);
131  int b = rect.height() == 0 ? y : std::floor(rect.bottom() * y_scale);
132  return Rect(x, y, r - x, b - y);
133}
134
135inline Rect ScaleToEnclosedRect(const Rect& rect, float scale) {
136  return ScaleToEnclosedRect(rect, scale, scale);
137}
138
139#if !defined(COMPILER_MSVC)
140extern template class RectBase<Rect, Point, Size, Insets, Vector2d, int>;
141#endif
142
143}  // namespace gfx
144
145#endif  // UI_GFX_RECT_H_
146