| Flutter Impeller |

round_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 #ifndef FLUTTER_IMPELLER_GEOMETRY_ROUND_RECT_H_
6 #define FLUTTER_IMPELLER_GEOMETRY_ROUND_RECT_H_
7
8 #include "flutter/impeller/geometry/path_source.h"
9 #include "flutter/impeller/geometry/point.h"
10 #include "flutter/impeller/geometry/rect.h"
11 #include "flutter/impeller/geometry/rounding_radii.h"
12 #include "flutter/impeller/geometry/size.h"
13
14 namespace impeller {
15
16 struct RoundRect {
17 RoundRect() = default;
18
19 inline static RoundRect MakeRect(const Rect& rect) {
20 return MakeRectRadii(rect, RoundingRadii());
21 }
22
23 inline static RoundRect MakeOval(const Rect& rect) {
24 return MakeRectRadii(rect, RoundingRadii::MakeRadii(rect.GetSize() * 0.5f));
25 }
26
27 inline static RoundRect MakeRectRadius(const Rect& rect, Scalar radius) {
28 return MakeRectRadii(rect, RoundingRadii::MakeRadius(radius));
29 }
30
31 inline static RoundRect MakeRectXY(const Rect& rect,
32 Scalar x_radius,
33 Scalar y_radius) {
34 return MakeRectRadii(rect,
35 RoundingRadii::MakeRadii(Size(x_radius, y_radius)));
36 }
37
38 inline static RoundRect MakeRectXY(const Rect& rect, Size corner_radii) {
39 return MakeRectRadii(rect, RoundingRadii::MakeRadii(corner_radii));
40 }
41
42 inline static RoundRect MakeNinePatch(const Rect& rect,
43 Scalar left,
44 Scalar top,
45 Scalar right,
46 Scalar bottom) {
47 return MakeRectRadii(
48 rect, RoundingRadii::MakeNinePatch(left, top, right, bottom));
49 }
50
51 static RoundRect MakeRectRadii(const Rect& rect, const RoundingRadii& radii);
52
53 constexpr const Rect& GetBounds() const { return bounds_; }
54
55 constexpr const RoundingRadii& GetRadii() const { return radii_; }
56
57 [[nodiscard]] constexpr bool IsFinite() const {
58 return bounds_.IsFinite() && //
59 radii_.top_left.IsFinite() && //
60 radii_.top_right.IsFinite() && //
61 radii_.bottom_left.IsFinite() && //
62 radii_.bottom_right.IsFinite();
63 }
64
65 [[nodiscard]] constexpr bool IsEmpty() const { return bounds_.IsEmpty(); }
66
67 [[nodiscard]] constexpr bool IsRect() const {
68 return !bounds_.IsEmpty() && radii_.AreAllCornersEmpty();
69 }
70
71 [[nodiscard]] constexpr bool IsOval() const {
72 return !bounds_.IsEmpty() && radii_.AreAllCornersSame() &&
73 ScalarNearlyEqual(radii_.top_left.width,
74 bounds_.GetWidth() * 0.5f) &&
75 ScalarNearlyEqual(radii_.top_left.height,
76 bounds_.GetHeight() * 0.5f);
77 }
78
79 /// @brief Returns true iff the provided point |p| is inside the
80 /// half-open interior of this rectangle.
81 ///
82 /// For purposes of containment, a rectangle contains points
83 /// along the top and left edges but not points along the
84 /// right and bottom edges so that a point is only ever
85 /// considered inside one of two abutting rectangles.
86 [[nodiscard]] bool Contains(const Point& p) const;
87
88 /// @brief Returns a new round rectangle translated by the given offset.
89 [[nodiscard]] inline RoundRect Shift(Scalar dx, Scalar dy) const {
90 // Just in case, use the factory rather than the internal constructor
91 // as shifting the rectangle may increase/decrease its bit precision
92 // so we should re-validate the radii to the newly located rectangle.
93 return MakeRectRadii(bounds_.Shift(dx, dy), radii_);
94 }
95
96 /// @brief Returns a round rectangle with expanded edges. Negative expansion
97 /// results in shrinking.
98 [[nodiscard]] inline RoundRect Expand(Scalar left,
99 Scalar top,
100 Scalar right,
101 Scalar bottom) const {
102 // Use the factory rather than the internal constructor as the changing
103 // size of the rectangle requires that we re-validate the radii to the
104 // newly sized rectangle.
105 return MakeRectRadii(bounds_.Expand(left, top, right, bottom), radii_);
106 }
107
108 /// @brief Returns a round rectangle with expanded edges. Negative expansion
109 /// results in shrinking.
110 [[nodiscard]] inline RoundRect Expand(Scalar horizontal,
111 Scalar vertical) const {
112 // Use the factory rather than the internal constructor as the changing
113 // size of the rectangle requires that we re-validate the radii to the
114 // newly sized rectangle.
115 return MakeRectRadii(bounds_.Expand(horizontal, vertical), radii_);
116 }
117
118 /// @brief Returns a round rectangle with expanded edges. Negative expansion
119 /// results in shrinking.
120 [[nodiscard]] inline RoundRect Expand(Scalar amount) const {
121 // Use the factory rather than the internal constructor as the changing
122 // size of the rectangle requires that we re-validate the radii to the
123 // newly sized rectangle.
124 return MakeRectRadii(bounds_.Expand(amount), radii_);
125 }
126
127 [[nodiscard]] constexpr bool operator==(const RoundRect& rr) const {
128 return bounds_ == rr.bounds_ && radii_ == rr.radii_;
129 }
130
131 private:
132 constexpr RoundRect(const Rect& bounds, const RoundingRadii& radii)
133 : bounds_(bounds), radii_(radii) {}
134
135 Rect bounds_;
136 RoundingRadii radii_;
137
138 // Helps with RoundRectPathSource and DiffRoundRectPathSource
139 void Dispatch(PathReceiver& receiver) const;
140
141 friend class RoundRectPathSource;
142 friend class DiffRoundRectPathSource;
143 };
144
145 class RoundRectPathSource : public PathSource {
146 public:
147 explicit RoundRectPathSource(const RoundRect& round_rect);
148
149 ~RoundRectPathSource();
150
151 const RoundRect& GetRoundRect() const { return round_rect_; }
152
153 // |PathSource|
154 FillType GetFillType() const override;
155
156 // |PathSource|
157 Rect GetBounds() const override;
158
159 // |PathSource|
160 bool IsConvex() const override;
161
162 // |PathSource|
163 void Dispatch(PathReceiver& receiver) const override;
164
165 private:
166 const RoundRect round_rect_;
167 };
168
169 class DiffRoundRectPathSource : public PathSource {
170 public:
171 explicit DiffRoundRectPathSource(const RoundRect& outer,
172 const RoundRect& inner);
173
174 ~DiffRoundRectPathSource();
175
176 const RoundRect& GetOuter() const { return outer_; }
177 const RoundRect& GetInner() const { return inner_; }
178
179 // |PathSource|
180 FillType GetFillType() const override;
181
182 // |PathSource|
183 Rect GetBounds() const override;
184
185 // |PathSource|
186 bool IsConvex() const override;
187
188 // |PathSource|
189 void Dispatch(PathReceiver& receiver) const override;
190
191 private:
192 const RoundRect outer_;
193 const RoundRect inner_;
194 };
195
196 } // namespace impeller
197
198 namespace std {
199
200 inline std::ostream& operator<<(std::ostream& out,
201 const impeller::RoundRect& rr) {
202 out << "(" //
203 << "rect: " << rr.GetBounds() << ", " //
204 << "radii: " << rr.GetRadii() //
205 << ")";
206 return out;
207 }
208
209 } // namespace std
210
211 #endif // FLUTTER_IMPELLER_GEOMETRY_ROUND_RECT_H_
impeller::DiffRoundRectPathSource
Definition: round_rect.h:169
impeller::DiffRoundRectPathSource::GetInner
const RoundRect & GetInner() const
Definition: round_rect.h:177
impeller::DiffRoundRectPathSource::DiffRoundRectPathSource
DiffRoundRectPathSource(const RoundRect &outer, const RoundRect &inner)
Definition: round_rect.cc:145
impeller::DiffRoundRectPathSource::~DiffRoundRectPathSource
~DiffRoundRectPathSource()
impeller::DiffRoundRectPathSource::GetBounds
Rect GetBounds() const override
Definition: round_rect.cc:155
impeller::DiffRoundRectPathSource::IsConvex
bool IsConvex() const override
Definition: round_rect.cc:159
impeller::DiffRoundRectPathSource::Dispatch
void Dispatch(PathReceiver &receiver) const override
Definition: round_rect.cc:163
impeller::DiffRoundRectPathSource::GetFillType
FillType GetFillType() const override
Definition: round_rect.cc:151
impeller::DiffRoundRectPathSource::GetOuter
const RoundRect & GetOuter() const
Definition: round_rect.h:176
impeller::PathReceiver
Collection of functions to receive path segments from the underlying path representation via the DlPa...
Definition: path_source.h:42
impeller::PathSource
Definition: path_source.h:55
impeller::RoundRectPathSource
Definition: round_rect.h:145
impeller::RoundRectPathSource::~RoundRectPathSource
~RoundRectPathSource()
impeller::RoundRectPathSource::RoundRectPathSource
RoundRectPathSource(const RoundRect &round_rect)
Definition: round_rect.cc:124
impeller::RoundRectPathSource::GetBounds
Rect GetBounds() const override
Definition: round_rect.cc:133
impeller::RoundRectPathSource::IsConvex
bool IsConvex() const override
Definition: round_rect.cc:137
impeller::RoundRectPathSource::Dispatch
void Dispatch(PathReceiver &receiver) const override
Definition: round_rect.cc:141
impeller::RoundRectPathSource::GetRoundRect
const RoundRect & GetRoundRect() const
Definition: round_rect.h:151
impeller::RoundRectPathSource::GetFillType
FillType GetFillType() const override
Definition: round_rect.cc:129
impeller
Definition: allocation.cc:12
impeller::Scalar
float Scalar
Definition: scalar.h:19
impeller::FillType
FillType
Definition: path_source.h:13
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:788
impeller::Size
TSize< Scalar > Size
Definition: size.h:159
impeller::ScalarNearlyEqual
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
Definition: scalar.h:36
std
Definition: comparable.h:95
std::operator<<
std::ostream & operator<<(std::ostream &out, const impeller::Arc &a)
Definition: arc.h:141
path_source.h
point.h
rect.h
rounding_radii.h
size.h
impeller::RoundRect
Definition: round_rect.h:16
impeller::RoundRect::IsFinite
constexpr bool IsFinite() const
Definition: round_rect.h:57
impeller::RoundRect::MakeRectRadius
static RoundRect MakeRectRadius(const Rect &rect, Scalar radius)
Definition: round_rect.h:27
impeller::RoundRect::GetRadii
constexpr const RoundingRadii & GetRadii() const
Definition: round_rect.h:55
impeller::RoundRect::MakeRectRadii
static RoundRect MakeRectRadii(const Rect &rect, const RoundingRadii &radii)
Definition: round_rect.cc:9
impeller::RoundRect::Expand
RoundRect Expand(Scalar amount) const
Returns a round rectangle with expanded edges. Negative expansion results in shrinking.
Definition: round_rect.h:120
impeller::RoundRect::MakeNinePatch
static RoundRect MakeNinePatch(const Rect &rect, Scalar left, Scalar top, Scalar right, Scalar bottom)
Definition: round_rect.h:42
impeller::RoundRect::IsEmpty
constexpr bool IsEmpty() const
Definition: round_rect.h:65
impeller::RoundRect::operator==
constexpr bool operator==(const RoundRect &rr) const
Definition: round_rect.h:127
impeller::RoundRect::MakeOval
static RoundRect MakeOval(const Rect &rect)
Definition: round_rect.h:23
impeller::RoundRect::MakeRectXY
static RoundRect MakeRectXY(const Rect &rect, Scalar x_radius, Scalar y_radius)
Definition: round_rect.h:31
impeller::RoundRect::IsRect
constexpr bool IsRect() const
Definition: round_rect.h:67
impeller::RoundRect::RoundRect
RoundRect()=default
impeller::RoundRect::Expand
RoundRect Expand(Scalar left, Scalar top, Scalar right, Scalar bottom) const
Returns a round rectangle with expanded edges. Negative expansion results in shrinking.
Definition: round_rect.h:98
impeller::RoundRect::MakeRectXY
static RoundRect MakeRectXY(const Rect &rect, Size corner_radii)
Definition: round_rect.h:38
impeller::RoundRect::Contains
bool Contains(const Point &p) const
Returns true iff the provided point |p| is inside the half-open interior of this rectangle.
Definition: round_rect.cc:73
impeller::RoundRect::Expand
RoundRect Expand(Scalar horizontal, Scalar vertical) const
Returns a round rectangle with expanded edges. Negative expansion results in shrinking.
Definition: round_rect.h:110
impeller::RoundRect::GetBounds
constexpr const Rect & GetBounds() const
Definition: round_rect.h:53
impeller::RoundRect::IsOval
constexpr bool IsOval() const
Definition: round_rect.h:71
impeller::RoundRect::MakeRect
static RoundRect MakeRect(const Rect &rect)
Definition: round_rect.h:19
impeller::RoundRect::Shift
RoundRect Shift(Scalar dx, Scalar dy) const
Returns a new round rectangle translated by the given offset.
Definition: round_rect.h:89
impeller::RoundingRadii
Definition: rounding_radii.h:14
impeller::RoundingRadii::MakeNinePatch
constexpr static RoundingRadii MakeNinePatch(Scalar left, Scalar top, Scalar right, Scalar bottom)
Definition: rounding_radii.h:28
impeller::RoundingRadii::top_right
Size top_right
Definition: rounding_radii.h:16
impeller::RoundingRadii::bottom_left
Size bottom_left
Definition: rounding_radii.h:17
impeller::RoundingRadii::bottom_right
Size bottom_right
Definition: rounding_radii.h:18
impeller::RoundingRadii::top_left
Size top_left
Definition: rounding_radii.h:15
impeller::RoundingRadii::AreAllCornersEmpty
constexpr bool AreAllCornersEmpty() const
Definition: rounding_radii.h:47
impeller::RoundingRadii::MakeRadii
constexpr static RoundingRadii MakeRadii(Size radii)
Definition: rounding_radii.h:24
impeller::RoundingRadii::AreAllCornersSame
constexpr bool AreAllCornersSame(Scalar tolerance=kEhCloseEnough) const
Definition: rounding_radii.h:54
impeller::RoundingRadii::MakeRadius
constexpr static RoundingRadii MakeRadius(Scalar radius)
Definition: rounding_radii.h:20
impeller::TPoint< Scalar >
impeller::TRect< Scalar >
impeller::TRect::Expand
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
Definition: rect.h:618
impeller::TRect::GetHeight
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
Definition: rect.h:347
impeller::TRect::IsEmpty
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition: rect.h:297
impeller::TRect::GetSize
constexpr TSize< Type > GetSize() const
Returns the size of the rectangle which may be negative in either width or height and may have been c...
Definition: rect.h:327
impeller::TRect::IsFinite
IsFinite() const
Returns true if all of the fields of this floating point rectangle are finite.
Definition: rect.h:288
impeller::TRect::Shift
constexpr TRect< T > Shift(T dx, T dy) const
Returns a new rectangle translated by the given offset.
Definition: rect.h:602
impeller::TRect::GetWidth
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition: rect.h:341
impeller::TSize< Scalar >
impeller::TSize::height
Type height
Definition: size.h:29
impeller::TSize::width
Type width
Definition: size.h:28
impeller::TSize::IsFinite
IsFinite() const
Definition: size.h:126