Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/geometry/rect.h" | 5 #include "ui/gfx/geometry/rect.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #if defined(OS_WIN) | 9 #if defined(OS_WIN) |
| 10 #include <windows.h> | 10 #include <windows.h> |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 53 if (*origin < dst_origin) | 53 if (*origin < dst_origin) |
| 54 *origin = dst_origin; | 54 *origin = dst_origin; |
| 55 else | 55 else |
| 56 *origin = std::min(dst_origin + dst_size, *origin + *size) - *size; | 56 *origin = std::min(dst_origin + dst_size, *origin + *size) - *size; |
| 57 } | 57 } |
| 58 | 58 |
| 59 } // namespace | 59 } // namespace |
| 60 | 60 |
| 61 namespace gfx { | 61 namespace gfx { |
| 62 | 62 |
| 63 // This is the per-axis heuristic for picking the most useful origin and | |
| 64 // width/height to represent the input range. | |
| 65 static void SaturatedClampRange(int min, int max, int* origin, int* span) { | |
| 66 if (max < min) { | |
| 67 *span = 0; | |
| 68 *origin = min; | |
| 69 return; | |
| 70 } | |
| 71 | |
| 72 *span = base::SaturatedSubtraction(max, min); | |
| 73 | |
| 74 int span_loss = base::SaturatedSubtraction(max, min + *span); | |
| 75 | |
| 76 // If the desired width is within the limits of ints, we can just | |
| 77 // use the simple computations to represent the range precisely. | |
| 78 if (span_loss == 0) { | |
| 79 *origin = min; | |
| 80 return; | |
| 81 } | |
| 82 | |
| 83 // Now we have to approximate. If one of min or max is close enough | |
| 84 // to zero we choose to make sure it is represented precisely. | |
| 85 // The other side is probably practically "infinite", so we move it. | |
| 86 if (base::SaturatedAbsolute(max) < std::numeric_limits<int>::max() / 2) { | |
| 87 *origin = max - *span; | |
| 88 } else if (base::SaturatedAbsolute(min) < | |
| 89 std::numeric_limits<int>::max() / 2) { | |
| 90 *origin = min; | |
| 91 } else { | |
| 92 // both are big, so keep the center. | |
| 93 *origin = min + span_loss / 2; | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 void Rect::SetByBounds(int left, int right, int top, int bottom) { | |
| 98 int x, y; | |
| 99 int width, height; | |
| 100 SaturatedClampRange(left, right, &x, &width); | |
| 101 SaturatedClampRange(top, bottom, &y, &height); | |
| 102 origin_.SetPoint(x, y); | |
| 103 size_.SetSize(width, height); | |
| 104 } | |
| 105 | |
| 63 void Rect::Inset(const Insets& insets) { | 106 void Rect::Inset(const Insets& insets) { |
| 64 Inset(insets.left(), insets.top(), insets.right(), insets.bottom()); | 107 Inset(insets.left(), insets.top(), insets.right(), insets.bottom()); |
| 65 } | 108 } |
| 66 | 109 |
| 67 void Rect::Inset(int left, int top, int right, int bottom) { | 110 void Rect::Inset(int left, int top, int right, int bottom) { |
| 68 origin_ += Vector2d(left, top); | 111 origin_ += Vector2d(left, top); |
| 69 // left+right might overflow/underflow, but width() - (left+right) might | 112 // left+right might overflow/underflow, but width() - (left+right) might |
| 70 // overflow as well. | 113 // overflow as well. |
| 71 set_width(base::SaturatedSubtraction(width(), | 114 set_width(base::SaturatedSubtraction(width(), |
| 72 base::SaturatedAddition(left, right))); | 115 base::SaturatedAddition(left, right))); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 rect.bottom() <= bottom()); | 164 rect.bottom() <= bottom()); |
| 122 } | 165 } |
| 123 | 166 |
| 124 bool Rect::Intersects(const Rect& rect) const { | 167 bool Rect::Intersects(const Rect& rect) const { |
| 125 return !(IsEmpty() || rect.IsEmpty() || rect.x() >= right() || | 168 return !(IsEmpty() || rect.IsEmpty() || rect.x() >= right() || |
| 126 rect.right() <= x() || rect.y() >= bottom() || rect.bottom() <= y()); | 169 rect.right() <= x() || rect.y() >= bottom() || rect.bottom() <= y()); |
| 127 } | 170 } |
| 128 | 171 |
| 129 void Rect::Intersect(const Rect& rect) { | 172 void Rect::Intersect(const Rect& rect) { |
| 130 if (IsEmpty() || rect.IsEmpty()) { | 173 if (IsEmpty() || rect.IsEmpty()) { |
| 131 SetRect(0, 0, 0, 0); | 174 SetRect(0, 0, 0, 0); // Throw away empty position. |
|
danakj
2017/03/28 20:40:34
nit: Throws
Peter Mayo
2017/03/29 18:49:25
Done.
| |
| 132 return; | 175 return; |
| 133 } | 176 } |
| 134 | 177 |
| 135 int rx = std::max(x(), rect.x()); | 178 int leftCoordinate = std::max(x(), rect.x()); |
|
danakj
2017/03/28 20:40:34
chromium style please. also just "left" "top" etc
Peter Mayo
2017/03/29 18:49:25
right and bottom are ambiguous with the this-> met
| |
| 136 int ry = std::max(y(), rect.y()); | 179 int topCoordinate = std::max(y(), rect.y()); |
| 137 int rr = std::min(right(), rect.right()); | 180 int rightCoordinate = std::min(right(), rect.right()); |
| 138 int rb = std::min(bottom(), rect.bottom()); | 181 int bottomCoordinate = std::min(bottom(), rect.bottom()); |
| 139 | 182 |
| 140 if (rx >= rr || ry >= rb) | 183 if (leftCoordinate >= rightCoordinate || topCoordinate >= bottomCoordinate) { |
| 141 rx = ry = rr = rb = 0; // non-intersecting | 184 SetRect(0, 0, 0, 0); // Throw away empty position. |
|
danakj
2017/03/28 20:40:34
nit: Throws
Peter Mayo
2017/03/29 18:49:25
Done.
| |
| 185 return; | |
| 186 } | |
| 142 | 187 |
| 143 SetRect(rx, ry, rr - rx, rb - ry); | 188 SetByBounds(leftCoordinate, rightCoordinate, topCoordinate, bottomCoordinate); |
| 144 } | 189 } |
| 145 | 190 |
| 146 void Rect::Union(const Rect& rect) { | 191 void Rect::Union(const Rect& rect) { |
| 147 if (IsEmpty()) { | 192 if (IsEmpty()) { |
| 148 *this = rect; | 193 *this = rect; |
| 149 return; | 194 return; |
| 150 } | 195 } |
| 151 if (rect.IsEmpty()) | 196 if (rect.IsEmpty()) |
| 152 return; | 197 return; |
| 153 | 198 |
| 154 int rx = std::min(x(), rect.x()); | 199 SetByBounds(std::min(x(), rect.x()), std::max(right(), rect.right()), |
| 155 int ry = std::min(y(), rect.y()); | 200 std::min(y(), rect.y()), std::max(bottom(), rect.bottom())); |
| 156 int rr = std::max(right(), rect.right()); | |
| 157 int rb = std::max(bottom(), rect.bottom()); | |
| 158 | |
| 159 // Subtracting to get width/height might overflow integers, so clamp them. | |
| 160 SetRect(rx, ry, base::SaturatedSubtraction(rr, rx), | |
| 161 base::SaturatedSubtraction(rb, ry)); | |
| 162 } | 201 } |
| 163 | 202 |
| 164 void Rect::Subtract(const Rect& rect) { | 203 void Rect::Subtract(const Rect& rect) { |
| 165 if (!Intersects(rect)) | 204 if (!Intersects(rect)) |
| 166 return; | 205 return; |
| 167 if (rect.Contains(*this)) { | 206 if (rect.Contains(*this)) { |
| 168 SetRect(0, 0, 0, 0); | 207 SetRect(0, 0, 0, 0); |
| 169 return; | 208 return; |
| 170 } | 209 } |
| 171 | 210 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 182 rr = rect.x(); | 221 rr = rect.x(); |
| 183 } | 222 } |
| 184 } else if (rect.x() <= x() && rect.right() >= right()) { | 223 } else if (rect.x() <= x() && rect.right() >= right()) { |
| 185 // complete intersection in the x-direction | 224 // complete intersection in the x-direction |
| 186 if (rect.y() <= y()) { | 225 if (rect.y() <= y()) { |
| 187 ry = rect.bottom(); | 226 ry = rect.bottom(); |
| 188 } else if (rect.bottom() >= bottom()) { | 227 } else if (rect.bottom() >= bottom()) { |
| 189 rb = rect.y(); | 228 rb = rect.y(); |
| 190 } | 229 } |
| 191 } | 230 } |
| 192 SetRect(rx, ry, rr - rx, rb - ry); | 231 SetByBounds(rx, rr, ry, rb); |
| 193 } | 232 } |
| 194 | 233 |
| 195 void Rect::AdjustToFit(const Rect& rect) { | 234 void Rect::AdjustToFit(const Rect& rect) { |
| 196 int new_x = x(); | 235 int new_x = x(); |
| 197 int new_y = y(); | 236 int new_y = y(); |
| 198 int new_width = width(); | 237 int new_width = width(); |
| 199 int new_height = height(); | 238 int new_height = height(); |
| 200 AdjustAlongAxis(rect.x(), rect.width(), &new_x, &new_width); | 239 AdjustAlongAxis(rect.x(), rect.width(), &new_x, &new_width); |
| 201 AdjustAlongAxis(rect.y(), rect.height(), &new_y, &new_height); | 240 AdjustAlongAxis(rect.y(), rect.height(), &new_y, &new_height); |
| 202 SetRect(new_x, new_y, new_width, new_height); | 241 SetRect(new_x, new_y, new_width, new_height); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 return result; | 324 return result; |
| 286 } | 325 } |
| 287 | 326 |
| 288 Rect SubtractRects(const Rect& a, const Rect& b) { | 327 Rect SubtractRects(const Rect& a, const Rect& b) { |
| 289 Rect result = a; | 328 Rect result = a; |
| 290 result.Subtract(b); | 329 result.Subtract(b); |
| 291 return result; | 330 return result; |
| 292 } | 331 } |
| 293 | 332 |
| 294 Rect BoundingRect(const Point& p1, const Point& p2) { | 333 Rect BoundingRect(const Point& p1, const Point& p2) { |
| 295 int rx = std::min(p1.x(), p2.x()); | 334 Rect result; |
| 296 int ry = std::min(p1.y(), p2.y()); | 335 result.SetByBounds(std::min(p1.x(), p2.x()), std::max(p1.x(), p2.x()), |
| 297 int rr = std::max(p1.x(), p2.x()); | 336 std::min(p1.y(), p2.y()), std::max(p1.y(), p2.y())); |
| 298 int rb = std::max(p1.y(), p2.y()); | 337 return result; |
| 299 return Rect(rx, ry, rr - rx, rb - ry); | |
| 300 } | 338 } |
| 301 | 339 |
| 302 } // namespace gfx | 340 } // namespace gfx |
| OLD | NEW |