| Flutter Impeller |

path_source_unittests.cc
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 #include "impeller/geometry/path_source.h"
6
7 #include "gtest/gtest.h"
8
9 #include "flutter/display_list/testing/dl_test_mock_path_receiver.h"
10 #include "flutter/testing/testing.h"
11 #include "impeller/geometry/dashed_line_path_source.h"
12 #include "impeller/geometry/rect.h"
13 #include "impeller/geometry/round_rect.h"
14 #include "impeller/geometry/round_superellipse.h"
15
16 namespace impeller {
17 namespace testing {
18
19 using DlPathReceiverMock = flutter::testing::DlPathReceiverMock;
20
21 TEST(PathSourceTest, RectSourceTest) {
22 Rect rect = Rect::MakeLTRB(10, 15, 20, 30);
23 RectPathSource source(rect);
24
25 EXPECT_TRUE(source.IsConvex());
26 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
27 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 15, 20, 30));
28
29 ::testing::StrictMock<DlPathReceiverMock> receiver;
30
31 {
32 ::testing::Sequence sequence;
33
34 EXPECT_CALL(receiver, MoveTo(Point(10, 15), true));
35 EXPECT_CALL(receiver, LineTo(Point(20, 15)));
36 EXPECT_CALL(receiver, LineTo(Point(20, 30)));
37 EXPECT_CALL(receiver, LineTo(Point(10, 30)));
38 EXPECT_CALL(receiver, LineTo(Point(10, 15)));
39 EXPECT_CALL(receiver, Close());
40 }
41
42 source.Dispatch(receiver);
43 }
44
45 TEST(PathSourceTest, EllipseSourceTest) {
46 Rect rect = Rect::MakeLTRB(10, 15, 20, 30);
47 EllipsePathSource source(rect);
48
49 EXPECT_TRUE(source.IsConvex());
50 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
51 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 15, 20, 30));
52
53 ::testing::StrictMock<DlPathReceiverMock> receiver;
54
55 {
56 ::testing::Sequence sequence;
57
58 EXPECT_CALL(receiver, MoveTo(Point(10, 22.5), true));
59 EXPECT_CALL(receiver, ConicTo(Point(10, 15), Point(15, 15), kSqrt2Over2));
60 EXPECT_CALL(receiver, ConicTo(Point(20, 15), Point(20, 22.5), kSqrt2Over2));
61 EXPECT_CALL(receiver, ConicTo(Point(20, 30), Point(15, 30), kSqrt2Over2));
62 EXPECT_CALL(receiver, ConicTo(Point(10, 30), Point(10, 22.5), kSqrt2Over2));
63 EXPECT_CALL(receiver, Close());
64 }
65
66 source.Dispatch(receiver);
67 }
68
69 TEST(PathSourceTest, RoundRectSourceTest) {
70 Rect rect = Rect::MakeLTRB(10, 15, 40, 60);
71 RoundingRadii radii = {
72 .top_left = Size(1, 11),
73 .top_right = Size(2, 12),
74 .bottom_left = Size(4, 14),
75 .bottom_right = Size(3, 13),
76 };
77 RoundRect round_rect = RoundRect::MakeRectRadii(rect, radii);
78 RoundRectPathSource source(round_rect);
79
80 EXPECT_TRUE(source.IsConvex());
81 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
82 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 15, 40, 60));
83
84 ::testing::StrictMock<DlPathReceiverMock> receiver;
85
86 {
87 ::testing::Sequence sequence;
88
89 EXPECT_CALL(receiver, MoveTo(Point(11, 15), true));
90 EXPECT_CALL(receiver, LineTo(Point(38, 15)));
91 EXPECT_CALL(receiver, ConicTo(Point(40, 15), Point(40, 27), kSqrt2Over2));
92 EXPECT_CALL(receiver, LineTo(Point(40, 47)));
93 EXPECT_CALL(receiver, ConicTo(Point(40, 60), Point(37, 60), kSqrt2Over2));
94 EXPECT_CALL(receiver, LineTo(Point(14, 60)));
95 EXPECT_CALL(receiver, ConicTo(Point(10, 60), Point(10, 46), kSqrt2Over2));
96 EXPECT_CALL(receiver, LineTo(Point(10, 26)));
97 EXPECT_CALL(receiver, ConicTo(Point(10, 15), Point(11, 15), kSqrt2Over2));
98 EXPECT_CALL(receiver, Close());
99 }
100
101 source.Dispatch(receiver);
102 }
103
104 TEST(PathSourceTest, DiffRoundRectSourceTest) {
105 Rect outer_rect = Rect::MakeLTRB(10, 15, 200, 300);
106 Rect inner_rect = Rect::MakeLTRB(50, 60, 100, 200);
107 ASSERT_TRUE(outer_rect.Contains(inner_rect));
108 RoundingRadii radii = {
109 .top_left = Size(1, 11),
110 .top_right = Size(2, 12),
111 .bottom_left = Size(4, 14),
112 .bottom_right = Size(3, 13),
113 };
114 RoundRect outer_rrect = RoundRect::MakeRectRadii(outer_rect, radii);
115 RoundRect inner_rrect = RoundRect::MakeRectRadii(inner_rect, radii);
116 DiffRoundRectPathSource source(outer_rrect, inner_rrect);
117
118 EXPECT_FALSE(source.IsConvex());
119 EXPECT_EQ(source.GetFillType(), FillType::kOdd);
120 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 15, 200, 300));
121
122 ::testing::StrictMock<DlPathReceiverMock> receiver;
123
124 {
125 ::testing::Sequence sequence;
126
127 EXPECT_CALL(receiver, MoveTo(Point(11, 15), true));
128 EXPECT_CALL(receiver, LineTo(Point(198, 15)));
129 EXPECT_CALL(receiver, ConicTo(Point(200, 15), Point(200, 27), kSqrt2Over2));
130 EXPECT_CALL(receiver, LineTo(Point(200, 287)));
131 EXPECT_CALL(receiver,
132 ConicTo(Point(200, 300), Point(197, 300), kSqrt2Over2));
133 EXPECT_CALL(receiver, LineTo(Point(14, 300)));
134 EXPECT_CALL(receiver, ConicTo(Point(10, 300), Point(10, 286), kSqrt2Over2));
135 EXPECT_CALL(receiver, LineTo(Point(10, 26)));
136 EXPECT_CALL(receiver, ConicTo(Point(10, 15), Point(11, 15), kSqrt2Over2));
137 // RetiresOnSaturation keeps identical calls from matching each other
138 EXPECT_CALL(receiver, Close()).RetiresOnSaturation();
139
140 EXPECT_CALL(receiver, MoveTo(Point(51, 60), true));
141 EXPECT_CALL(receiver, LineTo(Point(98, 60)));
142 EXPECT_CALL(receiver, ConicTo(Point(100, 60), Point(100, 72), kSqrt2Over2));
143 EXPECT_CALL(receiver, LineTo(Point(100, 187)));
144 EXPECT_CALL(receiver,
145 ConicTo(Point(100, 200), Point(97, 200), kSqrt2Over2));
146 EXPECT_CALL(receiver, LineTo(Point(54, 200)));
147 EXPECT_CALL(receiver, ConicTo(Point(50, 200), Point(50, 186), kSqrt2Over2));
148 EXPECT_CALL(receiver, LineTo(Point(50, 71)));
149 EXPECT_CALL(receiver, ConicTo(Point(50, 60), Point(51, 60), kSqrt2Over2));
150 // RetiresOnSaturation keeps identical calls from matching each other
151 EXPECT_CALL(receiver, Close()).RetiresOnSaturation();
152 }
153
154 source.Dispatch(receiver);
155 }
156
157 TEST(PathSourceTest, DashedLinePathSource) {
158 DashedLinePathSource source(Point(10, 10), Point(30, 10), 5, 5);
159
160 EXPECT_FALSE(source.IsConvex());
161 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
162 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 30, 10));
163
164 ::testing::StrictMock<DlPathReceiverMock> receiver;
165
166 {
167 ::testing::Sequence sequence;
168
169 EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
170 EXPECT_CALL(receiver, LineTo(Point(15, 10)));
171 EXPECT_CALL(receiver, MoveTo(Point(20, 10), false));
172 EXPECT_CALL(receiver, LineTo(Point(25, 10)));
173 }
174
175 source.Dispatch(receiver);
176 }
177
178 TEST(PathSourceTest, EmptyDashedLinePathSource) {
179 DashedLinePathSource source(Point(10, 10), Point(10, 10), 5, 5);
180
181 EXPECT_FALSE(source.IsConvex());
182 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
183 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 10, 10));
184
185 ::testing::StrictMock<DlPathReceiverMock> receiver;
186
187 {
188 ::testing::Sequence sequence;
189
190 EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
191 EXPECT_CALL(receiver, LineTo(Point(10, 10)));
192 }
193
194 source.Dispatch(receiver);
195 }
196
197 TEST(PathSourceTest, DashedLinePathSourceZeroOffGaps) {
198 DashedLinePathSource source(Point(10, 10), Point(30, 10), 5, 0);
199
200 EXPECT_FALSE(source.IsConvex());
201 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
202 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 30, 10));
203
204 ::testing::StrictMock<DlPathReceiverMock> receiver;
205
206 {
207 ::testing::Sequence sequence;
208
209 EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
210 EXPECT_CALL(receiver, LineTo(Point(30, 10)));
211 }
212
213 source.Dispatch(receiver);
214 }
215
216 TEST(PathSourceTest, DashedLinePathSourceInvalidOffGaps) {
217 DashedLinePathSource source(Point(10, 10), Point(30, 10), 5, -1);
218
219 EXPECT_FALSE(source.IsConvex());
220 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
221 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 30, 10));
222
223 ::testing::StrictMock<DlPathReceiverMock> receiver;
224
225 {
226 ::testing::Sequence sequence;
227
228 EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
229 EXPECT_CALL(receiver, LineTo(Point(30, 10)));
230 }
231
232 source.Dispatch(receiver);
233 }
234
235 TEST(PathSourceTest, DashedLinePathSourceInvalidOnRegion) {
236 DashedLinePathSource source(Point(10, 10), Point(30, 10), -1, 5);
237
238 EXPECT_FALSE(source.IsConvex());
239 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
240 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 30, 10));
241
242 ::testing::StrictMock<DlPathReceiverMock> receiver;
243
244 {
245 ::testing::Sequence sequence;
246
247 EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
248 EXPECT_CALL(receiver, LineTo(Point(30, 10)));
249 }
250
251 source.Dispatch(receiver);
252 }
253
254 } // namespace testing
255 } // namespace impeller
impeller::DashedLinePathSource
A PathSource that generates the various segments of a dashed line.
Definition: dashed_line_path_source.h:15
impeller::DashedLinePathSource::IsConvex
bool IsConvex() const override
Definition: dashed_line_path_source.cc:25
impeller::DashedLinePathSource::GetFillType
FillType GetFillType() const override
Definition: dashed_line_path_source.cc:17
impeller::DashedLinePathSource::GetBounds
Rect GetBounds() const override
Definition: dashed_line_path_source.cc:21
impeller::DashedLinePathSource::Dispatch
void Dispatch(PathReceiver &receiver) const override
Definition: dashed_line_path_source.cc:29
impeller::DiffRoundRectPathSource
Definition: round_rect.h:173
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::EllipsePathSource
A PathSource object that provides path iteration for any ellipse inscribed within a Rect bounds.
Definition: path_source.h:90
impeller::EllipsePathSource::Dispatch
void Dispatch(PathReceiver &receiver) const override
Definition: path_source.cc:48
impeller::EllipsePathSource::IsConvex
bool IsConvex() const override
Definition: path_source.cc:44
impeller::EllipsePathSource::GetBounds
Rect GetBounds() const override
Definition: path_source.cc:40
impeller::EllipsePathSource::GetFillType
FillType GetFillType() const override
Definition: path_source.cc:36
impeller::RectPathSource
A PathSource object that provides path iteration for any TRect.
Definition: path_source.h:65
impeller::RectPathSource::GetFillType
FillType GetFillType() const override
Definition: path_source.cc:15
impeller::RectPathSource::IsConvex
bool IsConvex() const override
Definition: path_source.cc:11
impeller::RectPathSource::GetBounds
Rect GetBounds() const override
Definition: path_source.cc:19
impeller::RectPathSource::Dispatch
void Dispatch(PathReceiver &receiver) const override
Definition: path_source.cc:23
impeller::RoundRectPathSource
Definition: round_rect.h:149
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::GetFillType
FillType GetFillType() const override
Definition: round_rect.cc:129
dashed_line_path_source.h
impeller::testing::TEST
TEST(AllocationSizeTest, CanCreateTypedAllocations)
Definition: allocation_size_unittests.cc:10
impeller::testing::DlPathReceiverMock
flutter::testing::DlPathReceiverMock DlPathReceiverMock
Definition: path_source_unittests.cc:19
impeller
Definition: allocation.cc:12
impeller::kSqrt2Over2
constexpr float kSqrt2Over2
Definition: constants.h:51
impeller::FillType::kOdd
@ kOdd
impeller::FillType::kNonZero
@ kNonZero
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
impeller::Size
TSize< Scalar > Size
Definition: size.h:159
impeller::MoveTo
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:20
impeller::LineTo
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:24
impeller::Close
void Close(PathBuilder *builder)
Definition: tessellator.cc:38
path_source.h
rect.h
round_rect.h
round_superellipse.h
impeller::RoundRect
Definition: round_rect.h:16
impeller::RoundRect::MakeRectRadii
static RoundRect MakeRectRadii(const Rect &rect, const RoundingRadii &radii)
Definition: round_rect.cc:9
impeller::RoundingRadii
Definition: rounding_radii.h:14
impeller::RoundingRadii::top_left
Size top_left
Definition: rounding_radii.h:15
impeller::TRect< Scalar >
impeller::TRect::Contains
constexpr bool Contains(const TPoint< Type > &p) const
Returns true iff the provided point |p| is inside the half-open interior of this rectangle.
Definition: rect.h:235
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129