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 // Must be called before any methods that use the context to ensure that
632 // this test is run with the antialias flag.
633 EnsureContextSupportsAntialiasLines();
634
635 Scalar scale = 5.0;
636 Scalar line_width = 10.f;
637 auto callback = [&]() -> sk_sp<DisplayList> {
638 if (AiksTest::ImGuiBegin("Controls", nullptr,
639 ImGuiWindowFlags_AlwaysAutoResize)) {
640 ImGui::SliderFloat("Scale", &scale, 0.001, 5);
641 ImGui::SliderFloat("Width", &line_width, 1, 20);
642
643 ImGui::End();
644 }
645 DisplayListBuilder builder;
646 builder.Scale(GetContentScale().x, GetContentScale().y);
647
648 builder.DrawPaint(DlPaint(DlColor(0xff111111)));
649
650 {
651 DlPaint paint;
653 paint.setStrokeWidth(line_width);
654
655 builder.DrawLine(DlPoint(100, 100), DlPoint(350, 100), paint);
656 builder.DrawLine(DlPoint(100, 100), DlPoint(350, 150), paint);
657
658 builder.Save();
659 builder.Translate(100, 300);
660 builder.Scale(scale, scale);
661 builder.Translate(-100, -300);
662 builder.DrawLine(DlPoint(100, 300), DlPoint(350, 300), paint);
663 builder.DrawLine(DlPoint(100, 300), DlPoint(350, 450), paint);
664 builder.Restore();
665 }
666
667 {
668 DlPaint paint;
670 paint.setStrokeWidth(2.0);
671
672 builder.Save();
673 builder.Translate(100, 500);
674 builder.Scale(0.2, 0.2);
675 builder.Translate(-100, -500);
676 builder.DrawLine(DlPoint(100, 500), DlPoint(350, 500), paint);
677 builder.DrawLine(DlPoint(100, 500), DlPoint(350, 650), paint);
678 builder.Restore();
679 }
680
681 return builder.Build();
682 };
683 ASSERT_TRUE(OpenPlaygroundHere(callback));
684}
685
686TEST_P(AiksTest, HexagonExperimentAntialiasLines) {
687 // Must be called before any methods that use the context to ensure that
688 // this test is run with the antialias flag.
689 EnsureContextSupportsAntialiasLines();
690
691 float scale = 5.0f;
692 float line_width = 10.f;
693 float rotation = 0.f;
694
695 auto callback = [&]() -> sk_sp<DisplayList> {
696 if (AiksTest::ImGuiBegin("Controls", nullptr,
697 ImGuiWindowFlags_AlwaysAutoResize)) {
698 // Use ImGui::SliderFloat for consistency
699 ImGui::SliderFloat("Scale", &scale, 0.001f, 5.0f);
700 ImGui::SliderFloat("Width", &line_width, 1.0f, 20.0f);
701 ImGui::SliderFloat("Rotation", &rotation, 0.0f, 180.0f);
702
703 ImGui::End();
704 }
705 DisplayListBuilder builder;
706 builder.Scale(static_cast<float>(GetContentScale().x),
707 static_cast<float>(GetContentScale().y));
708
709 builder.DrawPaint(DlPaint(DlColor(0xff111111))); // Background
710
711 {
712 DlPaint hex_paint;
713 hex_paint.setColor(
714 DlColor::kGreen()); // Changed color to Red for visibility
715 hex_paint.setStrokeWidth(line_width); // Use the interactive width
716
717 float cx = 512.0f; // Center X
718 float cy = 384.0f; // Center Y
719 float r = 80.0f; // Radius (distance from center to vertex)
720
721 float r_sin60 = r * std::sqrt(3.0f) / 2.0f;
722 float r_cos60 = r / 2.0f;
723
724 DlPoint v0 = DlPoint(cx + r, cy); // Right vertex
725 DlPoint v1 = DlPoint(cx + r_cos60, cy - r_sin60); // Top-right vertex
726 DlPoint v2 = DlPoint(
727 cx - r_cos60,
728 cy - r_sin60); // Top-left vertex (v1-v2 is top horizontal side)
729 DlPoint v3 = DlPoint(cx - r, cy); // Left vertex
730 DlPoint v4 = DlPoint(cx - r_cos60, cy + r_sin60); // Bottom-left vertex
731 DlPoint v5 =
732 DlPoint(cx + r_cos60, cy + r_sin60); // Bottom-right vertex (v4-v5 is
733 // bottom horizontal side)
734
735 builder.Translate(cx, cy);
736 builder.Scale(scale, scale);
737 builder.Rotate(rotation);
738 builder.Translate(-cx, -cy);
739
740 builder.DrawLine(v0, v1, hex_paint);
741 builder.DrawLine(v1, v2, hex_paint); // Top side
742 builder.DrawLine(v2, v3, hex_paint);
743 builder.DrawLine(v3, v4, hex_paint);
744 builder.DrawLine(v4, v5, hex_paint); // Bottom side
745 builder.DrawLine(v5, v0, hex_paint); // Close the hexagon
746 }
747
748 return builder.Build();
749 };
750 ASSERT_TRUE(OpenPlaygroundHere(callback));
751}
752
753TEST_P(AiksTest, SimpleExperimentAntialiasLines) {
754 // Must be called before any methods that use the context to ensure that
755 // this test is run with the antialias flag.
756 EnsureContextSupportsAntialiasLines();
757
758 DisplayListBuilder builder;
759 builder.Scale(GetContentScale().x, GetContentScale().y);
760
761 builder.DrawPaint(DlPaint(DlColor(0xff111111)));
762
763 DlPaint paint;
765 paint.setStrokeWidth(10);
766
767 auto draw = [&builder](DlPaint& paint) {
768 for (auto cap :
769 {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
770 paint.setStrokeCap(cap);
771 DlPoint origin = {100, 100};
772 builder.DrawLine(DlPoint(150, 100), DlPoint(250, 100), paint);
773 for (int d = 15; d < 90; d += 15) {
775 Point origin = {100, 100};
776 Point p0 = {50, 0};
777 Point p1 = {150, 0};
778 auto a = origin + m * p0;
779 auto b = origin + m * p1;
780
781 builder.DrawLine(a, b, paint);
782 }
783 builder.DrawLine(DlPoint(100, 150), DlPoint(100, 250), paint);
784 builder.DrawCircle(origin, 35, paint);
785
786 builder.DrawLine(DlPoint(250, 250), DlPoint(250, 250), paint);
787
788 builder.Translate(250, 0);
789 }
790 builder.Translate(-750, 250);
791 };
792
793 draw(paint);
794
795 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
796}
797
798TEST_P(AiksTest, DrawRectStrokesRenderCorrectly) {
799 DisplayListBuilder builder;
800 DlPaint paint;
801 paint.setColor(DlColor::kRed());
802 paint.setDrawStyle(DlDrawStyle::kStroke);
803 paint.setStrokeWidth(10);
804
805 builder.Translate(100, 100);
806 builder.DrawPath(DlPath::MakeRect(DlRect::MakeSize(DlSize(100, 100))), paint);
807
808 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
809}
810
811TEST_P(AiksTest, DrawRectStrokesWithBevelJoinRenderCorrectly) {
812 DisplayListBuilder builder;
813 DlPaint paint;
814 paint.setColor(DlColor::kRed());
815 paint.setDrawStyle(DlDrawStyle::kStroke);
816 paint.setStrokeWidth(10);
817 paint.setStrokeJoin(DlStrokeJoin::kBevel);
818
819 builder.Translate(100, 100);
820 builder.DrawPath(DlPath::MakeRect(DlRect::MakeSize(DlSize(100, 100))), paint);
821
822 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
823}
824
825TEST_P(AiksTest, CanDrawMultiContourConvexPath) {
826 DlPathBuilder path_builder;
827 for (auto i = 0; i < 10; i++) {
828 if (i % 2 == 0) {
829 // We use the factory method to convert the circle to a path so that it
830 // uses the legacy conics for legacy golden output.
831 DlPath circle =
832 DlPath::MakeCircle(DlPoint(100 + 50 * i, 100 + 50 * i), 100);
833 path_builder.AddPath(circle);
834 path_builder.Close();
835 } else {
836 path_builder.MoveTo(DlPoint(100.f + 50.f * i - 100, 100.f + 50.f * i));
837 path_builder.LineTo(DlPoint(100.f + 50.f * i, 100.f + 50.f * i - 100));
838 path_builder.LineTo(DlPoint(100.f + 50.f * i - 100, //
839 100.f + 50.f * i - 100));
840 path_builder.Close();
841 }
842 }
843 DlPath path = path_builder.TakePath();
844
845 DisplayListBuilder builder;
846 DlPaint paint;
847 paint.setColor(DlColor::kRed().withAlpha(102));
848 builder.DrawPath(path, paint);
849
850 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
851}
852
853TEST_P(AiksTest, ArcWithZeroSweepAndBlur) {
854 DisplayListBuilder builder;
855 builder.Scale(GetContentScale().x, GetContentScale().y);
856
857 DlPaint paint;
858 paint.setColor(DlColor::kRed());
859
860 std::vector<DlColor> colors = {DlColor::RGBA(1.0, 0.0, 0.0, 1.0),
861 DlColor::RGBA(0.0, 0.0, 0.0, 1.0)};
862 std::vector<Scalar> stops = {0.0, 1.0};
863
864 paint.setColorSource(
865 DlColorSource::MakeSweep({100, 100}, 45, 135, stops.size(), colors.data(),
866 stops.data(), DlTileMode::kMirror));
867 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
868
869 DlPathBuilder path_builder;
870 path_builder.AddArc(DlRect::MakeXYWH(10, 10, 100, 100), //
871 DlDegrees(0), DlDegrees(0));
872 builder.DrawPath(path_builder.TakePath(), paint);
873
874 // Check that this empty picture can be created without crashing.
875 builder.Build();
876}
877
878TEST_P(AiksTest, CanRenderClips) {
879 DisplayListBuilder builder;
880 DlPaint paint;
882
883 builder.ClipPath(DlPath::MakeRect(DlRect::MakeXYWH(0, 0, 500, 500)));
884 builder.DrawPath(DlPath::MakeCircle(DlPoint(500, 500), 250), paint);
885
886 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
887}
888
889TEST_P(AiksTest, FatStrokeArc) {
890 DlScalar stroke_width = 300;
891 DlScalar aspect = 1.0;
892 DlScalar start_angle = 0;
893 DlScalar end_angle = 90;
894 auto callback = [&]() -> sk_sp<DisplayList> {
895 if (AiksTest::ImGuiBegin("Controls", nullptr,
896 ImGuiWindowFlags_AlwaysAutoResize)) {
897 ImGui::SliderFloat("Stroke Width", &stroke_width, 1, 300);
898 ImGui::SliderFloat("Aspect", &aspect, 0.5, 2.0);
899 ImGui::SliderFloat("Start Angle", &start_angle, 0, 360);
900 ImGui::SliderFloat("End Angle", &end_angle, 0, 360);
901 ImGui::End();
902 }
903
904 DisplayListBuilder builder;
905 DlPaint grey_paint;
906 grey_paint.setColor(DlColor(0xff111111));
907 builder.DrawPaint(grey_paint);
908
909 DlPaint white_paint;
910 white_paint.setColor(DlColor::kWhite());
911 white_paint.setStrokeWidth(stroke_width);
912 white_paint.setDrawStyle(DlDrawStyle::kStroke);
913 DlPaint red_paint;
914 red_paint.setColor(DlColor::kRed());
915
916 Rect rect = Rect::MakeXYWH(100, 100, 100, aspect * 100);
917 builder.DrawRect(rect, red_paint);
918 builder.DrawArc(rect, start_angle, end_angle,
919 /*useCenter=*/false, white_paint);
920 DlScalar frontier = rect.GetRight() + stroke_width / 2.0;
921 builder.DrawLine(Point(frontier, 0), Point(frontier, 150), red_paint);
922
923 return builder.Build();
924 };
925 ASSERT_TRUE(OpenPlaygroundHere(callback));
926}
927
928TEST_P(AiksTest, CanRenderOverlappingMultiContourPath) {
929 DisplayListBuilder builder;
930
931 DlPaint paint;
932 paint.setColor(DlColor::kRed());
933
934 RoundingRadii radii = {
935 .top_left = DlSize(50, 50),
936 .top_right = DlSize(50, 50),
937 .bottom_left = DlSize(50, 50),
938 .bottom_right = DlSize(50, 50),
939 };
940
941 const Scalar kTriangleHeight = 100;
943 DlRect::MakeCircleBounds({0, 0}, kTriangleHeight * 0.5f), radii);
944 // We use the factory method to convert the rrect to a path so that it
945 // uses the legacy conics for legacy golden output.
946 DlPath rrect_path = DlPath::MakeRoundRect(rrect);
947
948 builder.Translate(200, 200);
949 // Form a path similar to the Material drop slider value indicator. Both
950 // shapes should render identically side-by-side.
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(kTriangleHeight / 2.0f, 0));
956 path_builder.Close();
957 path_builder.AddPath(rrect_path);
958
959 builder.DrawPath(path_builder.TakePath(), paint);
960 }
961 builder.Translate(100, 0);
962
963 {
964 DlPathBuilder path_builder;
965 path_builder.MoveTo(DlPoint(0, kTriangleHeight));
966 path_builder.LineTo(DlPoint(-kTriangleHeight / 2.0f, 0));
967 path_builder.LineTo(DlPoint(0, -10));
968 path_builder.LineTo(DlPoint(kTriangleHeight / 2.0f, 0));
969 path_builder.Close();
970 path_builder.AddPath(rrect_path);
971
972 builder.DrawPath(path_builder.TakePath(), paint);
973 }
974
975 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
976}
977
978TEST_P(AiksTest, TwoContourPathWithSinglePointContour) {
979 DisplayListBuilder builder;
980
981 DlPaint paint;
982 paint.setColor(DlColor::kRed());
983 paint.setDrawStyle(DlDrawStyle::kStroke);
984 paint.setStrokeWidth(15.0);
985 paint.setStrokeCap(DlStrokeCap::kRound);
986
987 DlPathBuilder path_builder;
988 path_builder.MoveTo(DlPoint(100, 100));
989 path_builder.LineTo(DlPoint(150, 150));
990 path_builder.MoveTo(DlPoint(200, 200));
991 path_builder.LineTo(DlPoint(200, 200));
992
993 builder.DrawPath(path_builder.TakePath(), paint);
994
995 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
996}
997
998TEST_P(AiksTest, TwoContourPathWithConnectingLines) {
999 DisplayListBuilder builder;
1000
1001 DlPaint paint;
1002 paint.setColor(DlColor::kRed());
1003 paint.setDrawStyle(DlDrawStyle::kStroke);
1004 paint.setStrokeWidth(15.0);
1005
1006 builder.Translate(100, 0);
1007 for (auto join : std::vector<DlStrokeJoin>{
1008 DlStrokeJoin::kMiter, DlStrokeJoin::kRound, DlStrokeJoin::kBevel}) {
1009 builder.Translate(0, 100);
1010 paint.setStrokeJoin(join);
1011
1012 DlPathBuilder path_builder;
1013 path_builder.MoveTo(DlPoint(0, 0));
1014 path_builder.LineTo(DlPoint(50, 50));
1015 path_builder.MoveTo(DlPoint(50, 50));
1016 path_builder.LineTo(DlPoint(100, 0));
1017
1018 builder.DrawPath(path_builder.TakePath(), paint);
1019 }
1020
1021 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1022}
1023
1024TEST_P(AiksTest, StrokeCapsAndJoins) {
1025 DisplayListBuilder builder;
1026 builder.Scale(GetContentScale().x, GetContentScale().y);
1027
1028 builder.Translate(100, 0);
1029
1030 builder.Save();
1031 for (auto cap : std::vector<DlStrokeCap>{
1032 DlStrokeCap::kButt, DlStrokeCap::kRound, DlStrokeCap::kSquare}) {
1033 DlPathBuilder path_builder;
1034 path_builder.MoveTo({20, 50});
1035 path_builder.LineTo({50, 50});
1036 path_builder.MoveTo({120, 50});
1037 path_builder.LineTo({120, 80});
1038 path_builder.MoveTo({180, 50});
1039 path_builder.LineTo({180, 50});
1040 DlPath path = path_builder.TakePath();
1041
1042 DlPaint paint;
1043 paint.setColor(DlColor::kRed());
1044 paint.setDrawStyle(DlDrawStyle::kStroke);
1045 paint.setStrokeWidth(20.0f);
1046 paint.setStrokeCap(cap);
1047 paint.setStrokeJoin(DlStrokeJoin::kBevel);
1048
1049 builder.DrawPath(path, paint);
1050
1051 paint.setColor(DlColor::kYellow());
1052 paint.setStrokeWidth(1.0f);
1053 paint.setStrokeCap(DlStrokeCap::kButt);
1054
1055 builder.DrawPath(path, paint);
1056
1057 builder.Translate(250, 0);
1058 }
1059 builder.Restore();
1060
1061 builder.Translate(0, 100);
1062
1063 builder.Save();
1064 for (auto join : std::vector<DlStrokeJoin>{
1065 DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
1066 DlPathBuilder path_builder;
1067 path_builder.MoveTo({20, 50}); // 0 degree right turn
1068 path_builder.LineTo({50, 50});
1069 path_builder.LineTo({80, 50});
1070 path_builder.MoveTo({20, 150}); // 90 degree right turn
1071 path_builder.LineTo({50, 150});
1072 path_builder.LineTo({50, 180});
1073 path_builder.MoveTo({20, 250}); // 45 degree right turn
1074 path_builder.LineTo({50, 250});
1075 path_builder.LineTo({70, 270});
1076 path_builder.MoveTo({20, 350}); // 135 degree right turn
1077 path_builder.LineTo({50, 350});
1078 path_builder.LineTo({30, 370});
1079 path_builder.MoveTo({20, 450}); // 180 degree right turn
1080 path_builder.LineTo({50, 450});
1081 path_builder.LineTo({20, 450});
1082 path_builder.MoveTo({120, 80}); // 0 degree left turn
1083 path_builder.LineTo({150, 80});
1084 path_builder.LineTo({180, 80});
1085 path_builder.MoveTo({120, 180}); // 90 degree left turn
1086 path_builder.LineTo({150, 180});
1087 path_builder.LineTo({150, 150});
1088 path_builder.MoveTo({120, 280}); // 45 degree left turn
1089 path_builder.LineTo({150, 280});
1090 path_builder.LineTo({170, 260});
1091 path_builder.MoveTo({120, 380}); // 135 degree left turn
1092 path_builder.LineTo({150, 380});
1093 path_builder.LineTo({130, 360});
1094 path_builder.MoveTo({120, 480}); // 180 degree left turn
1095 path_builder.LineTo({150, 480});
1096 path_builder.LineTo({120, 480});
1097 DlPath path = path_builder.TakePath();
1098
1099 DlPaint paint;
1100
1101 paint.setColor(DlColor::kRed());
1102 paint.setDrawStyle(DlDrawStyle::kStroke);
1103 paint.setStrokeWidth(20.0f);
1104 paint.setStrokeCap(DlStrokeCap::kSquare);
1105 paint.setStrokeJoin(join);
1106 builder.DrawPath(path, paint);
1107
1108 paint.setColor(DlColor::kYellow());
1109 paint.setStrokeWidth(1.0f);
1110 paint.setStrokeCap(DlStrokeCap::kButt);
1111 builder.DrawPath(path, paint);
1112
1113 builder.Translate(250, 0);
1114 }
1115 builder.Restore();
1116
1117 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1118}
1119
1120TEST_P(AiksTest, BlurredCircleWithStrokeWidth) {
1121 DisplayListBuilder builder;
1122 DlPaint paint;
1123 paint.setColor(DlColor::kGreen());
1124 paint.setDrawStyle(DlDrawStyle::kStroke);
1125 paint.setStrokeWidth(30);
1126 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 5));
1127
1128 builder.DrawCircle(DlPoint(200, 200), 100, paint);
1129
1130 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1131}
1132
1133} // namespace testing
1134} // 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