OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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 #include "gfx/rect.h" | |
6 | |
7 #if defined(OS_WIN) | |
8 #include <windows.h> | |
9 #elif defined(OS_MACOSX) | |
10 #include <CoreGraphics/CGGeometry.h> | |
11 #elif defined(OS_POSIX) | |
12 #include <gdk/gdk.h> | |
13 #endif | |
14 | |
15 #include <ostream> | |
16 | |
17 #include "gfx/insets.h" | |
18 | |
19 namespace { | |
20 | |
21 void AdjustAlongAxis(int dst_origin, int dst_size, int* origin, int* size) { | |
22 if (*origin < dst_origin) { | |
23 *origin = dst_origin; | |
24 *size = std::min(dst_size, *size); | |
25 } else { | |
26 *size = std::min(dst_size, *size); | |
27 *origin = std::min(dst_origin + dst_size, *origin + *size) - *size; | |
28 } | |
29 } | |
30 | |
31 } // namespace | |
32 | |
33 namespace gfx { | |
34 | |
35 Rect::Rect() { | |
36 } | |
37 | |
38 Rect::Rect(int width, int height) | |
39 : size_(width, height) { | |
40 } | |
41 | |
42 Rect::Rect(int x, int y, int width, int height) | |
43 : origin_(x, y), size_(width, height) { | |
44 } | |
45 | |
46 Rect::Rect(const gfx::Size& size) | |
47 : size_(size) { | |
48 } | |
49 | |
50 Rect::Rect(const gfx::Point& origin, const gfx::Size& size) | |
51 : origin_(origin), size_(size) { | |
52 } | |
53 | |
54 #if defined(OS_WIN) | |
55 Rect::Rect(const RECT& r) | |
56 : origin_(r.left, r.top) { | |
57 set_width(r.right - r.left); | |
58 set_height(r.bottom - r.top); | |
59 } | |
60 | |
61 Rect& Rect::operator=(const RECT& r) { | |
62 origin_.SetPoint(r.left, r.top); | |
63 set_width(r.right - r.left); | |
64 set_height(r.bottom - r.top); | |
65 return *this; | |
66 } | |
67 #elif defined(OS_MACOSX) | |
68 Rect::Rect(const CGRect& r) | |
69 : origin_(r.origin.x, r.origin.y) { | |
70 set_width(r.size.width); | |
71 set_height(r.size.height); | |
72 } | |
73 | |
74 Rect& Rect::operator=(const CGRect& r) { | |
75 origin_.SetPoint(r.origin.x, r.origin.y); | |
76 set_width(r.size.width); | |
77 set_height(r.size.height); | |
78 return *this; | |
79 } | |
80 #elif defined(OS_POSIX) | |
81 Rect::Rect(const GdkRectangle& r) | |
82 : origin_(r.x, r.y) { | |
83 set_width(r.width); | |
84 set_height(r.height); | |
85 } | |
86 | |
87 Rect& Rect::operator=(const GdkRectangle& r) { | |
88 origin_.SetPoint(r.x, r.y); | |
89 set_width(r.width); | |
90 set_height(r.height); | |
91 return *this; | |
92 } | |
93 #endif | |
94 | |
95 void Rect::SetRect(int x, int y, int width, int height) { | |
96 origin_.SetPoint(x, y); | |
97 set_width(width); | |
98 set_height(height); | |
99 } | |
100 | |
101 void Rect::Inset(const gfx::Insets& insets) { | |
102 Inset(insets.left(), insets.top(), insets.right(), insets.bottom()); | |
103 } | |
104 | |
105 void Rect::Inset(int left, int top, int right, int bottom) { | |
106 Offset(left, top); | |
107 set_width(std::max(width() - left - right, 0)); | |
108 set_height(std::max(height() - top - bottom, 0)); | |
109 } | |
110 | |
111 void Rect::Offset(int horizontal, int vertical) { | |
112 origin_.Offset(horizontal, vertical); | |
113 } | |
114 | |
115 bool Rect::operator==(const Rect& other) const { | |
116 return origin_ == other.origin_ && size_ == other.size_; | |
117 } | |
118 | |
119 bool Rect::operator<(const Rect& other) const { | |
120 if (origin_ == other.origin_) { | |
121 if (width() == other.width()) { | |
122 return height() < other.height(); | |
123 } else { | |
124 return width() < other.width(); | |
125 } | |
126 } else { | |
127 return origin_ < other.origin_; | |
128 } | |
129 } | |
130 | |
131 #if defined(OS_WIN) | |
132 RECT Rect::ToRECT() const { | |
133 RECT r; | |
134 r.left = x(); | |
135 r.right = right(); | |
136 r.top = y(); | |
137 r.bottom = bottom(); | |
138 return r; | |
139 } | |
140 #elif defined(OS_MACOSX) | |
141 CGRect Rect::ToCGRect() const { | |
142 return CGRectMake(x(), y(), width(), height()); | |
143 } | |
144 #elif defined(OS_POSIX) | |
145 GdkRectangle Rect::ToGdkRectangle() const { | |
146 GdkRectangle r = {x(), y(), width(), height()}; | |
147 return r; | |
148 } | |
149 #endif | |
150 | |
151 bool Rect::Contains(int point_x, int point_y) const { | |
152 return (point_x >= x()) && (point_x < right()) && | |
153 (point_y >= y()) && (point_y < bottom()); | |
154 } | |
155 | |
156 bool Rect::Contains(const Rect& rect) const { | |
157 return (rect.x() >= x() && rect.right() <= right() && | |
158 rect.y() >= y() && rect.bottom() <= bottom()); | |
159 } | |
160 | |
161 bool Rect::Intersects(const Rect& rect) const { | |
162 return !(rect.x() >= right() || rect.right() <= x() || | |
163 rect.y() >= bottom() || rect.bottom() <= y()); | |
164 } | |
165 | |
166 Rect Rect::Intersect(const Rect& rect) const { | |
167 int rx = std::max(x(), rect.x()); | |
168 int ry = std::max(y(), rect.y()); | |
169 int rr = std::min(right(), rect.right()); | |
170 int rb = std::min(bottom(), rect.bottom()); | |
171 | |
172 if (rx >= rr || ry >= rb) | |
173 rx = ry = rr = rb = 0; // non-intersecting | |
174 | |
175 return Rect(rx, ry, rr - rx, rb - ry); | |
176 } | |
177 | |
178 Rect Rect::Union(const Rect& rect) const { | |
179 // special case empty rects... | |
180 if (IsEmpty()) | |
181 return rect; | |
182 if (rect.IsEmpty()) | |
183 return *this; | |
184 | |
185 int rx = std::min(x(), rect.x()); | |
186 int ry = std::min(y(), rect.y()); | |
187 int rr = std::max(right(), rect.right()); | |
188 int rb = std::max(bottom(), rect.bottom()); | |
189 | |
190 return Rect(rx, ry, rr - rx, rb - ry); | |
191 } | |
192 | |
193 Rect Rect::Subtract(const Rect& rect) const { | |
194 // boundary cases: | |
195 if (!Intersects(rect)) | |
196 return *this; | |
197 if (rect.Contains(*this)) | |
198 return Rect(); | |
199 | |
200 int rx = x(); | |
201 int ry = y(); | |
202 int rr = right(); | |
203 int rb = bottom(); | |
204 | |
205 if (rect.y() <= y() && rect.bottom() >= bottom()) { | |
206 // complete intersection in the y-direction | |
207 if (rect.x() <= x()) { | |
208 rx = rect.right(); | |
209 } else { | |
210 rr = rect.x(); | |
211 } | |
212 } else if (rect.x() <= x() && rect.right() >= right()) { | |
213 // complete intersection in the x-direction | |
214 if (rect.y() <= y()) { | |
215 ry = rect.bottom(); | |
216 } else { | |
217 rb = rect.y(); | |
218 } | |
219 } | |
220 return Rect(rx, ry, rr - rx, rb - ry); | |
221 } | |
222 | |
223 Rect Rect::AdjustToFit(const Rect& rect) const { | |
224 int new_x = x(); | |
225 int new_y = y(); | |
226 int new_width = width(); | |
227 int new_height = height(); | |
228 AdjustAlongAxis(rect.x(), rect.width(), &new_x, &new_width); | |
229 AdjustAlongAxis(rect.y(), rect.height(), &new_y, &new_height); | |
230 return Rect(new_x, new_y, new_width, new_height); | |
231 } | |
232 | |
233 Point Rect::CenterPoint() const { | |
234 return Point(x() + (width() + 1) / 2, y() + (height() + 1) / 2); | |
235 } | |
236 | |
237 Rect Rect::Center(const gfx::Size& size) const { | |
238 int new_width = std::min(width(), size.width()); | |
239 int new_height = std::min(height(), size.height()); | |
240 int new_x = x() + (width() - new_width) / 2; | |
241 int new_y = y() + (height() - new_height) / 2; | |
242 return Rect(new_x, new_y, new_width, new_height); | |
243 } | |
244 | |
245 bool Rect::SharesEdgeWith(const gfx::Rect& rect) const { | |
246 return (y() == rect.y() && height() == rect.height() && | |
247 (x() == rect.right() || right() == rect.x())) || | |
248 (x() == rect.x() && width() == rect.width() && | |
249 (y() == rect.bottom() || bottom() == rect.y())); | |
250 } | |
251 | |
252 std::ostream& operator<<(std::ostream& out, const gfx::Rect& r) { | |
253 return out << r.origin() << " " << r.size(); | |
254 } | |
255 | |
256 } // namespace gfx | |
OLD | NEW |