summaryrefslogtreecommitdiff
path: root/chromium/ui/gfx/rect.h
blob: d983770dca847f2b0c0df2df19875ca6446a74c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Defines a simple integer rectangle class.  The containment semantics
// are array-like; that is, the coordinate (x, y) is considered to be
// contained by the rectangle, but the coordinate (x + width, y) is not.
// The class will happily let you create malformed rectangles (that is,
// rectangles with negative width and/or height), but there will be assertions
// in the operations (such as Contains()) to complain in this case.

#ifndef UI_GFX_RECT_H_
#define UI_GFX_RECT_H_

#include <cmath>
#include <string>

#include "ui/gfx/point.h"
#include "ui/gfx/rect_base.h"
#include "ui/gfx/rect_f.h"
#include "ui/gfx/size.h"
#include "ui/gfx/vector2d.h"

#if defined(OS_WIN)
typedef struct tagRECT RECT;
#elif defined(TOOLKIT_GTK)
typedef struct _GdkRectangle GdkRectangle;
#elif defined(OS_IOS)
#include <CoreGraphics/CoreGraphics.h>
#elif defined(OS_MACOSX)
#include <ApplicationServices/ApplicationServices.h>
#endif

namespace gfx {

class Insets;

class UI_EXPORT Rect
    : public RectBase<Rect, Point, Size, Insets, Vector2d, int> {
 public:
  Rect() : RectBase<Rect, Point, Size, Insets, Vector2d, int>(Point()) {}

  Rect(int width, int height)
      : RectBase<Rect, Point, Size, Insets, Vector2d, int>
            (Size(width, height)) {}

  Rect(int x, int y, int width, int height)
      : RectBase<Rect, Point, Size, Insets, Vector2d, int>
            (Point(x, y), Size(width, height)) {}

#if defined(OS_WIN)
  explicit Rect(const RECT& r);
#elif defined(OS_MACOSX)
  explicit Rect(const CGRect& r);
#elif defined(TOOLKIT_GTK)
  explicit Rect(const GdkRectangle& r);
#endif

  explicit Rect(const gfx::Size& size)
      : RectBase<Rect, Point, Size, Insets, Vector2d, int>(size) {}

  Rect(const gfx::Point& origin, const gfx::Size& size)
      : RectBase<Rect, Point, Size, Insets, Vector2d, int>(origin, size) {}

  ~Rect() {}

#if defined(OS_WIN)
  // Construct an equivalent Win32 RECT object.
  RECT ToRECT() const;
#elif defined(TOOLKIT_GTK)
  GdkRectangle ToGdkRectangle() const;
#elif defined(OS_MACOSX)
  // Construct an equivalent CoreGraphics object.
  CGRect ToCGRect() const;
#endif

  operator RectF() const {
    return RectF(origin().x(), origin().y(), size().width(), size().height());
  }

  std::string ToString() const;
};

inline bool operator==(const Rect& lhs, const Rect& rhs) {
  return lhs.origin() == rhs.origin() && lhs.size() == rhs.size();
}

inline bool operator!=(const Rect& lhs, const Rect& rhs) {
  return !(lhs == rhs);
}

UI_EXPORT Rect operator+(const Rect& lhs, const Vector2d& rhs);
UI_EXPORT Rect operator-(const Rect& lhs, const Vector2d& rhs);

inline Rect operator+(const Vector2d& lhs, const Rect& rhs) {
  return rhs + lhs;
}

UI_EXPORT Rect IntersectRects(const Rect& a, const Rect& b);
UI_EXPORT Rect UnionRects(const Rect& a, const Rect& b);
UI_EXPORT Rect SubtractRects(const Rect& a, const Rect& b);

// Constructs a rectangle with |p1| and |p2| as opposite corners.
//
// This could also be thought of as "the smallest rect that contains both
// points", except that we consider points on the right/bottom edges of the
// rect to be outside the rect.  So technically one or both points will not be
// contained within the rect, because they will appear on one of these edges.
UI_EXPORT Rect BoundingRect(const Point& p1, const Point& p2);

inline Rect ScaleToEnclosingRect(const Rect& rect,
                                 float x_scale,
                                 float y_scale) {
  int x = std::floor(rect.x() * x_scale);
  int y = std::floor(rect.y() * y_scale);
  int r = rect.width() == 0 ? x : std::ceil(rect.right() * x_scale);
  int b = rect.height() == 0 ? y : std::ceil(rect.bottom() * y_scale);
  return Rect(x, y, r - x, b - y);
}

inline Rect ScaleToEnclosingRect(const Rect& rect, float scale) {
  return ScaleToEnclosingRect(rect, scale, scale);
}

inline Rect ScaleToEnclosedRect(const Rect& rect,
                                float x_scale,
                                float y_scale) {
  int x = std::ceil(rect.x() * x_scale);
  int y = std::ceil(rect.y() * y_scale);
  int r = rect.width() == 0 ? x : std::floor(rect.right() * x_scale);
  int b = rect.height() == 0 ? y : std::floor(rect.bottom() * y_scale);
  return Rect(x, y, r - x, b - y);
}

inline Rect ScaleToEnclosedRect(const Rect& rect, float scale) {
  return ScaleToEnclosedRect(rect, scale, scale);
}

#if !defined(COMPILER_MSVC)
extern template class RectBase<Rect, Point, Size, Insets, Vector2d, int>;
#endif

}  // namespace gfx

#endif  // UI_GFX_RECT_H_