Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
aiks_dl_path_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
10
21
22namespace impeller {
23namespace testing {
24
25using namespace flutter;
26
27TEST_P(AiksTest, RotateColorFilteredPath) {
28 DisplayListBuilder builder;
31
32 DlPathBuilder arrow_stem;
33 DlPathBuilder arrow_head;
34
35 arrow_stem.MoveTo(DlPoint(120, 190)).LineTo(DlPoint(120, 50));
36 arrow_head.MoveTo(DlPoint(50, 120))
37 .LineTo(DlPoint(120, 190))
38 .LineTo(DlPoint(190, 120));
39
40 auto filter =
41 DlColorFilter::MakeBlend(DlColor::kAliceBlue(), DlBlendMode::kSrcIn);
42
43 DlPaint paint;
44 paint.setStrokeWidth(15.0);
45 paint.setStrokeCap(DlStrokeCap::kRound);
46 paint.setStrokeJoin(DlStrokeJoin::kRound);
47 paint.setDrawStyle(DlDrawStyle::kStroke);
48 paint.setColorFilter(filter);
50
51 builder.DrawPath(arrow_stem.TakePath(), paint);
52 builder.DrawPath(arrow_head.TakePath(), paint);
53
54 auto dl = builder.Build();
55 ASSERT_TRUE(OpenPlaygroundHere(dl));
56}
57
58TEST_P(AiksTest, CanRenderStrokes) {
59 DisplayListBuilder builder;
60 DlPaint paint;
61 paint.setColor(DlColor::kRed());
62 paint.setStrokeWidth(20);
63 paint.setDrawStyle(DlDrawStyle::kStroke);
64
65 builder.DrawPath(DlPath::MakeLine(DlPoint(200, 100), DlPoint(800, 100)),
66 paint);
67
68 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
69}
70
71TEST_P(AiksTest, CanRenderCurvedStrokes) {
72 DisplayListBuilder builder;
73 DlPaint paint;
74 paint.setColor(DlColor::kRed());
75 paint.setStrokeWidth(25);
76 paint.setDrawStyle(DlDrawStyle::kStroke);
77
78 builder.DrawPath(DlPath::MakeCircle(DlPoint(500, 500), 250), paint);
79
80 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
81}
82
83TEST_P(AiksTest, CanRenderThickCurvedStrokes) {
84 DisplayListBuilder builder;
85 DlPaint paint;
86 paint.setColor(DlColor::kRed());
87 paint.setStrokeWidth(100);
88 paint.setDrawStyle(DlDrawStyle::kStroke);
89
90 builder.DrawPath(DlPath::MakeCircle(DlPoint(100, 100), 50), paint);
91
92 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
93}
94
95TEST_P(AiksTest, CanRenderThinCurvedStrokes) {
96 DisplayListBuilder builder;
97 DlPaint paint;
98 paint.setColor(DlColor::kRed());
99 paint.setStrokeWidth(0.01);
100 paint.setDrawStyle(DlDrawStyle::kStroke);
101
102 builder.DrawPath(DlPath::MakeCircle(DlPoint(100, 100), 50), paint);
103
104 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
105}
106
107TEST_P(AiksTest, CanRenderStrokePathThatEndsAtSharpTurn) {
108 DisplayListBuilder builder;
109 DlPaint paint;
110 paint.setColor(DlColor::kRed());
111 paint.setStrokeWidth(200);
112 paint.setDrawStyle(DlDrawStyle::kStroke);
113
114 DlPath path = DlPath::MakeArc(DlRect::MakeXYWH(100, 100, 200, 200), //
115 DlDegrees(0), DlDegrees(90), false);
116
117 builder.DrawPath(path, paint);
118
119 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
120}
121
122TEST_P(AiksTest, CanRenderStrokePathWithCubicLine) {
123 DisplayListBuilder builder;
124
125 DlPaint paint;
126 paint.setColor(DlColor::kRed());
127 paint.setStrokeWidth(20);
128 paint.setDrawStyle(DlDrawStyle::kStroke);
129
130 DlPathBuilder path_builder;
131 path_builder.MoveTo(DlPoint(0, 200));
132 path_builder.CubicCurveTo(DlPoint(50, 400), DlPoint(350, 0),
133 DlPoint(400, 200));
134
135 builder.DrawPath(path_builder.TakePath(), paint);
136 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
137}
138
139TEST_P(AiksTest, CanRenderQuadraticStrokeWithInstantTurn) {
140 DisplayListBuilder builder;
141
142 DlPaint paint;
143 paint.setColor(DlColor::kRed());
144 paint.setStrokeWidth(50);
145 paint.setDrawStyle(DlDrawStyle::kStroke);
146 paint.setStrokeCap(DlStrokeCap::kRound);
147
148 // Should draw a diagonal pill shape. If flat on either end, the stroke is
149 // rendering wrong.
150 DlPathBuilder path_builder;
151 path_builder.MoveTo(DlPoint(250, 250));
152 path_builder.QuadraticCurveTo(DlPoint(100, 100), DlPoint(250, 250));
153
154 builder.DrawPath(path_builder.TakePath(), paint);
155
156 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
157}
158
159TEST_P(AiksTest, CanRenderFilledConicPaths) {
160 DisplayListBuilder builder;
161 builder.Scale(GetContentScale().x, GetContentScale().y);
162
163 DlPaint paint;
164 paint.setColor(DlColor::kRed());
165 paint.setDrawStyle(DlDrawStyle::kFill);
166
167 DlPaint reference_paint;
168 reference_paint.setColor(DlColor::kGreen());
169 reference_paint.setDrawStyle(DlDrawStyle::kFill);
170
171 DlPathBuilder path_builder;
172 DlPathBuilder reference_builder;
173
174 // weight of 1.0 is just a quadratic bezier
175 path_builder.MoveTo(DlPoint(100, 100));
176 path_builder.ConicCurveTo(DlPoint(150, 150), DlPoint(200, 100), 1.0f);
177 reference_builder.MoveTo(DlPoint(300, 100));
178 reference_builder.QuadraticCurveTo(DlPoint(350, 150), DlPoint(400, 100));
179
180 // weight of sqrt(2)/2 is a circular section
181 path_builder.MoveTo(DlPoint(100, 200));
182 path_builder.ConicCurveTo(DlPoint(150, 250), DlPoint(200, 200), kSqrt2Over2);
183 reference_builder.MoveTo(DlPoint(300, 200));
185 reference_builder.CubicCurveTo(DlPoint(300, 200) + DlPoint(50, 50) * magic,
186 DlPoint(400, 200) + DlPoint(-50, 50) * magic,
187 DlPoint(400, 200));
188
189 // weight of .01 is nearly a straight line
190 path_builder.MoveTo(DlPoint(100, 300));
191 path_builder.ConicCurveTo(DlPoint(150, 350), DlPoint(200, 300), 0.01f);
192 reference_builder.MoveTo(DlPoint(300, 300));
193 reference_builder.LineTo(DlPoint(350, 300.5));
194 reference_builder.LineTo(DlPoint(400, 300));
195
196 // weight of 100.0 is nearly a triangle
197 path_builder.MoveTo(DlPoint(100, 400));
198 path_builder.ConicCurveTo(DlPoint(150, 450), DlPoint(200, 400), 100.0f);
199 reference_builder.MoveTo(DlPoint(300, 400));
200 reference_builder.LineTo(DlPoint(350, 450));
201 reference_builder.LineTo(DlPoint(400, 400));
202
203 builder.DrawPath(path_builder.TakePath(), paint);
204 builder.DrawPath(reference_builder.TakePath(), reference_paint);
205
206 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
207}
208
209TEST_P(AiksTest, CanRenderStrokedConicPaths) {
210 DisplayListBuilder builder;
211 builder.Scale(GetContentScale().x, GetContentScale().y);
212
213 DlPaint paint;
214 paint.setColor(DlColor::kRed());
215 paint.setStrokeWidth(10);
216 paint.setDrawStyle(DlDrawStyle::kStroke);
217 paint.setStrokeCap(DlStrokeCap::kRound);
218 paint.setStrokeJoin(DlStrokeJoin::kRound);
219
220 DlPaint reference_paint;
221 reference_paint.setColor(DlColor::kGreen());
222 reference_paint.setStrokeWidth(10);
223 reference_paint.setDrawStyle(DlDrawStyle::kStroke);
224 reference_paint.setStrokeCap(DlStrokeCap::kRound);
225 reference_paint.setStrokeJoin(DlStrokeJoin::kRound);
226
227 DlPathBuilder path_builder;
228 DlPathBuilder reference_builder;
229
230 // weight of 1.0 is just a quadratic bezier
231 path_builder.MoveTo(DlPoint(100, 100));
232 path_builder.ConicCurveTo(DlPoint(150, 150), DlPoint(200, 100), 1.0f);
233 reference_builder.MoveTo(DlPoint(300, 100));
234 reference_builder.QuadraticCurveTo(DlPoint(350, 150), DlPoint(400, 100));
235
236 // weight of sqrt(2)/2 is a circular section
237 path_builder.MoveTo(DlPoint(100, 200));
238 path_builder.ConicCurveTo(DlPoint(150, 250), DlPoint(200, 200), kSqrt2Over2);
239 reference_builder.MoveTo(DlPoint(300, 200));
241 reference_builder.CubicCurveTo(DlPoint(300, 200) + DlPoint(50, 50) * magic,
242 DlPoint(400, 200) + DlPoint(-50, 50) * magic,
243 DlPoint(400, 200));
244
245 // weight of .0 is a straight line
246 path_builder.MoveTo(DlPoint(100, 300));
247 path_builder.ConicCurveTo(DlPoint(150, 350), DlPoint(200, 300), 0.0f);
248 reference_builder.MoveTo(DlPoint(300, 300));
249 reference_builder.LineTo(DlPoint(400, 300));
250
251 // weight of 100.0 is nearly a triangle
252 path_builder.MoveTo(DlPoint(100, 400));
253 path_builder.ConicCurveTo(DlPoint(150, 450), DlPoint(200, 400), 100.0f);
254 reference_builder.MoveTo(DlPoint(300, 400));
255 reference_builder.LineTo(DlPoint(350, 450));
256 reference_builder.LineTo(DlPoint(400, 400));
257
258 builder.DrawPath(path_builder.TakePath(), paint);
259 builder.DrawPath(reference_builder.TakePath(), reference_paint);
260
261 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
262}
263
264TEST_P(AiksTest, HairlinePath) {
265 Scalar scale = 1.f;
266 Scalar rotation = 0.f;
267 Scalar offset = 0.f;
268 Scalar width = 0.f;
269 auto callback = [&]() -> sk_sp<DisplayList> {
270 if (AiksTest::ImGuiBegin("Controls", nullptr,
271 ImGuiWindowFlags_AlwaysAutoResize)) {
272 ImGui::SliderFloat("Scale", &scale, 0, 6);
273 ImGui::SliderFloat("Rotate", &rotation, 0, 90);
274 ImGui::SliderFloat("Offset", &offset, 0, 2);
275 ImGui::SliderFloat("Width", &width, 0, 2);
276 ImGui::End();
277 }
278
279 DisplayListBuilder builder;
280 builder.Scale(GetContentScale().x, GetContentScale().y);
281 builder.DrawPaint(DlPaint(DlColor(0xff111111)));
282
283 DlPaint paint;
284 paint.setStrokeWidth(width);
285 paint.setColor(DlColor::kWhite());
286 paint.setStrokeCap(DlStrokeCap::kRound);
287 paint.setStrokeJoin(DlStrokeJoin::kRound);
288 paint.setDrawStyle(DlDrawStyle::kStroke);
289
290 builder.Translate(512, 384);
291 builder.Scale(scale, scale);
292 builder.Rotate(rotation);
293 builder.Translate(-512, -384 + offset);
294
295 for (int i = 0; i < 5; ++i) {
296 Scalar yoffset = i * 25.25f + 300.f;
297 DlPathBuilder path_builder;
298
299 path_builder.MoveTo(DlPoint(100, yoffset));
300 path_builder.LineTo(DlPoint(924, yoffset));
301 builder.DrawPath(path_builder.TakePath(), paint);
302 }
303
304 return builder.Build();
305 };
306
307 ASSERT_TRUE(OpenPlaygroundHere(callback));
308}
309
310TEST_P(AiksTest, HairlineDrawLine) {
311 Scalar scale = 1.f;
312 Scalar rotation = 0.f;
313 Scalar offset = 0.f;
314 auto callback = [&]() -> sk_sp<DisplayList> {
315 if (AiksTest::ImGuiBegin("Controls", nullptr,
316 ImGuiWindowFlags_AlwaysAutoResize)) {
317 ImGui::SliderFloat("Scale", &scale, 0, 6);
318 ImGui::SliderFloat("Rotate", &rotation, 0, 90);
319 ImGui::SliderFloat("Offset", &offset, 0, 2);
320 ImGui::End();
321 }
322
323 DisplayListBuilder builder;
324 builder.Scale(GetContentScale().x, GetContentScale().y);
325 builder.DrawPaint(DlPaint(DlColor(0xff111111)));
326
327 DlPaint paint;
328 paint.setStrokeWidth(0.f);
329 paint.setColor(DlColor::kWhite());
330
331 builder.Translate(512, 384);
332 builder.Scale(scale, scale);
333 builder.Rotate(rotation);
334 builder.Translate(-512, -384 + offset);
335
336 for (int i = 0; i < 5; ++i) {
337 Scalar yoffset = i * 25.25f + 300.f;
338
339 builder.DrawLine(DlPoint(100, yoffset), DlPoint(924, yoffset), paint);
340 }
341
342 return builder.Build();
343 };
344
345 ASSERT_TRUE(OpenPlaygroundHere(callback));
346}
347
348TEST_P(AiksTest, CanRenderTightConicPath) {
349 DisplayListBuilder builder;
350 builder.Scale(GetContentScale().x, GetContentScale().y);
351
352 DlPaint paint;
353 paint.setColor(DlColor::kRed());
354 paint.setDrawStyle(DlDrawStyle::kFill);
355
356 DlPaint reference_paint;
357 reference_paint.setColor(DlColor::kGreen());
358 reference_paint.setDrawStyle(DlDrawStyle::kFill);
359
360 DlPathBuilder path_builder;
361
362 path_builder.MoveTo(DlPoint(100, 100));
363 path_builder.ConicCurveTo(DlPoint(150, 450), DlPoint(200, 100), 5.0f);
364
365 DlPathBuilder reference_builder;
366 PathTessellator::Conic component{DlPoint(300, 100), //
367 DlPoint(350, 450), //
368 DlPoint(400, 100), //
369 5.0f};
370 reference_builder.MoveTo(component.p1);
371 constexpr int N = 100;
372 for (int i = 1; i < N; i++) {
373 reference_builder.LineTo(component.Solve(static_cast<Scalar>(i) / N));
374 }
375 reference_builder.LineTo(component.p2);
376
377 DlPaint line_paint;
378 line_paint.setColor(DlColor::kYellow());
379 line_paint.setDrawStyle(DlDrawStyle::kStroke);
380 line_paint.setStrokeWidth(1.0f);
381
382 // Draw some lines to provide a spacial reference for the curvature of
383 // the tips of the direct rendering and the manually tessellated versions.
384 builder.DrawLine(DlPoint(145, 100), DlPoint(145, 450), line_paint);
385 builder.DrawLine(DlPoint(155, 100), DlPoint(155, 450), line_paint);
386 builder.DrawLine(DlPoint(345, 100), DlPoint(345, 450), line_paint);
387 builder.DrawLine(DlPoint(355, 100), DlPoint(355, 450), line_paint);
388 builder.DrawLine(DlPoint(100, 392.5f), DlPoint(400, 392.5f), line_paint);
389
390 // Draw the two paths (direct and manually tessellated) on top of the lines.
391 builder.DrawPath(path_builder.TakePath(), paint);
392 builder.DrawPath(reference_builder.TakePath(), reference_paint);
393
394 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
395}
396
397TEST_P(AiksTest, CanRenderDifferencePaths) {
398 DisplayListBuilder builder;
399
400 DlPaint paint;
401 paint.setColor(DlColor::kRed());
402
403 RoundingRadii radii = {
404 .top_left = {50, 25},
405 .top_right = {25, 50},
406 .bottom_left = {25, 50},
407 .bottom_right = {50, 25},
408 };
409 DlPathBuilder path_builder;
410 DlRoundRect rrect =
411 DlRoundRect::MakeRectRadii(DlRect::MakeXYWH(100, 100, 200, 200), radii);
412 // We use the factory method to convert the rrect and circle to a path so
413 // that they use the legacy conics for legacy golden output.
414 path_builder.AddPath(DlPath::MakeRoundRect(rrect));
415 path_builder.AddPath(DlPath::MakeCircle(DlPoint(200, 200), 50));
416 path_builder.SetFillType(DlPathFillType::kOdd);
417 DlPath path = path_builder.TakePath();
418
419 builder.DrawImage(
420 DlImageImpeller::Make(CreateTextureForFixture("boston.jpg")),
421 DlPoint{10, 10}, {});
422 builder.DrawPath(path, paint);
423
424 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
425}
426
427// Regression test for https://github.com/flutter/flutter/issues/134816.
428//
429// It should be possible to draw 3 lines, and not have an implicit close path.
430TEST_P(AiksTest, CanDrawAnOpenPath) {
431 DisplayListBuilder builder;
432
433 // Starting at (50, 50), draw lines from:
434 // 1. (50, height)
435 // 2. (width, height)
436 // 3. (width, 50)
437 DlPathBuilder path_builder;
438 path_builder.MoveTo(DlPoint(50, 50));
439 path_builder.LineTo(DlPoint(50, 100));
440 path_builder.LineTo(DlPoint(100, 100));
441 path_builder.LineTo(DlPoint(100, 50));
442
443 DlPaint paint;
444 paint.setColor(DlColor::kRed());
445 paint.setDrawStyle(DlDrawStyle::kStroke);
446 paint.setStrokeWidth(10);
447
448 builder.DrawPath(path_builder.TakePath(), paint);
449
450 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
451}
452
453TEST_P(AiksTest, CanDrawAnOpenPathThatIsntARect) {
454 DisplayListBuilder builder;
455
456 // Draw a stroked path that is explicitly closed to verify
457 // It doesn't become a rectangle.
458 DlPathBuilder path_builder;
459 path_builder.MoveTo(DlPoint(50, 50));
460 path_builder.LineTo(DlPoint(520, 120));
461 path_builder.LineTo(DlPoint(300, 310));
462 path_builder.LineTo(DlPoint(100, 50));
463 path_builder.Close();
464
465 DlPaint paint;
466 paint.setColor(DlColor::kRed());
467 paint.setDrawStyle(DlDrawStyle::kStroke);
468 paint.setStrokeWidth(10);
469
470 builder.DrawPath(path_builder.TakePath(), paint);
471
472 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
473}
474
475TEST_P(AiksTest, SolidStrokesRenderCorrectly) {
476 // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
477 auto callback = [&]() -> sk_sp<DisplayList> {
478 static Color color = Color::Black().WithAlpha(0.5);
479 static float scale = 3;
480 static bool add_circle_clip = true;
481
482 if (AiksTest::ImGuiBegin("Controls", nullptr,
483 ImGuiWindowFlags_AlwaysAutoResize)) {
484 ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
485 ImGui::SliderFloat("Scale", &scale, 0, 6);
486 ImGui::Checkbox("Circle clip", &add_circle_clip);
487 ImGui::End();
488 }
489
490 DisplayListBuilder builder;
491 builder.Scale(GetContentScale().x, GetContentScale().y);
492 DlPaint paint;
493
494 paint.setColor(DlColor::kWhite());
495 builder.DrawPaint(paint);
496
497 paint.setColor(
498 DlColor::ARGB(color.alpha, color.red, color.green, color.blue));
499 paint.setDrawStyle(DlDrawStyle::kStroke);
500 paint.setStrokeWidth(10);
501
502 DlPathBuilder path_builder;
503 path_builder.MoveTo(DlPoint(20, 20));
504 path_builder.QuadraticCurveTo(DlPoint(60, 20), DlPoint(60, 60));
505 path_builder.Close();
506 path_builder.MoveTo(DlPoint(60, 20));
507 path_builder.QuadraticCurveTo(DlPoint(60, 60), DlPoint(20, 60));
508 DlPath path = path_builder.TakePath();
509
510 builder.Scale(scale, scale);
511
512 if (add_circle_clip) {
513 static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
514 Color::Red());
515 static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
516 Color::Red());
517 auto [handle_a, handle_b] =
518 DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
519
520 Matrix screen_to_canvas = builder.GetMatrix();
521 if (!screen_to_canvas.IsInvertible()) {
522 return nullptr;
523 }
524 screen_to_canvas = screen_to_canvas.Invert();
525
526 Point point_a = screen_to_canvas * handle_a;
527 Point point_b = screen_to_canvas * handle_b;
528
529 Point middle = point_a + point_b;
530 middle *= GetContentScale().x / 2;
531
532 auto radius = point_a.GetDistance(middle);
533
534 builder.ClipPath(DlPath::MakeCircle(middle, radius));
535 }
536
537 for (auto join :
538 {DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
539 paint.setStrokeJoin(join);
540 for (auto cap :
541 {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
542 paint.setStrokeCap(cap);
543 builder.DrawPath(path, paint);
544 builder.Translate(80, 0);
545 }
546 builder.Translate(-240, 60);
547 }
548
549 return builder.Build();
550 };
551
552 ASSERT_TRUE(OpenPlaygroundHere(callback));
553}
554
555TEST_P(AiksTest, DrawLinesRenderCorrectly) {
556 DisplayListBuilder builder;
557 builder.Scale(GetContentScale().x, GetContentScale().y);
558
559 DlPaint paint;
560 paint.setColor(DlColor::kBlue());
561 paint.setStrokeWidth(10);
562
563 auto draw = [&builder](DlPaint& paint) {
564 for (auto cap :
565 {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
566 paint.setStrokeCap(cap);
567 DlPoint origin = {100, 100};
568 builder.DrawLine(DlPoint(150, 100), DlPoint(250, 100), paint);
569 for (int d = 15; d < 90; d += 15) {
571 Point origin = {100, 100};
572 Point p0 = {50, 0};
573 Point p1 = {150, 0};
574 auto a = origin + m * p0;
575 auto b = origin + m * p1;
576
577 builder.DrawLine(a, b, paint);
578 }
579 builder.DrawLine(DlPoint(100, 150), DlPoint(100, 250), paint);
580 builder.DrawCircle(origin, 35, paint);
581
582 builder.DrawLine(DlPoint(250, 250), DlPoint(250, 250), paint);
583
584 builder.Translate(250, 0);
585 }
586 builder.Translate(-750, 250);
587 };
588
589 std::vector<DlColor> colors = {
590 DlColor::ARGB(1, 0x1f / 255.0, 0.0, 0x5c / 255.0),
591 DlColor::ARGB(1, 0x5b / 255.0, 0.0, 0x60 / 255.0),
592 DlColor::ARGB(1, 0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0),
593 DlColor::ARGB(1, 0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0),
594 DlColor::ARGB(1, 0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0),
595 DlColor::ARGB(1, 0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0),
596 DlColor::ARGB(1, 0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0)};
597 std::vector<Scalar> stops = {
598 0.0,
599 (1.0 / 6.0) * 1,
600 (1.0 / 6.0) * 2,
601 (1.0 / 6.0) * 3,
602 (1.0 / 6.0) * 4,
603 (1.0 / 6.0) * 5,
604 1.0,
605 };
606
608 CreateTextureForFixture("airplane.jpg",
609 /*enable_mipmapping=*/true));
610
611 draw(paint);
612
613 paint.setColorSource(DlColorSource::MakeRadial({100, 100}, 200, stops.size(),
614 colors.data(), stops.data(),
615 DlTileMode::kMirror));
616 draw(paint);
617
618 DlMatrix matrix = DlMatrix::MakeTranslation({-150, 75});
620 texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
621 DlImageSampling::kMipmapLinear, &matrix));
622 draw(paint);
623
624 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
625}
626
627// The goal of this test is to show that scaling the lines doesn't also scale
628// the antialiasing. The amount of blurring should be the same for both
629// horizontal lines.
630TEST_P(AiksTest, ScaleExperimentAntialiasLines) {
631 Scalar scale = 5.0;
632 Scalar line_width = 10.f;
633 auto callback = [&]() -> sk_sp<DisplayList> {
634 if (AiksTest::ImGuiBegin("Controls", nullptr,
635 ImGuiWindowFlags_AlwaysAutoResize)) {
636 ImGui::SliderFloat("Scale", &scale, 0.001, 5);
637 ImGui::SliderFloat("Width", &line_width, 1, 20);
638
639 ImGui::End();
640 }
641 DisplayListBuilder builder;
642 builder.Scale(GetContentScale().x, GetContentScale().y);
643
644 builder.DrawPaint(DlPaint(DlColor(0xff111111)));
645
646 {
647 DlPaint paint;
649 paint.setStrokeWidth(line_width);
650
651 builder.DrawLine(DlPoint(100, 100), DlPoint(350, 100), paint);
652 builder.DrawLine(DlPoint(100, 100), DlPoint(350, 150), paint);
653
654 builder.Save();
655 builder.Translate(100, 300);
656 builder.Scale(scale, scale);
657 builder.Translate(-100, -300);
658 builder.DrawLine(DlPoint(100, 300), DlPoint(350, 300), paint);
659 builder.DrawLine(DlPoint(100, 300), DlPoint(350, 450), paint);
660 builder.Restore();
661 }
662
663 {
664 DlPaint paint;
666 paint.setStrokeWidth(2.0);
667
668 builder.Save();
669 builder.Translate(100, 500);
670 builder.Scale(0.2, 0.2);
671 builder.Translate(-100, -500);
672 builder.DrawLine(DlPoint(100, 500), DlPoint(350, 500), paint);
673 builder.DrawLine(DlPoint(100, 500), DlPoint(350, 650), paint);
674 builder.Restore();
675 }
676
677 return builder.Build();
678 };
679 ASSERT_TRUE(OpenPlaygroundHere(callback));
680}
681
682TEST_P(AiksTest, HexagonExperimentAntialiasLines) {
683 float scale = 5.0f;
684 float line_width = 10.f;
685 float rotation = 0.f;
686
687 auto callback = [&]() -> sk_sp<DisplayList> {
688 if (AiksTest::ImGuiBegin("Controls", nullptr,
689 ImGuiWindowFlags_AlwaysAutoResize)) {
690 // Use ImGui::SliderFloat for consistency
691 ImGui::SliderFloat("Scale", &scale, 0.001f, 5.0f);
692 ImGui::SliderFloat("Width", &line_width, 1.0f, 20.0f);
693 ImGui::SliderFloat("Rotation", &rotation, 0.0f, 180.0f);
694
695 ImGui::End();
696 }
697 DisplayListBuilder builder;
698 builder.Scale(static_cast<float>(GetContentScale().x),
699 static_cast<float>(GetContentScale().y));
700
701 builder.DrawPaint(DlPaint(DlColor(0xff111111))); // Background
702
703 {
704 DlPaint hex_paint;
705 hex_paint.setColor(
706 DlColor::kGreen()); // Changed color to Red for visibility
707 hex_paint.setStrokeWidth(line_width); // Use the interactive width
708
709 float cx = 512.0f; // Center X
710 float cy = 384.0f; // Center Y
711 float r = 80.0f; // Radius (distance from center to vertex)
712
713 float r_sin60 = r * std::sqrt(3.0f) / 2.0f;
714 float r_cos60 = r / 2.0f;
715
716 DlPoint v0 = DlPoint(cx + r, cy); // Right vertex
717 DlPoint v1 = DlPoint(cx + r_cos60, cy - r_sin60); // Top-right vertex
718 DlPoint v2 = DlPoint(
719 cx - r_cos60,
720 cy - r_sin60); // Top-left vertex (v1-v2 is top horizontal side)
721 DlPoint v3 = DlPoint(cx - r, cy); // Left vertex
722 DlPoint v4 = DlPoint(cx - r_cos60, cy + r_sin60); // Bottom-left vertex
723 DlPoint v5 =
724 DlPoint(cx + r_cos60, cy + r_sin60); // Bottom-right vertex (v4-v5 is
725 // bottom horizontal side)
726
727 builder.Translate(cx, cy);
728 builder.Scale(scale, scale);
729 builder.Rotate(rotation);
730 builder.Translate(-cx, -cy);
731
732 builder.DrawLine(v0, v1, hex_paint);
733 builder.DrawLine(v1, v2, hex_paint); // Top side
734 builder.DrawLine(v2, v3, hex_paint);
735 builder.DrawLine(v3, v4, hex_paint);
736 builder.DrawLine(v4, v5, hex_paint); // Bottom side
737 builder.DrawLine(v5, v0, hex_paint); // Close the hexagon
738 }
739
740 return builder.Build();
741 };
742 ASSERT_TRUE(OpenPlaygroundHere(callback));
743}
744
745TEST_P(AiksTest, SimpleExperimentAntialiasLines) {
746 DisplayListBuilder builder;
747 builder.Scale(GetContentScale().x, GetContentScale().y);
748
749 builder.DrawPaint(DlPaint(DlColor(0xff111111)));
750
751 DlPaint paint;
753 paint.setStrokeWidth(10);
754
755 auto draw = [&builder](DlPaint& paint) {
756 for (auto cap :
757 {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
758 paint.setStrokeCap(cap);
759 DlPoint origin = {100, 100};
760 builder.DrawLine(DlPoint(150, 100), DlPoint(250, 100), paint);
761 for (int d = 15; d < 90; d += 15) {
763 Point origin = {100, 100};
764 Point p0 = {50, 0};
765 Point p1 = {150, 0};
766 auto a = origin + m * p0;
767 auto b = origin + m * p1;
768
769 builder.DrawLine(a, b, paint);
770 }
771 builder.DrawLine(DlPoint(100, 150), DlPoint(100, 250), paint);
772 builder.DrawCircle(origin, 35, paint);
773
774 builder.DrawLine(DlPoint(250, 250), DlPoint(250, 250), paint);
775
776 builder.Translate(250, 0);
777 }
778 builder.Translate(-750, 250);
779 };
780
781 draw(paint);
782
783 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
784}
785
786TEST_P(AiksTest, DrawRectStrokesRenderCorrectly) {
787 DisplayListBuilder builder;
788 DlPaint paint;
789 paint.setColor(DlColor::kRed());
790 paint.setDrawStyle(DlDrawStyle::kStroke);
791 paint.setStrokeWidth(10);
792
793 builder.Translate(100, 100);
794 builder.DrawPath(DlPath::MakeRect(DlRect::MakeSize(DlSize(100, 100))), paint);
795
796 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
797}
798
799TEST_P(AiksTest, DrawRectStrokesWithBevelJoinRenderCorrectly) {
800 DisplayListBuilder builder;
801 DlPaint paint;
802 paint.setColor(DlColor::kRed());
803 paint.setDrawStyle(DlDrawStyle::kStroke);
804 paint.setStrokeWidth(10);
805 paint.setStrokeJoin(DlStrokeJoin::kBevel);
806
807 builder.Translate(100, 100);
808 builder.DrawPath(DlPath::MakeRect(DlRect::MakeSize(DlSize(100, 100))), paint);
809
810 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
811}
812
813TEST_P(AiksTest, CanDrawMultiContourConvexPath) {
814 DlPathBuilder path_builder;
815 for (auto i = 0; i < 10; i++) {
816 if (i % 2 == 0) {
817 // We use the factory method to convert the circle to a path so that it
818 // uses the legacy conics for legacy golden output.
819 DlPath circle =
820 DlPath::MakeCircle(DlPoint(100 + 50 * i, 100 + 50 * i), 100);
821 path_builder.AddPath(circle);
822 path_builder.Close();
823 } else {
824 path_builder.MoveTo(DlPoint(100.f + 50.f * i - 100, 100.f + 50.f * i));
825 path_builder.LineTo(DlPoint(100.f + 50.f * i, 100.f + 50.f * i - 100));
826 path_builder.LineTo(DlPoint(100.f + 50.f * i - 100, //
827 100.f + 50.f * i - 100));
828 path_builder.Close();
829 }
830 }
831 DlPath path = path_builder.TakePath();
832
833 DisplayListBuilder builder;
834 DlPaint paint;
835 paint.setColor(DlColor::kRed().withAlpha(102));
836 builder.DrawPath(path, paint);
837
838 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
839}
840
841TEST_P(AiksTest, ArcWithZeroSweepAndBlur) {
842 DisplayListBuilder builder;
843 builder.Scale(GetContentScale().x, GetContentScale().y);
844
845 DlPaint paint;
846 paint.setColor(DlColor::kRed());
847
848 std::vector<DlColor> colors = {DlColor::RGBA(1.0, 0.0, 0.0, 1.0),
849 DlColor::RGBA(0.0, 0.0, 0.0, 1.0)};
850 std::vector<Scalar> stops = {0.0, 1.0};
851
852 paint.setColorSource(
853 DlColorSource::MakeSweep({100, 100}, 45, 135, stops.size(), colors.data(),
854 stops.data(), DlTileMode::kMirror));
855 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
856
857 DlPathBuilder path_builder;
858 path_builder.AddArc(DlRect::MakeXYWH(10, 10, 100, 100), //
859 DlDegrees(0), DlDegrees(0));
860 builder.DrawPath(path_builder.TakePath(), paint);
861
862 // Check that this empty picture can be created without crashing.
863 builder.Build();
864}
865
866TEST_P(AiksTest, CanRenderClips) {
867 DisplayListBuilder builder;
868 DlPaint paint;
870
871 builder.ClipPath(DlPath::MakeRect(DlRect::MakeXYWH(0, 0, 500, 500)));
872 builder.DrawPath(DlPath::MakeCircle(DlPoint(500, 500), 250), paint);
873
874 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
875}
876
877TEST_P(AiksTest, FatStrokeArc) {
878 DlScalar stroke_width = 300;
879 DlScalar aspect = 1.0;
880 DlScalar start_angle = 0;
881 DlScalar end_angle = 90;
882 auto callback = [&]() -> sk_sp<DisplayList> {
883 if (AiksTest::ImGuiBegin("Controls", nullptr,
884 ImGuiWindowFlags_AlwaysAutoResize)) {
885 ImGui::SliderFloat("Stroke Width", &stroke_width, 1, 300);
886 ImGui::SliderFloat("Aspect", &aspect, 0.5, 2.0);
887 ImGui::SliderFloat("Start Angle", &start_angle, 0, 360);
888 ImGui::SliderFloat("End Angle", &end_angle, 0, 360);
889 ImGui::End();
890 }
891
892 DisplayListBuilder builder;
893 DlPaint grey_paint;
894 grey_paint.setColor(DlColor(0xff111111));
895 builder.DrawPaint(grey_paint);
896
897 DlPaint white_paint;
898 white_paint.setColor(DlColor::kWhite());
899 white_paint.setStrokeWidth(stroke_width);
900 white_paint.setDrawStyle(DlDrawStyle::kStroke);
901 DlPaint red_paint;
902 red_paint.setColor(DlColor::kRed());
903
904 Rect rect = Rect::MakeXYWH(100, 100, 100, aspect * 100);
905 builder.DrawRect(rect, red_paint);
906 builder.DrawArc(rect, start_angle, end_angle,
907 /*useCenter=*/false, white_paint);
908 DlScalar frontier = rect.GetRight() + stroke_width / 2.0;
909 builder.DrawLine(Point(frontier, 0), Point(frontier, 150), red_paint);
910
911 return builder.Build();
912 };
913 ASSERT_TRUE(OpenPlaygroundHere(callback));
914}
915
916TEST_P(AiksTest, CanRenderOverlappingMultiContourPath) {
917 DisplayListBuilder builder;
918
919 DlPaint paint;
920 paint.setColor(DlColor::kRed());
921
922 RoundingRadii radii = {
923 .top_left = DlSize(50, 50),
924 .top_right = DlSize(50, 50),
925 .bottom_left = DlSize(50, 50),
926 .bottom_right = DlSize(50, 50),
927 };
928
929 const Scalar kTriangleHeight = 100;
931 DlRect::MakeCircleBounds({0, 0}, kTriangleHeight * 0.5f), radii);
932 // We use the factory method to convert the rrect to a path so that it
933 // uses the legacy conics for legacy golden output.
934 DlPath rrect_path = DlPath::MakeRoundRect(rrect);
935
936 builder.Translate(200, 200);
937 // Form a path similar to the Material drop slider value indicator. Both
938 // shapes should render identically side-by-side.
939 {
940 DlPathBuilder path_builder;
941 path_builder.MoveTo(DlPoint(0, kTriangleHeight));
942 path_builder.LineTo(DlPoint(-kTriangleHeight / 2.0f, 0));
943 path_builder.LineTo(DlPoint(kTriangleHeight / 2.0f, 0));
944 path_builder.Close();
945 path_builder.AddPath(rrect_path);
946
947 builder.DrawPath(path_builder.TakePath(), paint);
948 }
949 builder.Translate(100, 0);
950
951 {
952 DlPathBuilder path_builder;
953 path_builder.MoveTo(DlPoint(0, kTriangleHeight));
954 path_builder.LineTo(DlPoint(-kTriangleHeight / 2.0f, 0));
955 path_builder.LineTo(DlPoint(0, -10));
956 path_builder.LineTo(DlPoint(kTriangleHeight / 2.0f, 0));
957 path_builder.Close();
958 path_builder.AddPath(rrect_path);
959
960 builder.DrawPath(path_builder.TakePath(), paint);
961 }
962
963 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
964}
965
966TEST_P(AiksTest, TwoContourPathWithSinglePointContour) {
967 DisplayListBuilder builder;
968
969 DlPaint paint;
970 paint.setColor(DlColor::kRed());
971 paint.setDrawStyle(DlDrawStyle::kStroke);
972 paint.setStrokeWidth(15.0);
973 paint.setStrokeCap(DlStrokeCap::kRound);
974
975 DlPathBuilder path_builder;
976 path_builder.MoveTo(DlPoint(100, 100));
977 path_builder.LineTo(DlPoint(150, 150));
978 path_builder.MoveTo(DlPoint(200, 200));
979 path_builder.LineTo(DlPoint(200, 200));
980
981 builder.DrawPath(path_builder.TakePath(), paint);
982
983 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
984}
985
986TEST_P(AiksTest, StrokeCapsAndJoins) {
987 DisplayListBuilder builder;
988 builder.Scale(GetContentScale().x, GetContentScale().y);
989
990 builder.Translate(100, 0);
991
992 builder.Save();
993 for (auto cap : std::vector<DlStrokeCap>{
994 DlStrokeCap::kButt, DlStrokeCap::kRound, DlStrokeCap::kSquare}) {
995 DlPathBuilder path_builder;
996 path_builder.MoveTo({20, 50});
997 path_builder.LineTo({50, 50});
998 path_builder.MoveTo({120, 50});
999 path_builder.LineTo({120, 80});
1000 path_builder.MoveTo({180, 50});
1001 path_builder.LineTo({180, 50});
1002 DlPath path = path_builder.TakePath();
1003
1004 DlPaint paint;
1005 paint.setColor(DlColor::kRed());
1006 paint.setDrawStyle(DlDrawStyle::kStroke);
1007 paint.setStrokeWidth(20.0f);
1008 paint.setStrokeCap(cap);
1009 paint.setStrokeJoin(DlStrokeJoin::kBevel);
1010
1011 builder.DrawPath(path, paint);
1012
1013 paint.setColor(DlColor::kYellow());
1014 paint.setStrokeWidth(1.0f);
1015 paint.setStrokeCap(DlStrokeCap::kButt);
1016
1017 builder.DrawPath(path, paint);
1018
1019 builder.Translate(250, 0);
1020 }
1021 builder.Restore();
1022
1023 builder.Translate(0, 100);
1024
1025 builder.Save();
1026 for (auto join : std::vector<DlStrokeJoin>{
1027 DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
1028 DlPathBuilder path_builder;
1029 path_builder.MoveTo({20, 50}); // 0 degree right turn
1030 path_builder.LineTo({50, 50});
1031 path_builder.LineTo({80, 50});
1032 path_builder.MoveTo({20, 150}); // 90 degree right turn
1033 path_builder.LineTo({50, 150});
1034 path_builder.LineTo({50, 180});
1035 path_builder.MoveTo({20, 250}); // 45 degree right turn
1036 path_builder.LineTo({50, 250});
1037 path_builder.LineTo({70, 270});
1038 path_builder.MoveTo({20, 350}); // 135 degree right turn
1039 path_builder.LineTo({50, 350});
1040 path_builder.LineTo({30, 370});
1041 path_builder.MoveTo({20, 450}); // 180 degree right turn
1042 path_builder.LineTo({50, 450});
1043 path_builder.LineTo({20, 450});
1044 path_builder.MoveTo({120, 80}); // 0 degree left turn
1045 path_builder.LineTo({150, 80});
1046 path_builder.LineTo({180, 80});
1047 path_builder.MoveTo({120, 180}); // 90 degree left turn
1048 path_builder.LineTo({150, 180});
1049 path_builder.LineTo({150, 150});
1050 path_builder.MoveTo({120, 280}); // 45 degree left turn
1051 path_builder.LineTo({150, 280});
1052 path_builder.LineTo({170, 260});
1053 path_builder.MoveTo({120, 380}); // 135 degree left turn
1054 path_builder.LineTo({150, 380});
1055 path_builder.LineTo({130, 360});
1056 path_builder.MoveTo({120, 480}); // 180 degree left turn
1057 path_builder.LineTo({150, 480});
1058 path_builder.LineTo({120, 480});
1059 DlPath path = path_builder.TakePath();
1060
1061 DlPaint paint;
1062
1063 paint.setColor(DlColor::kRed());
1064 paint.setDrawStyle(DlDrawStyle::kStroke);
1065 paint.setStrokeWidth(20.0f);
1066 paint.setStrokeCap(DlStrokeCap::kSquare);
1067 paint.setStrokeJoin(join);
1068 builder.DrawPath(path, paint);
1069
1070 paint.setColor(DlColor::kYellow());
1071 paint.setStrokeWidth(1.0f);
1072 paint.setStrokeCap(DlStrokeCap::kButt);
1073 builder.DrawPath(path, paint);
1074
1075 builder.Translate(250, 0);
1076 }
1077 builder.Restore();
1078
1079 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1080}
1081
1082TEST_P(AiksTest, BlurredCircleWithStrokeWidth) {
1083 DisplayListBuilder builder;
1084 DlPaint paint;
1085 paint.setColor(DlColor::kGreen());
1086 paint.setDrawStyle(DlDrawStyle::kStroke);
1087 paint.setStrokeWidth(30);
1088 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 5));
1089
1090 builder.DrawCircle(DlPoint(200, 200), 100, paint);
1091
1092 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1093}
1094
1095} // namespace testing
1096} // namespace impeller
void DrawArc(const DlRect &bounds, DlScalar start, DlScalar sweep, bool useCenter, const DlPaint &paint) override
void DrawImage(const sk_sp< DlImage > &image, const DlPoint &point, DlImageSampling sampling, const DlPaint *paint=nullptr) override
DlMatrix GetMatrix() const override
Definition dl_builder.h:111
void DrawCircle(const DlPoint &center, DlScalar radius, const DlPaint &paint) override
void DrawLine(const DlPoint &p0, const DlPoint &p1, const DlPaint &paint) override
void Rotate(DlScalar degrees) override
void Scale(DlScalar sx, DlScalar sy) override
void Translate(DlScalar tx, DlScalar ty) override
void DrawPaint(const DlPaint &paint) override
sk_sp< DisplayList > Build()
void DrawPath(const DlPath &path, const DlPaint &paint) override
void ClipPath(const DlPath &path, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false) override
void Transform(const DlMatrix &matrix) override
void DrawRect(const DlRect &rect, const DlPaint &paint) override
static std::shared_ptr< DlMaskFilter > Make(DlBlurStyle style, SkScalar sigma, bool respect_ctm=true)
static std::shared_ptr< const DlColorFilter > MakeBlend(DlColor color, DlBlendMode mode)
static std::shared_ptr< DlColorSource > MakeSweep(DlPoint center, DlScalar start, DlScalar end, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, const DlMatrix *matrix=nullptr)
static std::shared_ptr< DlColorSource > MakeImage(const sk_sp< const DlImage > &image, DlTileMode horizontal_tile_mode, DlTileMode vertical_tile_mode, DlImageSampling sampling=DlImageSampling::kLinear, const DlMatrix *matrix=nullptr)
static std::shared_ptr< DlColorSource > MakeRadial(DlPoint center, DlScalar radius, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, const DlMatrix *matrix=nullptr)
DlPaint & setColor(DlColor color)
Definition dl_paint.h:70
DlPaint & setStrokeCap(DlStrokeCap cap)
Definition dl_paint.h:101
DlPaint & setStrokeWidth(float width)
Definition dl_paint.h:115
DlPaint & setMaskFilter(std::nullptr_t filter)
Definition dl_paint.h:185
DlPaint & setDrawStyle(DlDrawStyle style)
Definition dl_paint.h:93
DlPaint & setStrokeJoin(DlStrokeJoin join)
Definition dl_paint.h:109
DlPaint & setColorFilter(std::nullptr_t filter)
Definition dl_paint.h:149
DlPaint & setColorSource(std::nullptr_t source)
Definition dl_paint.h:131
DlPathBuilder & LineTo(DlPoint p2)
Draw a line from the current point to the indicated point p2.
DlPathBuilder & AddPath(const DlPath &path)
Append the provided path to this path as if the commands used to construct it were repeated on this p...
static constexpr const DlScalar kArcApproximationMagic
DlPathBuilder & MoveTo(DlPoint p2)
Start a new contour that will originate at the indicated point p2.
DlPathBuilder & SetFillType(DlPathFillType fill_type)
Set the fill type that should be used to determine the interior of this path to the indicated |fill_t...
const DlPath TakePath()
Returns the path constructed by this path builder and resets its internal state to the default state ...
DlPathBuilder & ConicCurveTo(DlPoint cp, DlPoint p2, DlScalar weight)
Draw a conic curve (a rational quadratic bezier curve) from the current point to the indicated point ...
DlPathBuilder & QuadraticCurveTo(DlPoint cp, DlPoint p2)
Draw a quadratic bezier curve from the current point to the indicated point p2, using the indicated p...
DlPathBuilder & Close()
The path is closed back to the location of the most recent MoveTo call. Contours that are filled are ...
DlPathBuilder & AddArc(const DlRect &bounds, DlDegrees start, DlDegrees sweep, bool use_center=false)
Append an arc contour to the path which:
DlPathBuilder & CubicCurveTo(DlPoint cp1, DlPoint cp2, DlPoint p2)
Draw a cubic bezier curve from the current point to the indicated point p2, using the indicated point...
static DlPath MakeLine(const DlPoint a, const DlPoint b)
Definition dl_path.cc:89
static DlPath MakeRoundRect(const DlRoundRect &rrect)
Definition dl_path.cc:72
static DlPath MakeCircle(const DlPoint center, DlScalar radius)
Definition dl_path.cc:68
static DlPath MakeArc(const DlRect &bounds, DlDegrees start, DlDegrees sweep, bool use_center)
Definition dl_path.cc:101
static DlPath MakeRect(const DlRect &rect)
Definition dl_path.cc:39
double x() const
Definition geometry.h:22
static bool ImGuiBegin(const char *name, bool *p_open, ImGuiWindowFlags flags)
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
int32_t x
auto & d
Definition main.cc:28
FlutterDesktopBinaryReply callback
FlTexture * texture
double y
impeller::Scalar DlScalar
impeller::Degrees DlDegrees
impeller::Size DlSize
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switch_defs.h:52
impeller::Point DlPoint
TEST_P(AiksTest, DrawAtlasNoColor)
float Scalar
Definition scalar.h:19
std::tuple< Point, Point > DrawPlaygroundLine(PlaygroundPoint &point_a, PlaygroundPoint &point_b)
Definition widgets.cc:51
constexpr float kSqrt2Over2
Definition constants.h:51
int32_t width
static constexpr DlColor kWhite()
Definition dl_color.h:70
static constexpr DlColor kBlue()
Definition dl_color.h:73
static constexpr DlColor RGBA(DlScalar r, DlScalar g, DlScalar b, DlScalar a)
Construct a 32 bit color from floating point R, G, B, and A color channels.
Definition dl_color.h:48
static constexpr DlColor kBlack()
Definition dl_color.h:69
static constexpr DlColor ARGB(DlScalar a, DlScalar r, DlScalar g, DlScalar b)
Construct a 32 bit color from floating point A, R, G, and B color channels.
Definition dl_color.h:57
static constexpr DlColor kYellow()
Definition dl_color.h:76
static constexpr DlColor kFuchsia()
Definition dl_color.h:81
static constexpr DlColor kAliceBlue()
Definition dl_color.h:80
static constexpr DlColor kRed()
Definition dl_color.h:71
static constexpr DlColor kGreen()
Definition dl_color.h:72
static constexpr DlColor kGreenYellow()
Definition dl_color.h:90
Scalar blue
Definition color.h:138
Scalar alpha
Definition color.h:143
static constexpr Color Black()
Definition color.h:271
constexpr Color WithAlpha(Scalar new_alpha) const
Definition color.h:283
Scalar red
Definition color.h:128
static constexpr Color Red()
Definition color.h:277
Scalar green
Definition color.h:133
A 4x4 matrix using column-major storage.
Definition matrix.h:37
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition matrix.h:95
bool IsInvertible() const
Definition matrix.h:321
Matrix Invert() const
Definition matrix.cc:99
static Matrix MakeRotationZ(Radians r)
Definition matrix.h:223
static RoundRect MakeRectRadii(const Rect &rect, const RoundingRadii &radii)
Definition round_rect.cc:9
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition rect.h:136
static constexpr TRect MakeCircleBounds(const TPoint< Type > &center, Type radius)
Definition rect.h:156
static constexpr TRect MakeSize(const TSize< U > &size)
Definition rect.h:150