@@ -153,6 +153,160 @@ TEST_P(AiksTest, CanRenderQuadraticStrokeWithInstantTurn) {
153153 ASSERT_TRUE (OpenPlaygroundHere (builder.Build ()));
154154}
155155
156+ TEST_P (AiksTest, CanRenderFilledConicPaths) {
157+ DisplayListBuilder builder;
158+ builder.Scale (GetContentScale ().x , GetContentScale ().y );
159+
160+ DlPaint paint;
161+ paint.setColor (DlColor::kRed ());
162+ paint.setDrawStyle (DlDrawStyle::kFill );
163+
164+ DlPaint reference_paint;
165+ reference_paint.setColor (DlColor::kGreen ());
166+ reference_paint.setDrawStyle (DlDrawStyle::kFill );
167+
168+ DlPathBuilder path_builder;
169+ DlPathBuilder reference_builder;
170+
171+ // weight of 1.0 is just a quadratic bezier
172+ path_builder.MoveTo (DlPoint (100 , 100 ));
173+ path_builder.ConicCurveTo (DlPoint (150 , 150 ), DlPoint (200 , 100 ), 1 .0f );
174+ reference_builder.MoveTo (DlPoint (300 , 100 ));
175+ reference_builder.QuadraticCurveTo (DlPoint (350 , 150 ), DlPoint (400 , 100 ));
176+
177+ // weight of sqrt(2)/2 is a circular section
178+ path_builder.MoveTo (DlPoint (100 , 200 ));
179+ path_builder.ConicCurveTo (DlPoint (150 , 250 ), DlPoint (200 , 200 ), kSqrt2Over2 );
180+ reference_builder.MoveTo (DlPoint (300 , 200 ));
181+ auto magic = DlPathBuilder::kArcApproximationMagic ;
182+ reference_builder.CubicCurveTo (DlPoint (300 , 200 ) + DlPoint (50 , 50 ) * magic,
183+ DlPoint (400 , 200 ) + DlPoint (-50 , 50 ) * magic,
184+ DlPoint (400 , 200 ));
185+
186+ // weight of .01 is nearly a straight line
187+ path_builder.MoveTo (DlPoint (100 , 300 ));
188+ path_builder.ConicCurveTo (DlPoint (150 , 350 ), DlPoint (200 , 300 ), 0 .01f );
189+ reference_builder.MoveTo (DlPoint (300 , 300 ));
190+ reference_builder.LineTo (DlPoint (350 , 300.5 ));
191+ reference_builder.LineTo (DlPoint (400 , 300 ));
192+
193+ // weight of 100.0 is nearly a triangle
194+ path_builder.MoveTo (DlPoint (100 , 400 ));
195+ path_builder.ConicCurveTo (DlPoint (150 , 450 ), DlPoint (200 , 400 ), 100 .0f );
196+ reference_builder.MoveTo (DlPoint (300 , 400 ));
197+ reference_builder.LineTo (DlPoint (350 , 450 ));
198+ reference_builder.LineTo (DlPoint (400 , 400 ));
199+
200+ builder.DrawPath (DlPath (path_builder), paint);
201+ builder.DrawPath (DlPath (reference_builder), reference_paint);
202+
203+ ASSERT_TRUE (OpenPlaygroundHere (builder.Build ()));
204+ }
205+
206+ TEST_P (AiksTest, CanRenderStrokedConicPaths) {
207+ DisplayListBuilder builder;
208+ builder.Scale (GetContentScale ().x , GetContentScale ().y );
209+
210+ DlPaint paint;
211+ paint.setColor (DlColor::kRed ());
212+ paint.setStrokeWidth (10 );
213+ paint.setDrawStyle (DlDrawStyle::kStroke );
214+ paint.setStrokeCap (DlStrokeCap::kRound );
215+ paint.setStrokeJoin (DlStrokeJoin::kRound );
216+
217+ DlPaint reference_paint;
218+ reference_paint.setColor (DlColor::kGreen ());
219+ reference_paint.setStrokeWidth (10 );
220+ reference_paint.setDrawStyle (DlDrawStyle::kStroke );
221+ reference_paint.setStrokeCap (DlStrokeCap::kRound );
222+ reference_paint.setStrokeJoin (DlStrokeJoin::kRound );
223+
224+ DlPathBuilder path_builder;
225+ DlPathBuilder reference_builder;
226+
227+ // weight of 1.0 is just a quadratic bezier
228+ path_builder.MoveTo (DlPoint (100 , 100 ));
229+ path_builder.ConicCurveTo (DlPoint (150 , 150 ), DlPoint (200 , 100 ), 1 .0f );
230+ reference_builder.MoveTo (DlPoint (300 , 100 ));
231+ reference_builder.QuadraticCurveTo (DlPoint (350 , 150 ), DlPoint (400 , 100 ));
232+
233+ // weight of sqrt(2)/2 is a circular section
234+ path_builder.MoveTo (DlPoint (100 , 200 ));
235+ path_builder.ConicCurveTo (DlPoint (150 , 250 ), DlPoint (200 , 200 ), kSqrt2Over2 );
236+ reference_builder.MoveTo (DlPoint (300 , 200 ));
237+ auto magic = DlPathBuilder::kArcApproximationMagic ;
238+ reference_builder.CubicCurveTo (DlPoint (300 , 200 ) + DlPoint (50 , 50 ) * magic,
239+ DlPoint (400 , 200 ) + DlPoint (-50 , 50 ) * magic,
240+ DlPoint (400 , 200 ));
241+
242+ // weight of .0 is a straight line
243+ path_builder.MoveTo (DlPoint (100 , 300 ));
244+ path_builder.ConicCurveTo (DlPoint (150 , 350 ), DlPoint (200 , 300 ), 0 .0f );
245+ reference_builder.MoveTo (DlPoint (300 , 300 ));
246+ reference_builder.LineTo (DlPoint (400 , 300 ));
247+
248+ // weight of 100.0 is nearly a triangle
249+ path_builder.MoveTo (DlPoint (100 , 400 ));
250+ path_builder.ConicCurveTo (DlPoint (150 , 450 ), DlPoint (200 , 400 ), 100 .0f );
251+ reference_builder.MoveTo (DlPoint (300 , 400 ));
252+ reference_builder.LineTo (DlPoint (350 , 450 ));
253+ reference_builder.LineTo (DlPoint (400 , 400 ));
254+
255+ builder.DrawPath (DlPath (path_builder), paint);
256+ builder.DrawPath (DlPath (reference_builder), reference_paint);
257+
258+ ASSERT_TRUE (OpenPlaygroundHere (builder.Build ()));
259+ }
260+
261+ TEST_P (AiksTest, CanRenderTightConicPath) {
262+ DisplayListBuilder builder;
263+ builder.Scale (GetContentScale ().x , GetContentScale ().y );
264+
265+ DlPaint paint;
266+ paint.setColor (DlColor::kRed ());
267+ paint.setDrawStyle (DlDrawStyle::kFill );
268+
269+ DlPaint reference_paint;
270+ reference_paint.setColor (DlColor::kGreen ());
271+ reference_paint.setDrawStyle (DlDrawStyle::kFill );
272+
273+ DlPathBuilder path_builder;
274+
275+ path_builder.MoveTo (DlPoint (100 , 100 ));
276+ path_builder.ConicCurveTo (DlPoint (150 , 450 ), DlPoint (200 , 100 ), 5 .0f );
277+
278+ DlPathBuilder reference_builder;
279+ ConicPathComponent component (DlPoint (300 , 100 ), //
280+ DlPoint (350 , 450 ), //
281+ DlPoint (400 , 100 ), //
282+ 5 .0f );
283+ reference_builder.MoveTo (component.p1 );
284+ constexpr int N = 100 ;
285+ for (int i = 1 ; i < N; i++) {
286+ reference_builder.LineTo (component.Solve (static_cast <Scalar>(i) / N));
287+ }
288+ reference_builder.LineTo (component.p2 );
289+
290+ DlPaint line_paint;
291+ line_paint.setColor (DlColor::kYellow ());
292+ line_paint.setDrawStyle (DlDrawStyle::kStroke );
293+ line_paint.setStrokeWidth (1 .0f );
294+
295+ // Draw some lines to provide a spacial reference for the curvature of
296+ // the tips of the direct rendering and the manually tessellated versions.
297+ builder.DrawLine (DlPoint (145 , 100 ), DlPoint (145 , 450 ), line_paint);
298+ builder.DrawLine (DlPoint (155 , 100 ), DlPoint (155 , 450 ), line_paint);
299+ builder.DrawLine (DlPoint (345 , 100 ), DlPoint (345 , 450 ), line_paint);
300+ builder.DrawLine (DlPoint (355 , 100 ), DlPoint (355 , 450 ), line_paint);
301+ builder.DrawLine (DlPoint (100 , 392 .5f ), DlPoint (400 , 392 .5f ), line_paint);
302+
303+ // Draw the two paths (direct and manually tessellated) on top of the lines.
304+ builder.DrawPath (DlPath (path_builder), paint);
305+ builder.DrawPath (DlPath (reference_builder), reference_paint);
306+
307+ ASSERT_TRUE (OpenPlaygroundHere (builder.Build ()));
308+ }
309+
156310TEST_P (AiksTest, CanRenderDifferencePaths) {
157311 DisplayListBuilder builder;
158312
0 commit comments