| Flutter Impeller |

round_superellipse.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_SUPERELLIPSE_H_
6 #define FLUTTER_IMPELLER_GEOMETRY_ROUND_SUPERELLIPSE_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
18 struct RoundSuperellipse {
19 RoundSuperellipse() = default;
20
21 inline static RoundSuperellipse MakeRect(const Rect& rect) {
22 return MakeRectRadii(rect, RoundingRadii());
23 }
24
25 inline static RoundSuperellipse MakeOval(const Rect& rect) {
26 return MakeRectRadii(rect, RoundingRadii::MakeRadii(rect.GetSize() * 0.5f));
27 }
28
29 inline static RoundSuperellipse MakeRectRadius(const Rect& rect,
30 Scalar radius) {
31 return MakeRectRadii(rect, RoundingRadii::MakeRadius(radius));
32 }
33
34 inline static RoundSuperellipse MakeRectXY(const Rect& rect,
35 Scalar x_radius,
36 Scalar y_radius) {
37 return MakeRectRadii(rect,
38 RoundingRadii::MakeRadii(Size(x_radius, y_radius)));
39 }
40
41 inline static RoundSuperellipse MakeRectXY(const Rect& rect,
42 Size corner_radii) {
43 return MakeRectRadii(rect, RoundingRadii::MakeRadii(corner_radii));
44 }
45
46 static RoundSuperellipse MakeRectRadii(const Rect& rect,
47 const RoundingRadii& radii);
48
49 constexpr const Rect& GetBounds() const { return bounds_; }
50 constexpr const RoundingRadii& GetRadii() const { return radii_; }
51
52 [[nodiscard]] constexpr bool IsFinite() const {
53 return bounds_.IsFinite() && //
54 radii_.top_left.IsFinite() && //
55 radii_.top_right.IsFinite() && //
56 radii_.bottom_left.IsFinite() && //
57 radii_.bottom_right.IsFinite();
58 }
59
60 [[nodiscard]] constexpr bool IsEmpty() const { return bounds_.IsEmpty(); }
61
62 [[nodiscard]] constexpr bool IsRect() const {
63 return !bounds_.IsEmpty() && radii_.AreAllCornersEmpty();
64 }
65
66 [[nodiscard]] constexpr bool IsOval() const {
67 return !bounds_.IsEmpty() && radii_.AreAllCornersSame() &&
68 ScalarNearlyEqual(radii_.top_left.width,
69 bounds_.GetWidth() * 0.5f) &&
70 ScalarNearlyEqual(radii_.top_left.height,
71 bounds_.GetHeight() * 0.5f);
72 }
73
74 /// @brief Returns true iff the provided point |p| is inside the
75 /// half-open interior of this rectangle.
76 ///
77 /// For purposes of containment, a rectangle contains points
78 /// along the top and left edges but not points along the
79 /// right and bottom edges so that a point is only ever
80 /// considered inside one of two abutting rectangles.
81 [[nodiscard]] bool Contains(const Point& p) const;
82
83 /// @brief Returns a new round rectangle translated by the given offset.
84 [[nodiscard]] inline RoundSuperellipse Shift(Scalar dx, Scalar dy) const {
85 // Just in case, use the factory rather than the internal constructor
86 // as shifting the rectangle may increase/decrease its bit precision
87 // so we should re-validate the radii to the newly located rectangle.
88 return MakeRectRadii(bounds_.Shift(dx, dy), radii_);
89 }
90
91 /// @brief Returns a round rectangle with expanded edges. Negative expansion
92 /// results in shrinking.
93 [[nodiscard]] inline RoundSuperellipse Expand(Scalar left,
94 Scalar top,
95 Scalar right,
96 Scalar bottom) const {
97 // Use the factory rather than the internal constructor as the changing
98 // size of the rectangle requires that we re-validate the radii to the
99 // newly sized rectangle.
100 return MakeRectRadii(bounds_.Expand(left, top, right, bottom), radii_);
101 }
102
103 /// @brief Returns a round rectangle with expanded edges. Negative expansion
104 /// results in shrinking.
105 [[nodiscard]] inline RoundSuperellipse Expand(Scalar horizontal,
106 Scalar vertical) const {
107 // Use the factory rather than the internal constructor as the changing
108 // size of the rectangle requires that we re-validate the radii to the
109 // newly sized rectangle.
110 return MakeRectRadii(bounds_.Expand(horizontal, vertical), radii_);
111 }
112
113 /// @brief Returns a round rectangle with expanded edges. Negative expansion
114 /// results in shrinking.
115 [[nodiscard]] inline RoundSuperellipse Expand(Scalar amount) const {
116 // Use the factory rather than the internal constructor as the changing
117 // size of the rectangle requires that we re-validate the radii to the
118 // newly sized rectangle.
119 return MakeRectRadii(bounds_.Expand(amount), radii_);
120 }
121
122 [[nodiscard]] constexpr bool operator==(const RoundSuperellipse& rr) const {
123 return bounds_ == rr.bounds_ && radii_ == rr.radii_;
124 }
125
126 [[nodiscard]] constexpr bool operator!=(const RoundSuperellipse& r) const {
127 return !(*this == r);
128 }
129
130 // Approximates a rounded superellipse with a round rectangle to the
131 // best practical accuracy.
132 //
133 // This is used for Skia backends, which does not support rounded
134 // superellipses directly, so rendering rounded superellipses
135 // falls back to RRect.
136 [[nodiscard]] RoundRect ToApproximateRoundRect() const;
137
138 private:
139 constexpr RoundSuperellipse(const Rect& bounds, const RoundingRadii& radii)
140 : bounds_(bounds), radii_(radii) {}
141
142 Rect bounds_;
143 RoundingRadii radii_;
144 };
145
146 class RoundSuperellipsePathSource : public PathSource {
147 public:
148 explicit RoundSuperellipsePathSource(
149 const RoundSuperellipse& round_superellipse);
150
151 ~RoundSuperellipsePathSource();
152
153 const RoundSuperellipse& GetRoundSuperellipse() const {
154 return round_superellipse_;
155 }
156
157 // |PathSource|
158 FillType GetFillType() const override;
159
160 // |PathSource|
161 Rect GetBounds() const override;
162
163 // |PathSource|
164 bool IsConvex() const override;
165
166 // |PathSource|
167 void Dispatch(PathReceiver& receiver) const override;
168
169 private:
170 const RoundSuperellipse round_superellipse_;
171 };
172
173 } // namespace impeller
174
175 namespace std {
176
177 inline std::ostream& operator<<(std::ostream& out,
178 const impeller::RoundSuperellipse& rr) {
179 out << "(" //
180 << "rect: " << rr.GetBounds() << ", " //
181 << "radii: " << rr.GetRadii();
182 out << ")";
183 return out;
184 }
185
186 } // namespace std
187
188 #endif // FLUTTER_IMPELLER_GEOMETRY_ROUND_SUPERELLIPSE_H_
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::RoundSuperellipsePathSource
Definition: round_superellipse.h:146
impeller::RoundSuperellipsePathSource::GetRoundSuperellipse
const RoundSuperellipse & GetRoundSuperellipse() const
Definition: round_superellipse.h:153
impeller::RoundSuperellipsePathSource::RoundSuperellipsePathSource
RoundSuperellipsePathSource(const RoundSuperellipse &round_superellipse)
Definition: round_superellipse.cc:41
impeller::RoundSuperellipsePathSource::GetBounds
Rect GetBounds() const override
Definition: round_superellipse.cc:51
impeller::RoundSuperellipsePathSource::IsConvex
bool IsConvex() const override
Definition: round_superellipse.cc:55
impeller::RoundSuperellipsePathSource::~RoundSuperellipsePathSource
~RoundSuperellipsePathSource()
impeller::RoundSuperellipsePathSource::GetFillType
FillType GetFillType() const override
Definition: round_superellipse.cc:47
impeller::RoundSuperellipsePathSource::Dispatch
void Dispatch(PathReceiver &receiver) const override
Definition: round_superellipse.cc:59
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:792
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::RoundSuperellipse
Definition: round_superellipse.h:18
impeller::RoundSuperellipse::Expand
RoundSuperellipse Expand(Scalar amount) const
Returns a round rectangle with expanded edges. Negative expansion results in shrinking.
Definition: round_superellipse.h:115
impeller::RoundSuperellipse::RoundSuperellipse
RoundSuperellipse()=default
impeller::RoundSuperellipse::GetRadii
constexpr const RoundingRadii & GetRadii() const
Definition: round_superellipse.h:50
impeller::RoundSuperellipse::MakeRectRadii
static RoundSuperellipse MakeRectRadii(const Rect &rect, const RoundingRadii &radii)
Definition: round_superellipse.cc:12
impeller::RoundSuperellipse::IsOval
constexpr bool IsOval() const
Definition: round_superellipse.h:66
impeller::RoundSuperellipse::IsFinite
constexpr bool IsFinite() const
Definition: round_superellipse.h:52
impeller::RoundSuperellipse::IsEmpty
constexpr bool IsEmpty() const
Definition: round_superellipse.h:60
impeller::RoundSuperellipse::Expand
RoundSuperellipse Expand(Scalar left, Scalar top, Scalar right, Scalar bottom) const
Returns a round rectangle with expanded edges. Negative expansion results in shrinking.
Definition: round_superellipse.h:93
impeller::RoundSuperellipse::IsRect
constexpr bool IsRect() const
Definition: round_superellipse.h:62
impeller::RoundSuperellipse::MakeOval
static RoundSuperellipse MakeOval(const Rect &rect)
Definition: round_superellipse.h:25
impeller::RoundSuperellipse::ToApproximateRoundRect
RoundRect ToApproximateRoundRect() const
Definition: round_superellipse.cc:34
impeller::RoundSuperellipse::Expand
RoundSuperellipse Expand(Scalar horizontal, Scalar vertical) const
Returns a round rectangle with expanded edges. Negative expansion results in shrinking.
Definition: round_superellipse.h:105
impeller::RoundSuperellipse::Shift
RoundSuperellipse Shift(Scalar dx, Scalar dy) const
Returns a new round rectangle translated by the given offset.
Definition: round_superellipse.h:84
impeller::RoundSuperellipse::MakeRect
static RoundSuperellipse MakeRect(const Rect &rect)
Definition: round_superellipse.h:21
impeller::RoundSuperellipse::MakeRectRadius
static RoundSuperellipse MakeRectRadius(const Rect &rect, Scalar radius)
Definition: round_superellipse.h:29
impeller::RoundSuperellipse::GetBounds
constexpr const Rect & GetBounds() const
Definition: round_superellipse.h:49
impeller::RoundSuperellipse::operator==
constexpr bool operator==(const RoundSuperellipse &rr) const
Definition: round_superellipse.h:122
impeller::RoundSuperellipse::operator!=
constexpr bool operator!=(const RoundSuperellipse &r) const
Definition: round_superellipse.h:126
impeller::RoundSuperellipse::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_superellipse.cc:26
impeller::RoundSuperellipse::MakeRectXY
static RoundSuperellipse MakeRectXY(const Rect &rect, Size corner_radii)
Definition: round_superellipse.h:41
impeller::RoundSuperellipse::MakeRectXY
static RoundSuperellipse MakeRectXY(const Rect &rect, Scalar x_radius, Scalar y_radius)
Definition: round_superellipse.h:34
impeller::RoundingRadii
Definition: rounding_radii.h:14
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:622
impeller::TRect::GetHeight
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
Definition: rect.h:351
impeller::TRect::IsEmpty
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition: rect.h:301
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:331
impeller::TRect::IsFinite
IsFinite() const
Returns true if all of the fields of this floating point rectangle are finite.
Definition: rect.h:292
impeller::TRect::Shift
constexpr TRect< T > Shift(T dx, T dy) const
Returns a new rectangle translated by the given offset.
Definition: rect.h:606
impeller::TRect::GetWidth
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition: rect.h:345
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