Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
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
6
7#include "gtest/gtest.h"
8
15
16namespace impeller {
17namespace testing {
18
19using ::flutter::testing::DlPathReceiverMock;
20using ::testing::Return;
21
22TEST(PathSourceTest, RectSourceTest) {
23 Rect rect = Rect::MakeLTRB(10, 15, 20, 30);
24 RectPathSource source(rect);
25
26 EXPECT_TRUE(source.IsConvex());
27 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
28 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 15, 20, 30));
29
30 ::testing::StrictMock<DlPathReceiverMock> receiver;
31
32 {
33 ::testing::Sequence sequence;
34
35 EXPECT_CALL(receiver, MoveTo(Point(10, 15), true));
36 EXPECT_CALL(receiver, LineTo(Point(20, 15)));
37 EXPECT_CALL(receiver, LineTo(Point(20, 30)));
38 EXPECT_CALL(receiver, LineTo(Point(10, 30)));
39 EXPECT_CALL(receiver, LineTo(Point(10, 15)));
40 EXPECT_CALL(receiver, Close());
41 }
42
43 source.Dispatch(receiver);
44}
45
46TEST(PathSourceTest, EllipseSourceTest) {
47 Rect rect = Rect::MakeLTRB(10, 15, 20, 30);
48 EllipsePathSource source(rect);
49
50 EXPECT_TRUE(source.IsConvex());
51 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
52 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 15, 20, 30));
53
54 ::testing::StrictMock<DlPathReceiverMock> receiver;
55
56 {
57 ::testing::Sequence sequence;
58
59 EXPECT_CALL(receiver, MoveTo(Point(10, 22.5), true));
60 EXPECT_CALL(receiver, ConicTo(Point(10, 15), Point(15, 15), kSqrt2Over2));
61 EXPECT_CALL(receiver, ConicTo(Point(20, 15), Point(20, 22.5), kSqrt2Over2));
62 EXPECT_CALL(receiver, ConicTo(Point(20, 30), Point(15, 30), kSqrt2Over2));
63 EXPECT_CALL(receiver, ConicTo(Point(10, 30), Point(10, 22.5), kSqrt2Over2));
64 EXPECT_CALL(receiver, Close());
65 }
66
67 source.Dispatch(receiver);
68}
69
70TEST(PathSourceTest, RoundRectSourceTest) {
71 Rect rect = Rect::MakeLTRB(10, 15, 40, 60);
72 RoundingRadii radii = {
73 .top_left = Size(1, 11),
74 .top_right = Size(2, 12),
75 .bottom_left = Size(4, 14),
76 .bottom_right = Size(3, 13),
77 };
78 RoundRect round_rect = RoundRect::MakeRectRadii(rect, radii);
79 RoundRectPathSource source(round_rect);
80
81 EXPECT_TRUE(source.IsConvex());
82 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
83 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 15, 40, 60));
84
85 ::testing::StrictMock<DlPathReceiverMock> receiver;
86
87 {
88 ::testing::Sequence sequence;
89
90 EXPECT_CALL(receiver, MoveTo(Point(11, 15), true));
91 EXPECT_CALL(receiver, LineTo(Point(38, 15)));
92 EXPECT_CALL(receiver, ConicTo(Point(40, 15), Point(40, 27), kSqrt2Over2));
93 EXPECT_CALL(receiver, LineTo(Point(40, 47)));
94 EXPECT_CALL(receiver, ConicTo(Point(40, 60), Point(37, 60), kSqrt2Over2));
95 EXPECT_CALL(receiver, LineTo(Point(14, 60)));
96 EXPECT_CALL(receiver, ConicTo(Point(10, 60), Point(10, 46), kSqrt2Over2));
97 EXPECT_CALL(receiver, LineTo(Point(10, 26)));
98 EXPECT_CALL(receiver, ConicTo(Point(10, 15), Point(11, 15), kSqrt2Over2));
99 EXPECT_CALL(receiver, Close());
100 }
101
102 source.Dispatch(receiver);
103}
104
105TEST(PathSourceTest, DiffRoundRectSourceTest) {
106 Rect outer_rect = Rect::MakeLTRB(10, 15, 200, 300);
107 Rect inner_rect = Rect::MakeLTRB(50, 60, 100, 200);
108 ASSERT_TRUE(outer_rect.Contains(inner_rect));
109 RoundingRadii radii = {
110 .top_left = Size(1, 11),
111 .top_right = Size(2, 12),
112 .bottom_left = Size(4, 14),
113 .bottom_right = Size(3, 13),
114 };
115 RoundRect outer_rrect = RoundRect::MakeRectRadii(outer_rect, radii);
116 RoundRect inner_rrect = RoundRect::MakeRectRadii(inner_rect, radii);
117 DiffRoundRectPathSource source(outer_rrect, inner_rrect);
118
119 EXPECT_FALSE(source.IsConvex());
120 EXPECT_EQ(source.GetFillType(), FillType::kOdd);
121 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 15, 200, 300));
122
123 ::testing::StrictMock<DlPathReceiverMock> receiver;
124
125 {
126 ::testing::Sequence sequence;
127
128 EXPECT_CALL(receiver, MoveTo(Point(11, 15), true));
129 EXPECT_CALL(receiver, LineTo(Point(198, 15)));
130 EXPECT_CALL(receiver, ConicTo(Point(200, 15), Point(200, 27), kSqrt2Over2));
131 EXPECT_CALL(receiver, LineTo(Point(200, 287)));
132 EXPECT_CALL(receiver,
133 ConicTo(Point(200, 300), Point(197, 300), kSqrt2Over2));
134 EXPECT_CALL(receiver, LineTo(Point(14, 300)));
135 EXPECT_CALL(receiver, ConicTo(Point(10, 300), Point(10, 286), kSqrt2Over2));
136 EXPECT_CALL(receiver, LineTo(Point(10, 26)));
137 EXPECT_CALL(receiver, ConicTo(Point(10, 15), Point(11, 15), kSqrt2Over2));
138 // RetiresOnSaturation keeps identical calls from matching each other
139 EXPECT_CALL(receiver, Close()).RetiresOnSaturation();
140
141 EXPECT_CALL(receiver, MoveTo(Point(51, 60), true));
142 EXPECT_CALL(receiver, LineTo(Point(98, 60)));
143 EXPECT_CALL(receiver, ConicTo(Point(100, 60), Point(100, 72), kSqrt2Over2));
144 EXPECT_CALL(receiver, LineTo(Point(100, 187)));
145 EXPECT_CALL(receiver,
146 ConicTo(Point(100, 200), Point(97, 200), kSqrt2Over2));
147 EXPECT_CALL(receiver, LineTo(Point(54, 200)));
148 EXPECT_CALL(receiver, ConicTo(Point(50, 200), Point(50, 186), kSqrt2Over2));
149 EXPECT_CALL(receiver, LineTo(Point(50, 71)));
150 EXPECT_CALL(receiver, ConicTo(Point(50, 60), Point(51, 60), kSqrt2Over2));
151 // RetiresOnSaturation keeps identical calls from matching each other
152 EXPECT_CALL(receiver, Close()).RetiresOnSaturation();
153 }
154
155 source.Dispatch(receiver);
156}
157
158TEST(PathSourceTest, DashedLinePathSource) {
159 DashedLinePathSource source(Point(10, 10), Point(30, 10), 5, 5);
160
161 EXPECT_FALSE(source.IsConvex());
162 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
163 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 30, 10));
164
165 ::testing::StrictMock<DlPathReceiverMock> receiver;
166
167 {
168 ::testing::Sequence sequence;
169
170 EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
171 EXPECT_CALL(receiver, LineTo(Point(15, 10)));
172 EXPECT_CALL(receiver, MoveTo(Point(20, 10), false));
173 EXPECT_CALL(receiver, LineTo(Point(25, 10)));
174 }
175
176 source.Dispatch(receiver);
177}
178
179TEST(PathSourceTest, EmptyDashedLinePathSource) {
180 DashedLinePathSource source(Point(10, 10), Point(10, 10), 5, 5);
181
182 EXPECT_FALSE(source.IsConvex());
183 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
184 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 10, 10));
185
186 ::testing::StrictMock<DlPathReceiverMock> receiver;
187
188 {
189 ::testing::Sequence sequence;
190
191 EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
192 EXPECT_CALL(receiver, LineTo(Point(10, 10)));
193 }
194
195 source.Dispatch(receiver);
196}
197
198TEST(PathSourceTest, DashedLinePathSourceZeroOffGaps) {
199 DashedLinePathSource source(Point(10, 10), Point(30, 10), 5, 0);
200
201 EXPECT_FALSE(source.IsConvex());
202 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
203 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 30, 10));
204
205 ::testing::StrictMock<DlPathReceiverMock> receiver;
206
207 {
208 ::testing::Sequence sequence;
209
210 EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
211 EXPECT_CALL(receiver, LineTo(Point(30, 10)));
212 }
213
214 source.Dispatch(receiver);
215}
216
217TEST(PathSourceTest, DashedLinePathSourceInvalidOffGaps) {
218 DashedLinePathSource source(Point(10, 10), Point(30, 10), 5, -1);
219
220 EXPECT_FALSE(source.IsConvex());
221 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
222 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 30, 10));
223
224 ::testing::StrictMock<DlPathReceiverMock> receiver;
225
226 {
227 ::testing::Sequence sequence;
228
229 EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
230 EXPECT_CALL(receiver, LineTo(Point(30, 10)));
231 }
232
233 source.Dispatch(receiver);
234}
235
236TEST(PathSourceTest, DashedLinePathSourceInvalidOnRegion) {
237 DashedLinePathSource source(Point(10, 10), Point(30, 10), -1, 5);
238
239 EXPECT_FALSE(source.IsConvex());
240 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
241 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 10, 30, 10));
242
243 ::testing::StrictMock<DlPathReceiverMock> receiver;
244
245 {
246 ::testing::Sequence sequence;
247
248 EXPECT_CALL(receiver, MoveTo(Point(10, 10), false));
249 EXPECT_CALL(receiver, LineTo(Point(30, 10)));
250 }
251
252 source.Dispatch(receiver);
253}
254
255TEST(PathSourceTest, PathTransformerRectSourceTest) {
256 Matrix matrix =
257 Matrix::MakeTranslateScale({2.0f, 3.0f, 1.0f}, {1.5f, 4.25f, 0.0f});
258 Rect rect = Rect::MakeLTRB(10, 15, 20, 30);
259 RectPathSource source(rect);
260
261 EXPECT_TRUE(source.IsConvex());
262 EXPECT_EQ(source.GetFillType(), FillType::kNonZero);
263 EXPECT_EQ(source.GetBounds(), Rect::MakeLTRB(10, 15, 20, 30));
264
265 ::testing::StrictMock<DlPathReceiverMock> mock_receiver;
266 PathTransformer receiver = PathTransformer(mock_receiver, matrix);
267
268 {
269 ::testing::Sequence sequence;
270
271 EXPECT_CALL(mock_receiver, MoveTo(Point(21.5f, 49.25f), true));
272 EXPECT_CALL(mock_receiver, LineTo(Point(41.5f, 49.25f)));
273 EXPECT_CALL(mock_receiver, LineTo(Point(41.5f, 94.25f)));
274 EXPECT_CALL(mock_receiver, LineTo(Point(21.5f, 94.25f)));
275 EXPECT_CALL(mock_receiver, LineTo(Point(21.5f, 49.25f)));
276 EXPECT_CALL(mock_receiver, Close());
277 }
278
279 source.Dispatch(receiver);
280}
281
282TEST(PathSourceTest, PathTransformerAllSegmentsTest) {
283 Matrix matrix =
284 Matrix::MakeTranslateScale({2.0f, 3.0f, 1.0f}, {1.5f, 4.25f, 0.0f});
285
286 ::testing::StrictMock<DlPathReceiverMock> mock_receiver;
287 PathTransformer receiver = PathTransformer(mock_receiver, matrix);
288
289 {
290 ::testing::Sequence sequence;
291
292 EXPECT_CALL(mock_receiver, MoveTo(Point(21.5f, 49.25f), false));
293 EXPECT_CALL(mock_receiver, LineTo(Point(41.5f, 49.25f)));
294
295 EXPECT_CALL(mock_receiver, MoveTo(Point(221.5f, 349.25f), true));
296 EXPECT_CALL(mock_receiver,
297 QuadTo(Point(241.5f, 349.25f), Point(241.5f, 394.25f)));
298 EXPECT_CALL(mock_receiver,
299 ConicTo(Point(237.5f, 409.25f), Point(231.5f, 409.25f), 5))
300 .WillOnce(Return(true));
301 EXPECT_CALL(mock_receiver,
302 ConicTo(Point(225.5f, 409.25f), Point(221.5f, 394.25f), 6))
303 .WillOnce(Return(false));
304 EXPECT_CALL(mock_receiver,
305 CubicTo(Point(211.5f, 379.25f), Point(211.5f, 364.25f),
306 Point(221.5f, 349.25f)));
307 EXPECT_CALL(mock_receiver, Close());
308 }
309
310 receiver.MoveTo(Point(10, 15), false);
311 receiver.LineTo(Point(20, 15));
312
313 receiver.MoveTo(Point(110, 115), true);
314 receiver.QuadTo(Point(120, 115), Point(120, 130));
315 EXPECT_TRUE(receiver.ConicTo(Point(118, 135), Point(115, 135), 5));
316 EXPECT_FALSE(receiver.ConicTo(Point(112, 135), Point(110, 130), 6));
317 receiver.CubicTo(Point(105, 125), Point(105, 120), Point(110, 115));
318 receiver.Close();
319}
320
321} // namespace testing
322} // namespace impeller
A PathSource that generates the various segments of a dashed line.
FillType GetFillType() const override
void Dispatch(PathReceiver &receiver) const override
Rect GetBounds() const override
bool IsConvex() const override
void Dispatch(PathReceiver &receiver) const override
FillType GetFillType() const override
A PathSource object that provides path iteration for any ellipse inscribed within a Rect bounds.
Definition path_source.h:90
void Dispatch(PathReceiver &receiver) const override
bool IsConvex() const override
Rect GetBounds() const override
FillType GetFillType() const override
void LineTo(const Point &p2) override
void QuadTo(const Point &cp, const Point &p2) override
bool ConicTo(const Point &cp, const Point &p2, Scalar weight) override
void MoveTo(const Point &p2, bool will_be_closed) override
void CubicTo(const Point &cp1, const Point &cp2, const Point &p2) override
A PathSource object that provides path iteration for any TRect.
Definition path_source.h:65
FillType GetFillType() const override
bool IsConvex() const override
Rect GetBounds() const override
void Dispatch(PathReceiver &receiver) const override
Rect GetBounds() const override
bool IsConvex() const override
void Dispatch(PathReceiver &receiver) const override
FillType GetFillType() const override
TEST(FrameTimingsRecorderTest, RecordVsync)
constexpr float kSqrt2Over2
Definition constants.h:51
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
void CubicTo(PathBuilder *builder, Scalar x1, Scalar y1, Scalar x2, Scalar y2, Scalar x3, Scalar y3)
void Close(PathBuilder *builder)
A 4x4 matrix using column-major storage.
Definition matrix.h:37
static constexpr Matrix MakeTranslateScale(const Vector3 &s, const Vector3 &t)
Definition matrix.h:113
static RoundRect MakeRectRadii(const Rect &rect, const RoundingRadii &radii)
Definition round_rect.cc:9
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129