blob: b7e2942fc94d0fa49dde9c059fa19e1ef8413dc8 [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// Copyright (c) 2006-2008 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.
initial.commit3f4a7322008-07-27 06:49:38 +09004
5#include "base/gfx/rect.h"
6
avi@google.com82277242008-08-07 05:38:29 +09007#if defined(OS_WIN)
initial.commit3f4a7322008-07-27 06:49:38 +09008#include <windows.h>
avi@google.com82277242008-08-07 05:38:29 +09009#elif defined(OS_MACOSX)
10#include <CoreGraphics/CGGeometry.h>
11#endif
initial.commit3f4a7322008-07-27 06:49:38 +090012
13#include "base/logging.h"
14
15namespace {
16
17void AdjustAlongAxis(int dst_origin, int dst_size, int* origin, int* size) {
18 if (*origin < dst_origin) {
19 *origin = dst_origin;
20 *size = std::min(dst_size, *size);
21 } else {
22 *size = std::min(dst_size, *size);
23 *origin = std::min(dst_origin + dst_size, *origin + *size) - *size;
24 }
25}
26
27} // namespace
28
29namespace gfx {
30
31Rect::Rect() {
32}
33
34Rect::Rect(int width, int height) {
35 set_width(width);
36 set_height(height);
37}
38
39Rect::Rect(int x, int y, int width, int height)
40 : origin_(x, y) {
41 set_width(width);
42 set_height(height);
43}
44
avi@google.com82277242008-08-07 05:38:29 +090045#if defined(OS_WIN)
initial.commit3f4a7322008-07-27 06:49:38 +090046Rect::Rect(const RECT& r)
47 : origin_(r.left, r.top) {
48 set_width(r.right - r.left);
49 set_height(r.bottom - r.top);
50}
51
52Rect& Rect::operator=(const RECT& r) {
53 origin_.SetPoint(r.left, r.top);
54 set_width(r.right - r.left);
55 set_height(r.bottom - r.top);
56 return *this;
57}
avi@google.com82277242008-08-07 05:38:29 +090058#elif defined(OS_MACOSX)
59Rect::Rect(const CGRect& r)
60 : origin_(r.origin.x, r.origin.y) {
61 set_width(r.size.width);
62 set_height(r.size.height);
63}
64
65Rect& Rect::operator=(const CGRect& r) {
66 origin_.SetPoint(r.origin.x, r.origin.y);
67 set_width(r.size.width);
68 set_height(r.size.height);
69 return *this;
70}
71#endif
initial.commit3f4a7322008-07-27 06:49:38 +090072
73void Rect::set_width(int width) {
74 if (width < 0) {
75 NOTREACHED();
76 width = 0;
77 }
78
79 size_.set_width(width);
80}
81void Rect::set_height(int height) {
82 if (height < 0) {
83 NOTREACHED();
84 height = 0;
85 }
86
87 size_.set_height(height);
88}
89
90void Rect::SetRect(int x, int y, int width, int height) {
91 origin_.SetPoint(x, y);
92 set_width(width);
93 set_height(height);
94}
95
96void Rect::Inset(int horizontal, int vertical) {
97 set_x(x() + horizontal);
98 set_y(y() + vertical);
99 set_width(std::max(width() - (horizontal * 2), 0));
100 set_height(std::max(height() - (vertical * 2), 0));
101}
102
103void Rect::Offset(int horizontal, int vertical) {
104 set_x(x() + horizontal);
105 set_y(y() + vertical);
106}
107
108bool Rect::IsEmpty() const {
109 return width() == 0 || height() == 0;
110}
111
112bool Rect::operator==(const Rect& other) const {
113 return origin_ == other.origin_ && size_ == other.size_;
114}
115
avi@google.com82277242008-08-07 05:38:29 +0900116#if defined(OS_WIN)
initial.commit3f4a7322008-07-27 06:49:38 +0900117RECT Rect::ToRECT() const {
118 RECT r;
119 r.left = x();
120 r.right = right();
121 r.top = y();
122 r.bottom = bottom();
123 return r;
124}
avi@google.com82277242008-08-07 05:38:29 +0900125#elif defined(OS_MACOSX)
126CGRect Rect::ToCGRect() const {
127 return CGRectMake(x(), y(), width(), height());
128}
129#endif
initial.commit3f4a7322008-07-27 06:49:38 +0900130
131bool Rect::Contains(int point_x, int point_y) const {
132 return (point_x >= x()) && (point_x < right()) &&
133 (point_y >= y()) && (point_y < bottom());
134}
135
136bool Rect::Contains(const Rect& rect) const {
137 return (rect.x() >= x() && rect.right() <= right() &&
138 rect.y() >= y() && rect.bottom() <= bottom());
139}
140
141bool Rect::Intersects(const Rect& rect) const {
142 return !(rect.x() >= right() || rect.right() <= x() ||
143 rect.y() >= bottom() || rect.bottom() <= y());
144}
145
146Rect Rect::Intersect(const Rect& rect) const {
147 int rx = std::max(x(), rect.x());
148 int ry = std::max(y(), rect.y());
149 int rr = std::min(right(), rect.right());
150 int rb = std::min(bottom(), rect.bottom());
151
152 if (rx >= rr || ry >= rb)
153 rx = ry = rr = rb = 0; // non-intersecting
154
155 return Rect(rx, ry, rr - rx, rb - ry);
156}
157
158Rect Rect::Union(const Rect& rect) const {
159 // special case empty rects...
160 if (IsEmpty())
161 return rect;
162 if (rect.IsEmpty())
163 return *this;
164
165 int rx = std::min(x(), rect.x());
166 int ry = std::min(y(), rect.y());
167 int rr = std::max(right(), rect.right());
168 int rb = std::max(bottom(), rect.bottom());
169
170 return Rect(rx, ry, rr - rx, rb - ry);
171}
172
173Rect Rect::Subtract(const Rect& rect) const {
174 // boundary cases:
175 if (!Intersects(rect))
176 return *this;
177 if (rect.Contains(*this))
178 return Rect();
179
180 int rx = x();
181 int ry = y();
182 int rr = right();
183 int rb = bottom();
184
185 if (rect.y() <= y() && rect.bottom() >= bottom()) {
186 // complete intersection in the y-direction
187 if (rect.x() <= x()) {
188 rx = rect.right();
189 } else {
190 rr = rect.x();
191 }
192 } else if (rect.x() <= x() && rect.right() >= right()) {
193 // complete intersection in the x-direction
194 if (rect.y() <= y()) {
195 ry = rect.bottom();
196 } else {
197 rb = rect.y();
198 }
199 }
200 return Rect(rx, ry, rr - rx, rb - ry);
201}
202
203Rect Rect::AdjustToFit(const Rect& rect) const {
204 int new_x = x();
205 int new_y = y();
206 int new_width = width();
207 int new_height = height();
208 AdjustAlongAxis(rect.x(), rect.width(), &new_x, &new_width);
209 AdjustAlongAxis(rect.y(), rect.height(), &new_y, &new_height);
210 return Rect(new_x, new_y, new_width, new_height);
211}
212
213Point Rect::CenterPoint() const {
214 return Point(x() + (width() + 1) / 2, y() + (height() + 1) / 2);
215}
216
217} // namespace gfx
license.botf003cfe2008-08-24 09:55:55 +0900218