Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
rect.cc
Go to the documentation of this file.
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
3// found in the LICENSE file.
4
5#include "rect.h"
6
7#include <algorithm>
8
9#if defined(OS_WIN)
10#include <windows.h>
11#elif defined(OS_IOS)
12#include <CoreGraphics/CoreGraphics.h>
13#elif defined(OS_APPLE)
14#include <ApplicationServices/ApplicationServices.h>
15#endif
16
18#include "base/logging.h"
20#include "base/string_utils.h"
21#include "insets.h"
22
23namespace gfx {
24
25#if defined(OS_WIN)
26Rect::Rect(const RECT& r)
27 : origin_(r.left, r.top),
28 size_(std::abs(r.right - r.left), std::abs(r.bottom - r.top)) {}
29#elif defined(OS_APPLE)
30Rect::Rect(const CGRect& r)
31 : origin_(r.origin.x, r.origin.y), size_(r.size.width, r.size.height) {}
32#endif
33
34#if defined(OS_WIN)
35RECT Rect::ToRECT() const {
36 RECT r;
37 r.left = x();
38 r.right = right();
39 r.top = y();
40 r.bottom = bottom();
41 return r;
42}
43#elif defined(OS_APPLE)
44CGRect Rect::ToCGRect() const {
45 return CGRectMake(x(), y(), width(), height());
46}
47#endif
48
49void AdjustAlongAxis(int dst_origin, int dst_size, int* origin, int* size) {
50 *size = std::min(dst_size, *size);
51 if (*origin < dst_origin)
52 *origin = dst_origin;
53 else
54 *origin = std::min(dst_origin + dst_size, *origin + *size) - *size;
55}
56
57} // namespace gfx
58
59namespace gfx {
60
61// This is the per-axis heuristic for picking the most useful origin and
62// width/height to represent the input range.
63static void SaturatedClampRange(int min, int max, int* origin, int* span) {
64 if (max < min) {
65 *span = 0;
66 *origin = min;
67 return;
68 }
69
70 int effective_span = base::ClampSub(max, min);
71 int span_loss = base::ClampSub(max, min + effective_span);
72
73 // If the desired width is within the limits of ints, we can just
74 // use the simple computations to represent the range precisely.
75 if (span_loss == 0) {
76 *span = effective_span;
77 *origin = min;
78 return;
79 }
80
81 // Now we have to approximate. If one of min or max is close enough
82 // to zero we choose to represent that one precisely. The other side is
83 // probably practically "infinite", so we move it.
84 constexpr unsigned kMaxDimension = std::numeric_limits<int>::max() / 2;
85 if (base::SafeUnsignedAbs(max) < kMaxDimension) {
86 // Maintain origin + span == max.
87 *span = effective_span;
88 *origin = max - effective_span;
89 } else if (base::SafeUnsignedAbs(min) < kMaxDimension) {
90 // Maintain origin == min.
91 *span = effective_span;
92 *origin = min;
93 } else {
94 // Both are big, so keep the center.
95 *span = effective_span;
96 *origin = min + span_loss / 2;
97 }
98}
99
100void Rect::SetByBounds(int left, int top, int right, int bottom) {
101 int x, y;
102 int width, height;
105 origin_.SetPoint(x, y);
106 size_.SetSize(width, height);
107}
108
109void Rect::Inset(const Insets& insets) {
110 Inset(insets.left(), insets.top(), insets.right(), insets.bottom());
111}
112
113void Rect::Inset(int left, int top, int right, int bottom) {
114 origin_ += Vector2d(left, top);
115 // left+right might overflow/underflow, but width() - (left+right) might
116 // overflow as well.
117 set_width(base::ClampSub(width(), base::ClampAdd(left, right)));
118 set_height(base::ClampSub(height(), base::ClampAdd(top, bottom)));
119}
120
121void Rect::Offset(int horizontal, int vertical) {
122 origin_ += Vector2d(horizontal, vertical);
123 // Ensure that width and height remain valid.
124 set_width(width());
126}
127
129 origin_ += offset;
130 // Ensure that width and height remain valid.
131 set_width(width());
133}
134
136 origin_ -= offset;
137}
138
139Insets Rect::InsetsFrom(const Rect& inner) const {
140 return Insets(inner.y() - y(), inner.x() - x(), bottom() - inner.bottom(),
141 right() - inner.right());
142}
143
144bool Rect::operator<(const Rect& other) const {
145 if (origin_ == other.origin_) {
146 if (width() == other.width()) {
147 return height() < other.height();
148 } else {
149 return width() < other.width();
150 }
151 } else {
152 return origin_ < other.origin_;
153 }
154}
155
156bool Rect::Contains(int point_x, int point_y) const {
157 return (point_x >= x()) && (point_x < right()) && (point_y >= y()) &&
158 (point_y < bottom());
159}
160
161bool Rect::Contains(const Rect& rect) const {
162 return (rect.x() >= x() && rect.right() <= right() && rect.y() >= y() &&
163 rect.bottom() <= bottom());
164}
165
166bool Rect::Intersects(const Rect& rect) const {
167 return !(IsEmpty() || rect.IsEmpty() || rect.x() >= right() ||
168 rect.right() <= x() || rect.y() >= bottom() || rect.bottom() <= y());
169}
170
171void Rect::Intersect(const Rect& rect) {
172 if (IsEmpty() || rect.IsEmpty()) {
173 SetRect(0, 0, 0, 0); // Throws away empty position.
174 return;
175 }
176
177 int left = std::max(x(), rect.x());
178 int top = std::max(y(), rect.y());
179 int new_right = std::min(right(), rect.right());
180 int new_bottom = std::min(bottom(), rect.bottom());
181
182 if (left >= new_right || top >= new_bottom) {
183 SetRect(0, 0, 0, 0); // Throws away empty position.
184 return;
185 }
186
187 SetByBounds(left, top, new_right, new_bottom);
188}
189
190void Rect::Union(const Rect& rect) {
191 if (IsEmpty()) {
192 *this = rect;
193 return;
194 }
195 if (rect.IsEmpty())
196 return;
197
198 SetByBounds(std::min(x(), rect.x()), std::min(y(), rect.y()),
199 std::max(right(), rect.right()),
200 std::max(bottom(), rect.bottom()));
201}
202
203void Rect::Subtract(const Rect& rect) {
204 if (!Intersects(rect))
205 return;
206 if (rect.Contains(*this)) {
207 SetRect(0, 0, 0, 0);
208 return;
209 }
210
211 int rx = x();
212 int ry = y();
213 int rr = right();
214 int rb = bottom();
215
216 if (rect.y() <= y() && rect.bottom() >= bottom()) {
217 // complete intersection in the y-direction
218 if (rect.x() <= x()) {
219 rx = rect.right();
220 } else if (rect.right() >= right()) {
221 rr = rect.x();
222 }
223 } else if (rect.x() <= x() && rect.right() >= right()) {
224 // complete intersection in the x-direction
225 if (rect.y() <= y()) {
226 ry = rect.bottom();
227 } else if (rect.bottom() >= bottom()) {
228 rb = rect.y();
229 }
230 }
231 SetByBounds(rx, ry, rr, rb);
232}
233
234void Rect::AdjustToFit(const Rect& rect) {
235 int new_x = x();
236 int new_y = y();
237 int new_width = width();
238 int new_height = height();
239 AdjustAlongAxis(rect.x(), rect.width(), &new_x, &new_width);
240 AdjustAlongAxis(rect.y(), rect.height(), &new_y, &new_height);
241 SetRect(new_x, new_y, new_width, new_height);
242}
243
245 return Point(x() + width() / 2, y() + height() / 2);
246}
247
249 int new_width = std::min(width(), size.width());
250 int new_height = std::min(height(), size.height());
251 int new_x = x() + (width() - new_width) / 2;
252 int new_y = y() + (height() - new_height) / 2;
253 SetRect(new_x, new_y, new_width, new_height);
254}
255
257 SetRect(y(), x(), height(), width());
258}
259
260void Rect::SplitVertically(Rect* left_half, Rect* right_half) const {
261 BASE_DCHECK(left_half);
262 BASE_DCHECK(right_half);
263
264 left_half->SetRect(x(), y(), width() / 2, height());
265 right_half->SetRect(left_half->right(), y(), width() - left_half->width(),
266 height());
267}
268
269bool Rect::SharesEdgeWith(const Rect& rect) const {
270 return (y() == rect.y() && height() == rect.height() &&
271 (x() == rect.right() || right() == rect.x())) ||
272 (x() == rect.x() && width() == rect.width() &&
273 (y() == rect.bottom() || bottom() == rect.y()));
274}
275
276int Rect::ManhattanDistanceToPoint(const Point& point) const {
277 int x_distance =
278 std::max<int>(0, std::max(x() - point.x(), point.x() - right()));
279 int y_distance =
280 std::max<int>(0, std::max(y() - point.y(), point.y() - bottom()));
281
282 return x_distance + y_distance;
283}
284
285int Rect::ManhattanInternalDistance(const Rect& rect) const {
286 Rect c(*this);
287 c.Union(rect);
288
289 int x = std::max(0, c.width() - width() - rect.width() + 1);
290 int y = std::max(0, c.height() - height() - rect.height() + 1);
291 return x + y;
292}
293
294std::string Rect::ToString() const {
295 return base::StringPrintf("%s %s", origin().ToString().c_str(),
296 size().ToString().c_str());
297}
298
299bool Rect::ApproximatelyEqual(const Rect& rect, int tolerance) const {
300 return std::abs(x() - rect.x()) <= tolerance &&
301 std::abs(y() - rect.y()) <= tolerance &&
302 std::abs(right() - rect.right()) <= tolerance &&
303 std::abs(bottom() - rect.bottom()) <= tolerance;
304}
305
306Rect operator+(const Rect& lhs, const Vector2d& rhs) {
307 Rect result(lhs);
308 result += rhs;
309 return result;
310}
311
312Rect operator-(const Rect& lhs, const Vector2d& rhs) {
313 Rect result(lhs);
314 result -= rhs;
315 return result;
316}
317
318Rect IntersectRects(const Rect& a, const Rect& b) {
319 Rect result = a;
320 result.Intersect(b);
321 return result;
322}
323
324Rect UnionRects(const Rect& a, const Rect& b) {
325 Rect result = a;
326 result.Union(b);
327 return result;
328}
329
330Rect SubtractRects(const Rect& a, const Rect& b) {
331 Rect result = a;
332 result.Subtract(b);
333 return result;
334}
335
336Rect BoundingRect(const Point& p1, const Point& p2) {
337 Rect result;
338 result.SetByBounds(std::min(p1.x(), p2.x()), std::min(p1.y(), p2.y()),
339 std::max(p1.x(), p2.x()), std::max(p1.y(), p2.y()));
340 return result;
341}
342
343} // namespace gfx
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
constexpr int right() const
Definition insets.h:48
constexpr int bottom() const
Definition insets.h:47
constexpr int top() const
Definition insets.h:45
constexpr int left() const
Definition insets.h:46
constexpr int y() const
Definition point.h:49
void SetPoint(int x, int y)
Definition point.h:53
constexpr int x() const
Definition point.h:48
bool Intersects(const Rect &rect) const
Definition rect.cc:166
bool ApproximatelyEqual(const Rect &rect, int tolerance) const
Definition rect.cc:299
constexpr int height() const
Definition rect.h:79
int ManhattanDistanceToPoint(const Point &point) const
Definition rect.cc:276
Insets InsetsFrom(const Rect &inner) const
Definition rect.cc:139
Point CenterPoint() const
Definition rect.cc:244
void operator+=(const Vector2d &offset)
Definition rect.cc:128
void set_width(int width)
Definition rect.h:77
void Offset(int horizontal, int vertical)
Definition rect.cc:121
void SetByBounds(int left, int top, int right, int bottom)
Definition rect.cc:100
void Intersect(const Rect &rect)
Definition rect.cc:171
bool operator<(const Rect &other) const
Definition rect.cc:144
void AdjustToFit(const Rect &rect)
Definition rect.cc:234
constexpr int right() const
Definition rect.h:96
constexpr const Point & origin() const
Definition rect.h:82
constexpr int bottom() const
Definition rect.h:97
bool SharesEdgeWith(const Rect &rect) const
Definition rect.cc:269
void Subtract(const Rect &rect)
Definition rect.cc:203
void set_height(int height)
Definition rect.h:80
std::string ToString() const
Definition rect.cc:294
constexpr int y() const
Definition rect.h:69
constexpr const Size & size() const
Definition rect.h:90
void operator-=(const Vector2d &offset)
Definition rect.cc:135
void Transpose()
Definition rect.cc:256
void Inset(int horizontal, int vertical)
Definition rect.h:123
void SetRect(int x, int y, int width, int height)
Definition rect.h:110
bool Contains(int point_x, int point_y) const
Definition rect.cc:156
int ManhattanInternalDistance(const Rect &rect) const
Definition rect.cc:285
void Union(const Rect &rect)
Definition rect.cc:190
void ClampToCenteredSize(const Size &size)
Definition rect.cc:248
void SplitVertically(Rect *left_half, Rect *right_half) const
Definition rect.cc:260
bool IsEmpty() const
Definition rect.h:140
constexpr int x() const
Definition rect.h:62
constexpr Rect()=default
constexpr int width() const
Definition rect.h:76
constexpr int height() const
Definition size.h:50
void SetSize(int width, int height)
Definition size.h:60
constexpr int width() const
Definition size.h:49
static bool b
struct MyStruct a[10]
GAsyncResult * result
static float max(float r, float g, float b)
Definition hsl.cpp:49
static float min(float r, float g, float b)
Definition hsl.cpp:48
double y
double x
std::string StringPrintf(const std::string &format, Args... args)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259
Definition insets.cc:10
Rect BoundingRect(const Point &p1, const Point &p2)
Definition rect.cc:336
void AdjustAlongAxis(int dst_origin, int dst_size, int *origin, int *size)
Definition rect.cc:49
Rect IntersectRects(const Rect &a, const Rect &b)
Definition rect.cc:318
Insets operator+(Insets lhs, const Insets &rhs)
Definition insets.h:175
Rect UnionRects(const Rect &a, const Rect &b)
Definition rect.cc:324
Rect SubtractRects(const Rect &a, const Rect &b)
Definition rect.cc:330
static void SaturatedClampRange(int min, int max, int *origin, int *span)
Definition rect.cc:63
Insets operator-(Insets lhs, const Insets &rhs)
Definition insets.h:180
constexpr size_t size(const T(&array)[N]) noexcept
SIN Vec< N, float > abs(const Vec< N, float > &x)
Definition SkVx.h:707
Definition ref_ptr.h:256
int32_t height
int32_t width
Point offset
#define BASE_DCHECK(condition)
Definition logging.h:63