Flutter Engine
The Flutter Engine
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;
103 SaturatedClampRange(left, right, &x, &width);
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
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
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
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
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 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
Definition: rect.h:36
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
Definition: size.h:26
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
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
constexpr std::make_unsigned< T >::type SafeUnsignedAbs(T value)
std::string StringPrintf(const std::string &format, Args... args)
Definition: string_utils.h:18
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
TRect< Scalar > Rect
Definition: rect.h:769
TPoint< Scalar > Point
Definition: point.h:322
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
SeparatedVector2 offset
#define BASE_DCHECK(condition)
Definition: logging.h:63