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 
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"
12 #include "impeller/geometry/rect.h"
15 
16 namespace impeller {
17 namespace testing {
18 
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
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
Definition: round_rect.cc:155
bool IsConvex() const override
Definition: round_rect.cc:159
void Dispatch(PathReceiver &receiver) const override
Definition: round_rect.cc:163
FillType GetFillType() const override
Definition: round_rect.cc:151
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
Definition: path_source.cc:48
bool IsConvex() const override
Definition: path_source.cc:44
Rect GetBounds() const override
Definition: path_source.cc:40
FillType GetFillType() const override
Definition: path_source.cc:36
A PathSource object that provides path iteration for any TRect.
Definition: path_source.h:65
FillType GetFillType() const override
Definition: path_source.cc:15
bool IsConvex() const override
Definition: path_source.cc:11
Rect GetBounds() const override
Definition: path_source.cc:19
void Dispatch(PathReceiver &receiver) const override
Definition: path_source.cc:23
Rect GetBounds() const override
Definition: round_rect.cc:133
bool IsConvex() const override
Definition: round_rect.cc:137
void Dispatch(PathReceiver &receiver) const override
Definition: round_rect.cc:141
FillType GetFillType() const override
Definition: round_rect.cc:129
TEST(AllocationSizeTest, CanCreateTypedAllocations)
flutter::testing::DlPathReceiverMock DlPathReceiverMock
constexpr float kSqrt2Over2
Definition: constants.h:51
TPoint< Scalar > Point
Definition: point.h:327
TSize< Scalar > Size
Definition: size.h:159
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:20
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:24
void Close(PathBuilder *builder)
Definition: tessellator.cc:38
static RoundRect MakeRectRadii(const Rect &rect, const RoundingRadii &radii)
Definition: round_rect.cc:9
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
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129