Flutter Engine
rect.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter 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 #pragma once
6 
7 #include <array>
8 #include <optional>
9 #include <ostream>
10 #include <vector>
11 
15 #include "impeller/geometry/size.h"
16 
17 namespace impeller {
18 
19 template <class T>
20 struct TRect {
21  using Type = T;
22 
25 
26  constexpr TRect() : origin({0, 0}), size({0, 0}) {}
27 
28  constexpr TRect(TSize<Type> size) : origin({0.0, 0.0}), size(size) {}
29 
30  constexpr TRect(TPoint<Type> origin, TSize<Type> size)
31  : origin(origin), size(size) {}
32 
33  constexpr TRect(const Type components[4])
34  : origin(components[0], components[1]),
35  size(components[2], components[3]) {}
36 
37  constexpr TRect(Type x, Type y, Type width, Type height)
38  : origin(x, y), size(width, height) {}
39 
40  constexpr static TRect MakeLTRB(Type left,
41  Type top,
42  Type right,
43  Type bottom) {
44  return TRect(left, top, right - left, bottom - top);
45  }
46 
47  constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height) {
48  return TRect(x, y, width, height);
49  }
50 
51  constexpr static TRect MakeSize(const TSize<Type>& size) {
52  return TRect(0.0, 0.0, size.width, size.height);
53  }
54 
55  constexpr static std::optional<TRect> MakePointBounds(
56  const std::vector<TPoint<Type>>& points) {
57  if (points.empty()) {
58  return std::nullopt;
59  }
60  auto left = points[0].x;
61  auto top = points[0].y;
62  auto right = points[0].x;
63  auto bottom = points[0].y;
64  if (points.size() > 1) {
65  for (size_t i = 1; i < points.size(); i++) {
66  left = std::min(left, points[i].x);
67  top = std::min(top, points[i].y);
68  right = std::max(right, points[i].x);
69  bottom = std::max(bottom, points[i].y);
70  }
71  }
72  return TRect::MakeLTRB(left, top, right, bottom);
73  }
74 
75  template <class U>
76  constexpr explicit TRect(const TRect<U>& other)
77  : origin(static_cast<TPoint<Type>>(other.origin)),
78  size(static_cast<TSize<Type>>(other.size)) {}
79 
80  constexpr TRect operator+(const TRect& r) const {
81  return TRect({origin.x + r.origin.x, origin.y + r.origin.y},
82  {size.width + r.size.width, size.height + r.size.height});
83  }
84 
85  constexpr TRect operator-(const TRect& r) const {
86  return TRect({origin.x - r.origin.x, origin.y - r.origin.y},
87  {size.width - r.size.width, size.height - r.size.height});
88  }
89 
90  constexpr TRect operator*(Type scale) const {
91  return TRect({origin.x * scale, origin.y * scale},
92  {size.width * scale, size.height * scale});
93  }
94 
95  constexpr TRect operator*(const TRect& r) const {
96  return TRect({origin.x * r.origin.x, origin.y * r.origin.y},
97  {size.width * r.size.width, size.height * r.size.height});
98  }
99 
100  constexpr bool operator==(const TRect& r) const {
101  return origin == r.origin && size == r.size;
102  }
103 
104  constexpr bool Contains(const TPoint<Type>& p) const {
105  return p.x >= origin.x && p.x < origin.x + size.width && p.y >= origin.y &&
106  p.y < origin.y + size.height;
107  }
108 
109  constexpr bool Contains(const TRect& o) const {
110  return Union(o).size == size;
111  }
112 
113  constexpr bool IsZero() const { return size.IsZero(); }
114 
115  constexpr bool IsEmpty() const { return size.IsEmpty(); }
116 
117  constexpr auto GetLeft() const {
118  return std::min(origin.x, origin.x + size.width);
119  }
120 
121  constexpr auto GetTop() const {
122  return std::min(origin.y, origin.y + size.height);
123  }
124 
125  constexpr auto GetRight() const {
126  return std::max(origin.x, origin.x + size.width);
127  }
128 
129  constexpr auto GetBottom() const {
130  return std::max(origin.y, origin.y + size.height);
131  }
132 
133  constexpr std::array<T, 4> GetLTRB() const {
134  const auto left = std::min(origin.x, origin.x + size.width);
135  const auto top = std::min(origin.y, origin.y + size.height);
136  const auto right = std::max(origin.x, origin.x + size.width);
137  const auto bottom = std::max(origin.y, origin.y + size.height);
138  return {left, top, right, bottom};
139  }
140 
141  constexpr std::array<TPoint<T>, 4> GetPoints() const {
142  auto [left, top, right, bottom] = GetLTRB();
143  return {TPoint(left, top), TPoint(right, top), TPoint(left, bottom),
144  TPoint(right, bottom)};
145  }
146 
147  constexpr std::array<TPoint<T>, 4> GetTransformedPoints(
148  const Matrix& transform) const {
149  auto points = GetPoints();
150  for (size_t i = 0; i < points.size(); i++) {
151  points[i] = transform * points[i];
152  }
153  return points;
154  }
155 
156  /// @brief Creates a new bounding box that contains this transformed
157  /// rectangle.
158  constexpr TRect TransformBounds(const Matrix& transform) const {
159  auto points = GetTransformedPoints(transform);
160  return TRect::MakePointBounds({points.begin(), points.end()}).value();
161  }
162 
163  constexpr TRect Union(const TRect& o) const {
164  auto this_ltrb = GetLTRB();
165  auto other_ltrb = o.GetLTRB();
166  return TRect::MakeLTRB(std::min(this_ltrb[0], other_ltrb[0]), //
167  std::min(this_ltrb[1], other_ltrb[1]), //
168  std::max(this_ltrb[2], other_ltrb[2]), //
169  std::max(this_ltrb[3], other_ltrb[3]) //
170  );
171  }
172 
173  constexpr std::optional<TRect<T>> Intersection(const TRect& o) const {
174  auto this_ltrb = GetLTRB();
175  auto other_ltrb = o.GetLTRB();
176  auto intersection =
177  TRect::MakeLTRB(std::max(this_ltrb[0], other_ltrb[0]), //
178  std::max(this_ltrb[1], other_ltrb[1]), //
179  std::min(this_ltrb[2], other_ltrb[2]), //
180  std::min(this_ltrb[3], other_ltrb[3]) //
181  );
182  if (intersection.size.IsEmpty()) {
183  return std::nullopt;
184  }
185  return intersection;
186  }
187 
188  constexpr bool IntersectsWithRect(const TRect& o) const {
189  return Interesection(o).has_value();
190  }
191 };
192 
195 
196 } // namespace impeller
197 
198 namespace std {
199 
200 template <class T>
201 inline std::ostream& operator<<(std::ostream& out,
202  const impeller::TRect<T>& r) {
203  out << "(" << r.origin << ", " << r.size << ")";
204  return out;
205 }
206 
207 } // namespace std
TPoint< Type > origin
Definition: rect.h:23
constexpr TRect(TSize< Type > size)
Definition: rect.h:28
constexpr TRect operator+(const TRect &r) const
Definition: rect.h:80
constexpr bool IsEmpty() const
Definition: rect.h:115
constexpr bool Contains(const TRect &o) const
Definition: rect.h:109
constexpr TRect operator*(Type scale) const
Definition: rect.h:90
static constexpr std::optional< TRect > MakePointBounds(const std::vector< TPoint< Type >> &points)
Definition: rect.h:55
Type width
Definition: size.h:21
Type height
Definition: size.h:22
constexpr TRect operator-(const TRect &r) const
Definition: rect.h:85
constexpr auto GetRight() const
Definition: rect.h:125
constexpr bool Contains(const TPoint< Type > &p) const
Definition: rect.h:104
Definition: ref_ptr.h:255
constexpr TRect operator*(const TRect &r) const
Definition: rect.h:95
constexpr TRect(const Type components[4])
Definition: rect.h:33
constexpr TRect(const TRect< U > &other)
Definition: rect.h:76
constexpr auto GetTop() const
Definition: rect.h:121
constexpr bool IsZero() const
Definition: size.h:91
constexpr std::array< T, 4 > GetLTRB() const
Definition: rect.h:133
constexpr bool IsEmpty() const
Definition: size.h:93
constexpr bool operator==(const TRect &r) const
Definition: rect.h:100
constexpr bool IsZero() const
Definition: rect.h:113
std::ostream & operator<<(std::ostream &out, const impeller::TRect< T > &r)
Definition: rect.h:201
constexpr bool IntersectsWithRect(const TRect &o) const
Definition: rect.h:188
TSize< Type > size
Definition: rect.h:24
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition: rect.h:47
uint8_t value
constexpr auto GetBottom() const
Definition: rect.h:129
static constexpr TRect MakeSize(const TSize< Type > &size)
Definition: rect.h:51
constexpr TRect()
Definition: rect.h:26
A 4x4 matrix using column-major storage.
Definition: matrix.h:34
constexpr TRect Union(const TRect &o) const
Definition: rect.h:163
int32_t width
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:158
int32_t height
constexpr auto GetLeft() const
Definition: rect.h:117
constexpr std::optional< TRect< T > > Intersection(const TRect &o) const
Definition: rect.h:173
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:40
constexpr TRect(Type x, Type y, Type width, Type height)
Definition: rect.h:37
constexpr std::array< TPoint< T >, 4 > GetTransformedPoints(const Matrix &transform) const
Definition: rect.h:147
constexpr TRect(TPoint< Type > origin, TSize< Type > size)
Definition: rect.h:30
constexpr std::array< TPoint< T >, 4 > GetPoints() const
Definition: rect.h:141