• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2009 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 "base/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 <iostream>
16 
17 #include "base/logging.h"
18 
19 namespace {
20 
AdjustAlongAxis(int dst_origin,int dst_size,int * origin,int * size)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 
Rect()35 Rect::Rect() {
36 }
37 
Rect(int width,int height)38 Rect::Rect(int width, int height) {
39   set_width(width);
40   set_height(height);
41 }
42 
Rect(int x,int y,int width,int height)43 Rect::Rect(int x, int y, int width, int height)
44     : origin_(x, y) {
45   set_width(width);
46   set_height(height);
47 }
48 
Rect(const gfx::Point & origin,const gfx::Size & size)49 Rect::Rect(const gfx::Point& origin, const gfx::Size& size)
50     : origin_(origin), size_(size) {
51 }
52 
53 #if defined(OS_WIN)
Rect(const RECT & r)54 Rect::Rect(const RECT& r)
55     : origin_(r.left, r.top) {
56   set_width(r.right - r.left);
57   set_height(r.bottom - r.top);
58 }
59 
operator =(const RECT & r)60 Rect& Rect::operator=(const RECT& r) {
61   origin_.SetPoint(r.left, r.top);
62   set_width(r.right - r.left);
63   set_height(r.bottom - r.top);
64   return *this;
65 }
66 #elif defined(OS_MACOSX)
Rect(const CGRect & r)67 Rect::Rect(const CGRect& r)
68     : origin_(r.origin.x, r.origin.y) {
69   set_width(r.size.width);
70   set_height(r.size.height);
71 }
72 
operator =(const CGRect & r)73 Rect& Rect::operator=(const CGRect& r) {
74   origin_.SetPoint(r.origin.x, r.origin.y);
75   set_width(r.size.width);
76   set_height(r.size.height);
77   return *this;
78 }
79 #elif defined(OS_POSIX)
Rect(const GdkRectangle & r)80 Rect::Rect(const GdkRectangle& r)
81     : origin_(r.x, r.y) {
82   set_width(r.width);
83   set_height(r.height);
84 }
85 
operator =(const GdkRectangle & r)86 Rect& Rect::operator=(const GdkRectangle& r) {
87   origin_.SetPoint(r.x, r.y);
88   set_width(r.width);
89   set_height(r.height);
90   return *this;
91 }
92 #endif
93 
set_width(int width)94 void Rect::set_width(int width) {
95   size_.set_width(width);
96 }
set_height(int height)97 void Rect::set_height(int height) {
98   size_.set_height(height);
99 }
100 
SetRect(int x,int y,int width,int height)101 void Rect::SetRect(int x, int y, int width, int height) {
102   origin_.SetPoint(x, y);
103   set_width(width);
104   set_height(height);
105 }
106 
Inset(int left,int top,int right,int bottom)107 void Rect::Inset(int left, int top, int right, int bottom) {
108   Offset(left, top);
109   set_width(std::max(width() - left - right, 0));
110   set_height(std::max(height() - top - bottom, 0));
111 }
112 
Offset(int horizontal,int vertical)113 void Rect::Offset(int horizontal, int vertical) {
114   set_x(x() + horizontal);
115   set_y(y() + vertical);
116 }
117 
operator ==(const Rect & other) const118 bool Rect::operator==(const Rect& other) const {
119   return origin_ == other.origin_ && size_ == other.size_;
120 }
121 
122 #if defined(OS_WIN)
ToRECT() const123 RECT Rect::ToRECT() const {
124   RECT r;
125   r.left = x();
126   r.right = right();
127   r.top = y();
128   r.bottom = bottom();
129   return r;
130 }
131 #elif defined(OS_MACOSX)
ToCGRect() const132 CGRect Rect::ToCGRect() const {
133   return CGRectMake(x(), y(), width(), height());
134 }
135 #elif defined(OS_POSIX)
ToGdkRectangle() const136 GdkRectangle Rect::ToGdkRectangle() const {
137   GdkRectangle r = {x(), y(), width(), height()};
138   return r;
139 }
140 #endif
141 
Contains(int point_x,int point_y) const142 bool Rect::Contains(int point_x, int point_y) const {
143   return (point_x >= x()) && (point_x < right()) &&
144          (point_y >= y()) && (point_y < bottom());
145 }
146 
Contains(const Rect & rect) const147 bool Rect::Contains(const Rect& rect) const {
148   return (rect.x() >= x() && rect.right() <= right() &&
149           rect.y() >= y() && rect.bottom() <= bottom());
150 }
151 
Intersects(const Rect & rect) const152 bool Rect::Intersects(const Rect& rect) const {
153   return !(rect.x() >= right() || rect.right() <= x() ||
154            rect.y() >= bottom() || rect.bottom() <= y());
155 }
156 
Intersect(const Rect & rect) const157 Rect Rect::Intersect(const Rect& rect) const {
158   int rx = std::max(x(), rect.x());
159   int ry = std::max(y(), rect.y());
160   int rr = std::min(right(), rect.right());
161   int rb = std::min(bottom(), rect.bottom());
162 
163   if (rx >= rr || ry >= rb)
164     rx = ry = rr = rb = 0;  // non-intersecting
165 
166   return Rect(rx, ry, rr - rx, rb - ry);
167 }
168 
Union(const Rect & rect) const169 Rect Rect::Union(const Rect& rect) const {
170   // special case empty rects...
171   if (IsEmpty())
172     return rect;
173   if (rect.IsEmpty())
174     return *this;
175 
176   int rx = std::min(x(), rect.x());
177   int ry = std::min(y(), rect.y());
178   int rr = std::max(right(), rect.right());
179   int rb = std::max(bottom(), rect.bottom());
180 
181   return Rect(rx, ry, rr - rx, rb - ry);
182 }
183 
Subtract(const Rect & rect) const184 Rect Rect::Subtract(const Rect& rect) const {
185   // boundary cases:
186   if (!Intersects(rect))
187     return *this;
188   if (rect.Contains(*this))
189     return Rect();
190 
191   int rx = x();
192   int ry = y();
193   int rr = right();
194   int rb = bottom();
195 
196   if (rect.y() <= y() && rect.bottom() >= bottom()) {
197     // complete intersection in the y-direction
198     if (rect.x() <= x()) {
199       rx = rect.right();
200     } else {
201       rr = rect.x();
202     }
203   } else if (rect.x() <= x() && rect.right() >= right()) {
204     // complete intersection in the x-direction
205     if (rect.y() <= y()) {
206       ry = rect.bottom();
207     } else {
208       rb = rect.y();
209     }
210   }
211   return Rect(rx, ry, rr - rx, rb - ry);
212 }
213 
AdjustToFit(const Rect & rect) const214 Rect Rect::AdjustToFit(const Rect& rect) const {
215   int new_x = x();
216   int new_y = y();
217   int new_width = width();
218   int new_height = height();
219   AdjustAlongAxis(rect.x(), rect.width(), &new_x, &new_width);
220   AdjustAlongAxis(rect.y(), rect.height(), &new_y, &new_height);
221   return Rect(new_x, new_y, new_width, new_height);
222 }
223 
CenterPoint() const224 Point Rect::CenterPoint() const {
225   return Point(x() + (width() + 1) / 2, y() + (height() + 1) / 2);
226 }
227 
SharesEdgeWith(const gfx::Rect & rect) const228 bool Rect::SharesEdgeWith(const gfx::Rect& rect) const {
229   return (y() == rect.y() && height() == rect.height() &&
230              (x() == rect.right() || right() == rect.x())) ||
231          (x() == rect.x() && width() == rect.width() &&
232              (y() == rect.bottom() || bottom() == rect.y()));
233 }
234 
235 }  // namespace gfx
236 
operator <<(std::ostream & out,const gfx::Rect & r)237 std::ostream& operator<<(std::ostream& out, const gfx::Rect& r) {
238   return out << r.origin() << " " << r.size();
239 }
240