| 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/point.h"
9 #include "flutter/impeller/geometry/rect.h"
10 #include "flutter/impeller/geometry/rounding_radii.h"
11 #include "flutter/impeller/geometry/size.h"
12
13 namespace impeller {
14
15 struct RoundRect;
16
17 struct RoundSuperellipse {
18 RoundSuperellipse() = default;
19
20 constexpr static RoundSuperellipse MakeRect(const Rect& rect) {
21 return MakeRectRadii(rect, RoundingRadii());
22 }
23
24 constexpr static RoundSuperellipse MakeOval(const Rect& rect) {
25 return MakeRectRadii(rect, RoundingRadii::MakeRadii(rect.GetSize() * 0.5f));
26 }
27
28 constexpr static RoundSuperellipse MakeRectRadius(const Rect& rect,
29 Scalar radius) {
30 return MakeRectRadii(rect, RoundingRadii::MakeRadius(radius));
31 }
32
33 constexpr static RoundSuperellipse MakeRectXY(const Rect& rect,
34 Scalar x_radius,
35 Scalar y_radius) {
36 return MakeRectRadii(rect,
37 RoundingRadii::MakeRadii(Size(x_radius, y_radius)));
38 }
39
40 constexpr static RoundSuperellipse MakeRectXY(const Rect& rect,
41 Size corner_radii) {
42 return MakeRectRadii(rect, RoundingRadii::MakeRadii(corner_radii));
43 }
44
45 static RoundSuperellipse MakeRectRadii(const Rect& rect,
46 const RoundingRadii& radii);
47
48 constexpr const Rect& GetBounds() const { return bounds_; }
49 constexpr const RoundingRadii& GetRadii() const { return radii_; }
50
51 [[nodiscard]] constexpr bool IsFinite() const {
52 return bounds_.IsFinite() && //
53 radii_.top_left.IsFinite() && //
54 radii_.top_right.IsFinite() && //
55 radii_.bottom_left.IsFinite() && //
56 radii_.bottom_right.IsFinite();
57 }
58
59 [[nodiscard]] constexpr bool IsEmpty() const { return bounds_.IsEmpty(); }
60
61 [[nodiscard]] constexpr bool IsRect() const {
62 return !bounds_.IsEmpty() && radii_.AreAllCornersEmpty();
63 }
64
65 [[nodiscard]] constexpr bool IsOval() const {
66 return !bounds_.IsEmpty() && radii_.AreAllCornersSame() &&
67 ScalarNearlyEqual(radii_.top_left.width,
68 bounds_.GetWidth() * 0.5f) &&
69 ScalarNearlyEqual(radii_.top_left.height,
70 bounds_.GetHeight() * 0.5f);
71 }
72
73 /// @brief Returns true iff the provided point |p| is inside the
74 /// half-open interior of this rectangle.
75 ///
76 /// For purposes of containment, a rectangle contains points
77 /// along the top and left edges but not points along the
78 /// right and bottom edges so that a point is only ever
79 /// considered inside one of two abutting rectangles.
80 [[nodiscard]] bool Contains(const Point& p) const;
81
82 /// @brief Returns a new round rectangle translated by the given offset.
83 [[nodiscard]] constexpr RoundSuperellipse Shift(Scalar dx, Scalar dy) const {
84 // Just in case, use the factory rather than the internal constructor
85 // as shifting the rectangle may increase/decrease its bit precision
86 // so we should re-validate the radii to the newly located rectangle.
87 return MakeRectRadii(bounds_.Shift(dx, dy), radii_);
88 }
89
90 /// @brief Returns a round rectangle with expanded edges. Negative expansion
91 /// results in shrinking.
92 [[nodiscard]] constexpr RoundSuperellipse Expand(Scalar left,
93 Scalar top,
94 Scalar right,
95 Scalar bottom) const {
96 // Use the factory rather than the internal constructor as the changing
97 // size of the rectangle requires that we re-validate the radii to the
98 // newly sized rectangle.
99 return MakeRectRadii(bounds_.Expand(left, top, right, bottom), radii_);
100 }
101
102 /// @brief Returns a round rectangle with expanded edges. Negative expansion
103 /// results in shrinking.
104 [[nodiscard]] constexpr RoundSuperellipse Expand(Scalar horizontal,
105 Scalar vertical) const {
106 // Use the factory rather than the internal constructor as the changing
107 // size of the rectangle requires that we re-validate the radii to the
108 // newly sized rectangle.
109 return MakeRectRadii(bounds_.Expand(horizontal, vertical), radii_);
110 }
111
112 /// @brief Returns a round rectangle with expanded edges. Negative expansion
113 /// results in shrinking.
114 [[nodiscard]] constexpr RoundSuperellipse Expand(Scalar amount) const {
115 // Use the factory rather than the internal constructor as the changing
116 // size of the rectangle requires that we re-validate the radii to the
117 // newly sized rectangle.
118 return MakeRectRadii(bounds_.Expand(amount), radii_);
119 }
120
121 [[nodiscard]] constexpr bool operator==(const RoundSuperellipse& rr) const {
122 return bounds_ == rr.bounds_ && radii_ == rr.radii_;
123 }
124
125 [[nodiscard]] constexpr bool operator!=(const RoundSuperellipse& r) const {
126 return !(*this == r);
127 }
128
129 // Approximates a rounded superellipse with a round rectangle to the
130 // best practical accuracy.
131 //
132 // This is used for Skia backends, which does not support rounded
133 // superellipses directly, so rendering rounded superellipses
134 // falls back to RRect.
135 [[nodiscard]] RoundRect ToApproximateRoundRect() const;
136
137 private:
138 constexpr RoundSuperellipse(const Rect& bounds, const RoundingRadii& radii)
139 : bounds_(bounds), radii_(radii) {}
140
141 Rect bounds_;
142 RoundingRadii radii_;
143 };
144
145 } // namespace impeller
146
147 namespace std {
148
149 inline std::ostream& operator<<(std::ostream& out,
150 const impeller::RoundSuperellipse& rr) {
151 out << "(" //
152 << "rect: " << rr.GetBounds() << ", " //
153 << "radii: " << rr.GetRadii();
154 out << ")";
155 return out;
156 }
157
158 } // namespace std
159
160 #endif // FLUTTER_IMPELLER_GEOMETRY_ROUND_SUPERELLIPSE_H_
impeller
Definition: allocation.cc:12
impeller::Scalar
float Scalar
Definition: scalar.h:18
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:35
std
Definition: comparable.h:95
std::operator<<
std::ostream & operator<<(std::ostream &out, const impeller::Color &c)
Definition: color.h:927
point.h
rect.h
rounding_radii.h
size.h
impeller::RoundRect
Definition: round_rect.h:15
impeller::RoundSuperellipse
Definition: round_superellipse.h:17
impeller::RoundSuperellipse::Expand
constexpr 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:92
impeller::RoundSuperellipse::Expand
constexpr RoundSuperellipse Expand(Scalar horizontal, Scalar vertical) const
Returns a round rectangle with expanded edges. Negative expansion results in shrinking.
Definition: round_superellipse.h:104
impeller::RoundSuperellipse::MakeRectXY
constexpr static RoundSuperellipse MakeRectXY(const Rect &rect, Size corner_radii)
Definition: round_superellipse.h:40
impeller::RoundSuperellipse::RoundSuperellipse
RoundSuperellipse()=default
impeller::RoundSuperellipse::MakeOval
constexpr static RoundSuperellipse MakeOval(const Rect &rect)
Definition: round_superellipse.h:24
impeller::RoundSuperellipse::GetRadii
constexpr const RoundingRadii & GetRadii() const
Definition: round_superellipse.h:49
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:65
impeller::RoundSuperellipse::MakeRect
constexpr static RoundSuperellipse MakeRect(const Rect &rect)
Definition: round_superellipse.h:20
impeller::RoundSuperellipse::IsFinite
constexpr bool IsFinite() const
Definition: round_superellipse.h:51
impeller::RoundSuperellipse::IsEmpty
constexpr bool IsEmpty() const
Definition: round_superellipse.h:59
impeller::RoundSuperellipse::Expand
constexpr RoundSuperellipse Expand(Scalar amount) const
Returns a round rectangle with expanded edges. Negative expansion results in shrinking.
Definition: round_superellipse.h:114
impeller::RoundSuperellipse::IsRect
constexpr bool IsRect() const
Definition: round_superellipse.h:61
impeller::RoundSuperellipse::Shift
constexpr RoundSuperellipse Shift(Scalar dx, Scalar dy) const
Returns a new round rectangle translated by the given offset.
Definition: round_superellipse.h:83
impeller::RoundSuperellipse::MakeRectRadius
constexpr static RoundSuperellipse MakeRectRadius(const Rect &rect, Scalar radius)
Definition: round_superellipse.h:28
impeller::RoundSuperellipse::ToApproximateRoundRect
RoundRect ToApproximateRoundRect() const
Definition: round_superellipse.cc:34
impeller::RoundSuperellipse::GetBounds
constexpr const Rect & GetBounds() const
Definition: round_superellipse.h:48
impeller::RoundSuperellipse::operator==
constexpr bool operator==(const RoundSuperellipse &rr) const
Definition: round_superellipse.h:121
impeller::RoundSuperellipse::operator!=
constexpr bool operator!=(const RoundSuperellipse &r) const
Definition: round_superellipse.h:125
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
constexpr static RoundSuperellipse MakeRectXY(const Rect &rect, Scalar x_radius, Scalar y_radius)
Definition: round_superellipse.h:33
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