license.bot | f003cfe | 2008-08-24 09:55:55 +0900 | [diff] [blame^] | 1 | // 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.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 4 | |
| 5 | #include "base/gfx/rect.h" |
| 6 | |
avi@google.com | 8227724 | 2008-08-07 05:38:29 +0900 | [diff] [blame] | 7 | #if defined(OS_WIN) |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 8 | #include <windows.h> |
avi@google.com | 8227724 | 2008-08-07 05:38:29 +0900 | [diff] [blame] | 9 | #elif defined(OS_MACOSX) |
| 10 | #include <CoreGraphics/CGGeometry.h> |
| 11 | #endif |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 12 | |
| 13 | #include "base/logging.h" |
| 14 | |
| 15 | namespace { |
| 16 | |
| 17 | void 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 | |
| 29 | namespace gfx { |
| 30 | |
| 31 | Rect::Rect() { |
| 32 | } |
| 33 | |
| 34 | Rect::Rect(int width, int height) { |
| 35 | set_width(width); |
| 36 | set_height(height); |
| 37 | } |
| 38 | |
| 39 | Rect::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.com | 8227724 | 2008-08-07 05:38:29 +0900 | [diff] [blame] | 45 | #if defined(OS_WIN) |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 46 | Rect::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 | |
| 52 | Rect& 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.com | 8227724 | 2008-08-07 05:38:29 +0900 | [diff] [blame] | 58 | #elif defined(OS_MACOSX) |
| 59 | Rect::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 | |
| 65 | Rect& 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.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 72 | |
| 73 | void Rect::set_width(int width) { |
| 74 | if (width < 0) { |
| 75 | NOTREACHED(); |
| 76 | width = 0; |
| 77 | } |
| 78 | |
| 79 | size_.set_width(width); |
| 80 | } |
| 81 | void Rect::set_height(int height) { |
| 82 | if (height < 0) { |
| 83 | NOTREACHED(); |
| 84 | height = 0; |
| 85 | } |
| 86 | |
| 87 | size_.set_height(height); |
| 88 | } |
| 89 | |
| 90 | void 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 | |
| 96 | void 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 | |
| 103 | void Rect::Offset(int horizontal, int vertical) { |
| 104 | set_x(x() + horizontal); |
| 105 | set_y(y() + vertical); |
| 106 | } |
| 107 | |
| 108 | bool Rect::IsEmpty() const { |
| 109 | return width() == 0 || height() == 0; |
| 110 | } |
| 111 | |
| 112 | bool Rect::operator==(const Rect& other) const { |
| 113 | return origin_ == other.origin_ && size_ == other.size_; |
| 114 | } |
| 115 | |
avi@google.com | 8227724 | 2008-08-07 05:38:29 +0900 | [diff] [blame] | 116 | #if defined(OS_WIN) |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 117 | RECT 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.com | 8227724 | 2008-08-07 05:38:29 +0900 | [diff] [blame] | 125 | #elif defined(OS_MACOSX) |
| 126 | CGRect Rect::ToCGRect() const { |
| 127 | return CGRectMake(x(), y(), width(), height()); |
| 128 | } |
| 129 | #endif |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 130 | |
| 131 | bool 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 | |
| 136 | bool Rect::Contains(const Rect& rect) const { |
| 137 | return (rect.x() >= x() && rect.right() <= right() && |
| 138 | rect.y() >= y() && rect.bottom() <= bottom()); |
| 139 | } |
| 140 | |
| 141 | bool Rect::Intersects(const Rect& rect) const { |
| 142 | return !(rect.x() >= right() || rect.right() <= x() || |
| 143 | rect.y() >= bottom() || rect.bottom() <= y()); |
| 144 | } |
| 145 | |
| 146 | Rect 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 | |
| 158 | Rect 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 | |
| 173 | Rect 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 | |
| 203 | Rect 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 | |
| 213 | Point Rect::CenterPoint() const { |
| 214 | return Point(x() + (width() + 1) / 2, y() + (height() + 1) / 2); |
| 215 | } |
| 216 | |
| 217 | } // namespace gfx |
license.bot | f003cfe | 2008-08-24 09:55:55 +0900 | [diff] [blame^] | 218 | |