Flutter Engine
 
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 auto callback = [&]() -> sk_sp<DisplayList> {
269 if (AiksTest::ImGuiBegin("Controls", nullptr,
270 ImGuiWindowFlags_AlwaysAutoResize)) {
271 ImGui::SliderFloat("Scale", &scale, 0, 6);
272 ImGui::SliderFloat("Rotate", &rotation, 0, 90);
273 ImGui::SliderFloat("Offset", &offset, 0, 2);
274 ImGui::End();
275 }
276
277 DisplayListBuilder builder;
278 builder.Scale(GetContentScale().x, GetContentScale().y);
279 builder.DrawPaint(DlPaint(DlColor(0xff111111)));
280
281 DlPaint paint;
282 paint.setStrokeWidth(0.f);
283 paint.setColor(DlColor::kWhite());
284 paint.setStrokeCap(DlStrokeCap::kRound);
285 paint.setStrokeJoin(DlStrokeJoin::kRound);
286 paint.setDrawStyle(DlDrawStyle::kStroke);
287
288 builder.Translate(512, 384);
289 builder.Scale(scale, scale);
290 builder.Rotate(rotation);
291 builder.Translate(-512, -384 + offset);
292
293 for (int i = 0; i < 5; ++i) {
294 Scalar yoffset = i * 25.25f + 300.f;
295 DlPathBuilder path_builder;
296
297 path_builder.MoveTo(DlPoint(100, yoffset));
298 path_builder.LineTo(DlPoint(924, yoffset));
299 builder.DrawPath(path_builder.TakePath(), paint);
300 }
301
302 return builder.Build();
303 };
304
305 ASSERT_TRUE(OpenPlaygroundHere(callback));
306}
307
308TEST_P(AiksTest, HairlineDrawLine) {
309 Scalar scale = 1.f;
310 Scalar rotation = 0.f;
311 Scalar offset = 0.f;
312 auto callback = [&]() -> sk_sp<DisplayList> {
313 if (AiksTest::ImGuiBegin("Controls", nullptr,
314 ImGuiWindowFlags_AlwaysAutoResize)) {
315 ImGui::SliderFloat("Scale", &scale, 0, 6);
316 ImGui::SliderFloat("Rotate", &rotation, 0, 90);
317 ImGui::SliderFloat("Offset", &offset, 0, 2);
318 ImGui::End();
319 }
320
321 DisplayListBuilder builder;
322 builder.Scale(GetContentScale().x, GetContentScale().y);
323 builder.DrawPaint(DlPaint(DlColor(0xff111111)));
324
325 DlPaint paint;
326 paint.setStrokeWidth(0.f);
327 paint.setColor(DlColor::kWhite());
328
329 builder.Translate(512, 384);
330 builder.Scale(scale, scale);
331 builder.Rotate(rotation);
332 builder.Translate(-512, -384 + offset);
333
334 for (int i = 0; i < 5; ++i) {
335 Scalar yoffset = i * 25.25f + 300.f;
336
337 builder.DrawLine(DlPoint(100, yoffset), DlPoint(924, yoffset), paint);
338 }
339
340 return builder.Build();
341 };
342
343 ASSERT_TRUE(OpenPlaygroundHere(callback));
344}
345
346TEST_P(AiksTest, CanRenderTightConicPath) {
347 DisplayListBuilder builder;
348 builder.Scale(GetContentScale().x, GetContentScale().y);
349
350 DlPaint paint;
351 paint.setColor(DlColor::kRed());
352 paint.setDrawStyle(DlDrawStyle::kFill);
353
354 DlPaint reference_paint;
355 reference_paint.setColor(DlColor::kGreen());
356 reference_paint.setDrawStyle(DlDrawStyle::kFill);
357
358 DlPathBuilder path_builder;
359
360 path_builder.MoveTo(DlPoint(100, 100));
361 path_builder.ConicCurveTo(DlPoint(150, 450), DlPoint(200, 100), 5.0f);
362
363 DlPathBuilder reference_builder;
364 PathTessellator::Conic component{DlPoint(300, 100), //
365 DlPoint(350, 450), //
366 DlPoint(400, 100), //
367 5.0f};
368 reference_builder.MoveTo(component.p1);
369 constexpr int N = 100;
370 for (int i = 1; i < N; i++) {
371 reference_builder.LineTo(component.Solve(static_cast<Scalar>(i) / N));
372 }
373 reference_builder.LineTo(component.p2);
374
375 DlPaint line_paint;
376 line_paint.setColor(DlColor::kYellow());
377 line_paint.setDrawStyle(DlDrawStyle::kStroke);
378 line_paint.setStrokeWidth(1.0f);
379
380 // Draw some lines to provide a spacial reference for the curvature of
381 // the tips of the direct rendering and the manually tessellated versions.
382 builder.DrawLine(DlPoint(145, 100), DlPoint(145, 450), line_paint);
383 builder.DrawLine(DlPoint(155, 100), DlPoint(155, 450), line_paint);
384 builder.DrawLine(DlPoint(345, 100), DlPoint(345, 450), line_paint);
385 builder.DrawLine(DlPoint(355, 100), DlPoint(355, 450), line_paint);
386 builder.DrawLine(DlPoint(100, 392.5f), DlPoint(400, 392.5f), line_paint);
387
388 // Draw the two paths (direct and manually tessellated) on top of the lines.
389 builder.DrawPath(path_builder.TakePath(), paint);
390 builder.DrawPath(reference_builder.TakePath(), reference_paint);
391
392 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
393}
394
395TEST_P(AiksTest, CanRenderDifferencePaths) {
396 DisplayListBuilder builder;
397
398 DlPaint paint;
399 paint.setColor(DlColor::kRed());
400
401 RoundingRadii radii = {
402 .top_left = {50, 25},
403 .top_right = {25, 50},
404 .bottom_left = {25, 50},
405 .bottom_right = {50, 25},
406 };
407 DlPathBuilder path_builder;
408 DlRoundRect rrect =
409 DlRoundRect::MakeRectRadii(DlRect::MakeXYWH(100, 100, 200, 200), radii);
410 // We use the factory method to convert the rrect and circle to a path so
411 // that they use the legacy conics for legacy golden output.
412 path_builder.AddPath(DlPath::MakeRoundRect(rrect));
413 path_builder.AddPath(DlPath::MakeCircle(DlPoint(200, 200), 50));
414 path_builder.SetFillType(DlPathFillType::kOdd);
415 DlPath path = path_builder.TakePath();
416
417 builder.DrawImage(
418 DlImageImpeller::Make(CreateTextureForFixture("boston.jpg")),
419 DlPoint{10, 10}, {});
420 builder.DrawPath(path, paint);
421
422 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
423}
424
425// Regression test for https://github.com/flutter/flutter/issues/134816.
426//
427// It should be possible to draw 3 lines, and not have an implicit close path.
428TEST_P(AiksTest, CanDrawAnOpenPath) {
429 DisplayListBuilder builder;
430
431 // Starting at (50, 50), draw lines from:
432 // 1. (50, height)
433 // 2. (width, height)
434 // 3. (width, 50)
435 DlPathBuilder path_builder;
436 path_builder.MoveTo(DlPoint(50, 50));
437 path_builder.LineTo(DlPoint(50, 100));
438 path_builder.LineTo(DlPoint(100, 100));
439 path_builder.LineTo(DlPoint(100, 50));
440
441 DlPaint paint;
442 paint.setColor(DlColor::kRed());
443 paint.setDrawStyle(DlDrawStyle::kStroke);
444 paint.setStrokeWidth(10);
445
446 builder.DrawPath(path_builder.TakePath(), paint);
447
448 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
449}
450
451TEST_P(AiksTest, CanDrawAnOpenPathThatIsntARect) {
452 DisplayListBuilder builder;
453
454 // Draw a stroked path that is explicitly closed to verify
455 // It doesn't become a rectangle.
456 DlPathBuilder path_builder;
457 path_builder.MoveTo(DlPoint(50, 50));
458 path_builder.LineTo(DlPoint(520, 120));
459 path_builder.LineTo(DlPoint(300, 310));
460 path_builder.LineTo(DlPoint(100, 50));
461 path_builder.Close();
462
463 DlPaint paint;
464 paint.setColor(DlColor::kRed());
465 paint.setDrawStyle(DlDrawStyle::kStroke);
466 paint.setStrokeWidth(10);
467
468 builder.DrawPath(path_builder.TakePath(), paint);
469
470 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
471}
472
473TEST_P(AiksTest, SolidStrokesRenderCorrectly) {
474 // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
475 auto callback = [&]() -> sk_sp<DisplayList> {
476 static Color color = Color::Black().WithAlpha(0.5);
477 static float scale = 3;
478 static bool add_circle_clip = true;
479
480 if (AiksTest::ImGuiBegin("Controls", nullptr,
481 ImGuiWindowFlags_AlwaysAutoResize)) {
482 ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
483 ImGui::SliderFloat("Scale", &scale, 0, 6);
484 ImGui::Checkbox("Circle clip", &add_circle_clip);
485 ImGui::End();
486 }
487
488 DisplayListBuilder builder;
489 builder.Scale(GetContentScale().x, GetContentScale().y);
490 DlPaint paint;
491
492 paint.setColor(DlColor::kWhite());
493 builder.DrawPaint(paint);
494
495 paint.setColor(
496 DlColor::ARGB(color.alpha, color.red, color.green, color.blue));
497 paint.setDrawStyle(DlDrawStyle::kStroke);
498 paint.setStrokeWidth(10);
499
500 DlPathBuilder path_builder;
501 path_builder.MoveTo(DlPoint(20, 20));
502 path_builder.QuadraticCurveTo(DlPoint(60, 20), DlPoint(60, 60));
503 path_builder.Close();
504 path_builder.MoveTo(DlPoint(60, 20));
505 path_builder.QuadraticCurveTo(DlPoint(60, 60), DlPoint(20, 60));
506 DlPath path = path_builder.TakePath();
507
508 builder.Scale(scale, scale);
509
510 if (add_circle_clip) {
511 static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
512 Color::Red());
513 static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
514 Color::Red());
515 auto [handle_a, handle_b] =
516 DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
517
518 Matrix screen_to_canvas = builder.GetMatrix();
519 if (!screen_to_canvas.IsInvertible()) {
520 return nullptr;
521 }
522 screen_to_canvas = screen_to_canvas.Invert();
523
524 Point point_a = screen_to_canvas * handle_a;
525 Point point_b = screen_to_canvas * handle_b;
526
527 Point middle = point_a + point_b;
528 middle *= GetContentScale().x / 2;
529
530 auto radius = point_a.GetDistance(middle);
531
532 builder.ClipPath(DlPath::MakeCircle(middle, radius));
533 }
534
535 for (auto join :
536 {DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
537 paint.setStrokeJoin(join);
538 for (auto cap :
539 {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
540 paint.setStrokeCap(cap);
541 builder.DrawPath(path, paint);
542 builder.Translate(80, 0);
543 }
544 builder.Translate(-240, 60);
545 }
546
547 return builder.Build();
548 };
549
550 ASSERT_TRUE(OpenPlaygroundHere(callback));
551}
552
553TEST_P(AiksTest, DrawLinesRenderCorrectly) {
554 DisplayListBuilder builder;
555 builder.Scale(GetContentScale().x, GetContentScale().y);
556
557 DlPaint paint;
558 paint.setColor(DlColor::kBlue());
559 paint.setStrokeWidth(10);
560
561 auto draw = [&builder](DlPaint& paint) {
562 for (auto cap :
563 {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
564 paint.setStrokeCap(cap);
565 DlPoint origin = {100, 100};
566 builder.DrawLine(DlPoint(150, 100), DlPoint(250, 100), paint);
567 for (int d = 15; d < 90; d += 15) {
569 Point origin = {100, 100};
570 Point p0 = {50, 0};
571 Point p1 = {150, 0};
572 auto a = origin + m * p0;
573 auto b = origin + m * p1;
574
575 builder.DrawLine(a, b, paint);
576 }
577 builder.DrawLine(DlPoint(100, 150), DlPoint(100, 250), paint);
578 builder.DrawCircle(origin, 35, paint);
579
580 builder.DrawLine(DlPoint(250, 250), DlPoint(250, 250), paint);
581
582 builder.Translate(250, 0);
583 }
584 builder.Translate(-750, 250);
585 };
586
587 std::vector<DlColor> colors = {
588 DlColor::ARGB(1, 0x1f / 255.0, 0.0, 0x5c / 255.0),
589 DlColor::ARGB(1, 0x5b / 255.0, 0.0, 0x60 / 255.0),
590 DlColor::ARGB(1, 0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0),
591 DlColor::ARGB(1, 0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0),
592 DlColor::ARGB(1, 0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0),
593 DlColor::ARGB(1, 0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0),
594 DlColor::ARGB(1, 0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0)};
595 std::vector<Scalar> stops = {
596 0.0,
597 (1.0 / 6.0) * 1,
598 (1.0 / 6.0) * 2,
599 (1.0 / 6.0) * 3,
600 (1.0 / 6.0) * 4,
601 (1.0 / 6.0) * 5,
602 1.0,
603 };
604
606 CreateTextureForFixture("airplane.jpg",
607 /*enable_mipmapping=*/true));
608
609 draw(paint);
610
611 paint.setColorSource(DlColorSource::MakeRadial({100, 100}, 200, stops.size(),
612 colors.data(), stops.data(),
613 DlTileMode::kMirror));
614 draw(paint);
615
616 DlMatrix matrix = DlMatrix::MakeTranslation({-150, 75});
618 texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
619 DlImageSampling::kMipmapLinear, &matrix));
620 draw(paint);
621
622 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
623}
624
625// The goal of this test is to show that scaling the lines doesn't also scale
626// the antialiasing. The amount of blurring should be the same for both
627// horizontal lines.
628TEST_P(AiksTest, ScaleExperimentAntialiasLines) {
629 Scalar scale = 5.0;
630 Scalar line_width = 10.f;
631 auto callback = [&]() -> sk_sp<DisplayList> {
632 if (AiksTest::ImGuiBegin("Controls", nullptr,
633 ImGuiWindowFlags_AlwaysAutoResize)) {
634 ImGui::SliderFloat("Scale", &scale, 0.001, 5);
635 ImGui::SliderFloat("Width", &line_width, 1, 20);
636
637 ImGui::End();
638 }
639 DisplayListBuilder builder;
640 builder.Scale(GetContentScale().x, GetContentScale().y);
641
642 builder.DrawPaint(DlPaint(DlColor(0xff111111)));
643
644 {
645 DlPaint paint;
647 paint.setStrokeWidth(line_width);
648
649 builder.DrawLine(DlPoint(100, 100), DlPoint(350, 100), paint);
650 builder.DrawLine(DlPoint(100, 100), DlPoint(350, 150), paint);
651
652 builder.Save();
653 builder.Translate(100, 300);
654 builder.Scale(scale, scale);
655 builder.Translate(-100, -300);
656 builder.DrawLine(DlPoint(100, 300), DlPoint(350, 300), paint);
657 builder.DrawLine(DlPoint(100, 300), DlPoint(350, 450), paint);
658 builder.Restore();
659 }
660
661 {
662 DlPaint paint;
664 paint.setStrokeWidth(2.0);
665
666 builder.Save();
667 builder.Translate(100, 500);
668 builder.Scale(0.2, 0.2);
669 builder.Translate(-100, -500);
670 builder.DrawLine(DlPoint(100, 500), DlPoint(350, 500), paint);
671 builder.DrawLine(DlPoint(100, 500), DlPoint(350, 650), paint);
672 builder.Restore();
673 }
674
675 return builder.Build();
676 };
677 ASSERT_TRUE(OpenPlaygroundHere(callback));
678}
679
680TEST_P(AiksTest, HexagonExperimentAntialiasLines) {
681 float scale = 5.0f;
682 float line_width = 10.f;
683 float rotation = 0.f;
684
685 auto callback = [&]() -> sk_sp<DisplayList> {
686 if (AiksTest::ImGuiBegin("Controls", nullptr,
687 ImGuiWindowFlags_AlwaysAutoResize)) {
688 // Use ImGui::SliderFloat for consistency
689 ImGui::SliderFloat("Scale", &scale, 0.001f, 5.0f);
690 ImGui::SliderFloat("Width", &line_width, 1.0f, 20.0f);
691 ImGui::SliderFloat("Rotation", &rotation, 0.0f, 180.0f);
692
693 ImGui::End();
694 }
695 DisplayListBuilder builder;
696 builder.Scale(static_cast<float>(GetContentScale().x),
697 static_cast<float>(GetContentScale().y));
698
699 builder.DrawPaint(DlPaint(DlColor(0xff111111))); // Background
700
701 {
702 DlPaint hex_paint;
703 hex_paint.setColor(
704 DlColor::kGreen()); // Changed color to Red for visibility
705 hex_paint.setStrokeWidth(line_width); // Use the interactive width
706
707 float cx = 512.0f; // Center X
708 float cy = 384.0f; // Center Y
709 float r = 80.0f; // Radius (distance from center to vertex)
710
711 float r_sin60 = r * std::sqrt(3.0f) / 2.0f;
712 float r_cos60 = r / 2.0f;
713
714 DlPoint v0 = DlPoint(cx + r, cy); // Right vertex
715 DlPoint v1 = DlPoint(cx + r_cos60, cy - r_sin60); // Top-right vertex
716 DlPoint v2 = DlPoint(
717 cx - r_cos60,
718 cy - r_sin60); // Top-left vertex (v1-v2 is top horizontal side)
719 DlPoint v3 = DlPoint(cx - r, cy); // Left vertex
720 DlPoint v4 = DlPoint(cx - r_cos60, cy + r_sin60); // Bottom-left vertex
721 DlPoint v5 =
722 DlPoint(cx + r_cos60, cy + r_sin60); // Bottom-right vertex (v4-v5 is
723 // bottom horizontal side)
724
725 builder.Translate(cx, cy);
726 builder.Scale(scale, scale);
727 builder.Rotate(rotation);
728 builder.Translate(-cx, -cy);
729
730 builder.DrawLine(v0, v1, hex_paint);
731 builder.DrawLine(v1, v2, hex_paint); // Top side
732 builder.DrawLine(v2, v3, hex_paint);
733 builder.DrawLine(v3, v4, hex_paint);
734 builder.DrawLine(v4, v5, hex_paint); // Bottom side
735 builder.DrawLine(v5, v0, hex_paint); // Close the hexagon
736 }
737
738 return builder.Build();
739 };
740 ASSERT_TRUE(OpenPlaygroundHere(callback));
741}
742
743TEST_P(AiksTest, SimpleExperimentAntialiasLines) {
744 DisplayListBuilder builder;
745 builder.Scale(GetContentScale().x, GetContentScale().y);
746
747 builder.DrawPaint(DlPaint(DlColor(0xff111111)));
748
749 DlPaint paint;
751 paint.setStrokeWidth(10);
752
753 auto draw = [&builder](DlPaint& paint) {
754 for (auto cap :
755 {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
756 paint.setStrokeCap(cap);
757 DlPoint origin = {100, 100};
758 builder.DrawLine(DlPoint(150, 100), DlPoint(250, 100), paint);
759 for (int d = 15; d < 90; d += 15) {
761 Point origin = {100, 100};
762 Point p0 = {50, 0};
763 Point p1 = {150, 0};
764 auto a = origin + m * p0;
765 auto b = origin + m * p1;
766
767 builder.DrawLine(a, b, paint);
768 }
769 builder.DrawLine(DlPoint(100, 150), DlPoint(100, 250), paint);
770 builder.DrawCircle(origin, 35, paint);
771
772 builder.DrawLine(DlPoint(250, 250), DlPoint(250, 250), paint);
773
774 builder.Translate(250, 0);
775 }
776 builder.Translate(-750, 250);
777 };
778
779 draw(paint);
780
781 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
782}
783
784TEST_P(AiksTest, DrawRectStrokesRenderCorrectly) {
785 DisplayListBuilder builder;
786 DlPaint paint;
787 paint.setColor(DlColor::kRed());
788 paint.setDrawStyle(DlDrawStyle::kStroke);
789 paint.setStrokeWidth(10);
790
791 builder.Translate(100, 100);
792 builder.DrawPath(DlPath::MakeRect(DlRect::MakeSize(DlSize(100, 100))), paint);
793
794 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
795}
796
797TEST_P(AiksTest, DrawRectStrokesWithBevelJoinRenderCorrectly) {
798 DisplayListBuilder builder;
799 DlPaint paint;
800 paint.setColor(DlColor::kRed());
801 paint.setDrawStyle(DlDrawStyle::kStroke);
802 paint.setStrokeWidth(10);
803 paint.setStrokeJoin(DlStrokeJoin::kBevel);
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, CanDrawMultiContourConvexPath) {
812 DlPathBuilder path_builder;
813 for (auto i = 0; i < 10; i++) {
814 if (i % 2 == 0) {
815 // We use the factory method to convert the circle to a path so that it
816 // uses the legacy conics for legacy golden output.
817 DlPath circle =
818 DlPath::MakeCircle(DlPoint(100 + 50 * i, 100 + 50 * i), 100);
819 path_builder.AddPath(circle);
820 path_builder.Close();
821 } else {
822 path_builder.MoveTo(DlPoint(100.f + 50.f * i - 100, 100.f + 50.f * i));
823 path_builder.LineTo(DlPoint(100.f + 50.f * i, 100.f + 50.f * i - 100));
824 path_builder.LineTo(DlPoint(100.f + 50.f * i - 100, //
825 100.f + 50.f * i - 100));
826 path_builder.Close();
827 }
828 }
829 DlPath path = path_builder.TakePath();
830
831 DisplayListBuilder builder;
832 DlPaint paint;
833 paint.setColor(DlColor::kRed().withAlpha(102));
834 builder.DrawPath(path, paint);
835
836 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
837}
838
839TEST_P(AiksTest, ArcWithZeroSweepAndBlur) {
840 DisplayListBuilder builder;
841 builder.Scale(GetContentScale().x, GetContentScale().y);
842
843 DlPaint paint;
844 paint.setColor(DlColor::kRed());
845
846 std::vector<DlColor> colors = {DlColor::RGBA(1.0, 0.0, 0.0, 1.0),
847 DlColor::RGBA(0.0, 0.0, 0.0, 1.0)};
848 std::vector<Scalar> stops = {0.0, 1.0};
849
850 paint.setColorSource(
851 DlColorSource::MakeSweep({100, 100}, 45, 135, stops.size(), colors.data(),
852 stops.data(), DlTileMode::kMirror));
853 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
854
855 DlPathBuilder path_builder;
856 path_builder.AddArc(DlRect::MakeXYWH(10, 10, 100, 100), //
857 DlDegrees(0), DlDegrees(0));
858 builder.DrawPath(path_builder.TakePath(), paint);
859
860 // Check that this empty picture can be created without crashing.
861 builder.Build();
862}
863
864TEST_P(AiksTest, CanRenderClips) {
865 DisplayListBuilder builder;
866 DlPaint paint;
868
869 builder.ClipPath(DlPath::MakeRect(DlRect::MakeXYWH(0, 0, 500, 500)));
870 builder.DrawPath(DlPath::MakeCircle(DlPoint(500, 500), 250), paint);
871
872 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
873}
874
875TEST_P(AiksTest, FatStrokeArc) {
876 DlScalar stroke_width = 300;
877 DlScalar aspect = 1.0;
878 DlScalar start_angle = 0;
879 DlScalar end_angle = 90;
880 auto callback = [&]() -> sk_sp<DisplayList> {
881 if (AiksTest::ImGuiBegin("Controls", nullptr,
882 ImGuiWindowFlags_AlwaysAutoResize)) {
883 ImGui::SliderFloat("Stroke Width", &stroke_width, 1, 300);
884 ImGui::SliderFloat("Aspect", &aspect, 0.5, 2.0);
885 ImGui::SliderFloat("Start Angle", &start_angle, 0, 360);
886 ImGui::SliderFloat("End Angle", &end_angle, 0, 360);
887 ImGui::End();
888 }
889
890 DisplayListBuilder builder;
891 DlPaint grey_paint;
892 grey_paint.setColor(DlColor(0xff111111));
893 builder.DrawPaint(grey_paint);
894
895 DlPaint white_paint;
896 white_paint.setColor(DlColor::kWhite());
897 white_paint.setStrokeWidth(stroke_width);
898 white_paint.setDrawStyle(DlDrawStyle::kStroke);
899 DlPaint red_paint;
900 red_paint.setColor(DlColor::kRed());
901
902 Rect rect = Rect::MakeXYWH(100, 100, 100, aspect * 100);
903 builder.DrawRect(rect, red_paint);
904 builder.DrawArc(rect, start_angle, end_angle,
905 /*useCenter=*/false, white_paint);
906 DlScalar frontier = rect.GetRight() + stroke_width / 2.0;
907 builder.DrawLine(Point(frontier, 0), Point(frontier, 150), red_paint);
908
909 return builder.Build();
910 };
911 ASSERT_TRUE(OpenPlaygroundHere(callback));
912}
913
914TEST_P(AiksTest, CanRenderOverlappingMultiContourPath) {
915 DisplayListBuilder builder;
916
917 DlPaint paint;
918 paint.setColor(DlColor::kRed());
919
920 RoundingRadii radii = {
921 .top_left = DlSize(50, 50),
922 .top_right = DlSize(50, 50),
923 .bottom_left = DlSize(50, 50),
924 .bottom_right = DlSize(50, 50),
925 };
926
927 const Scalar kTriangleHeight = 100;
929 DlRect::MakeXYWH(-kTriangleHeight / 2.0f, -kTriangleHeight / 2.0f,
930 kTriangleHeight, kTriangleHeight),
931 radii //
932 );
933 // We use the factory method to convert the rrect to a path so that it
934 // uses the legacy conics for legacy golden output.
935 DlPath rrect_path = DlPath::MakeRoundRect(rrect);
936
937 builder.Translate(200, 200);
938 // Form a path similar to the Material drop slider value indicator. Both
939 // shapes should render identically side-by-side.
940 {
941 DlPathBuilder path_builder;
942 path_builder.MoveTo(DlPoint(0, kTriangleHeight));
943 path_builder.LineTo(DlPoint(-kTriangleHeight / 2.0f, 0));
944 path_builder.LineTo(DlPoint(kTriangleHeight / 2.0f, 0));
945 path_builder.Close();
946 path_builder.AddPath(rrect_path);
947
948 builder.DrawPath(path_builder.TakePath(), paint);
949 }
950 builder.Translate(100, 0);
951
952 {
953 DlPathBuilder path_builder;
954 path_builder.MoveTo(DlPoint(0, kTriangleHeight));
955 path_builder.LineTo(DlPoint(-kTriangleHeight / 2.0f, 0));
956 path_builder.LineTo(DlPoint(0, -10));
957 path_builder.LineTo(DlPoint(kTriangleHeight / 2.0f, 0));
958 path_builder.Close();
959 path_builder.AddPath(rrect_path);
960
961 builder.DrawPath(path_builder.TakePath(), paint);
962 }
963
964 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
965}
966
967TEST_P(AiksTest, TwoContourPathWithSinglePointContour) {
968 DisplayListBuilder builder;
969
970 DlPaint paint;
971 paint.setColor(DlColor::kRed());
972 paint.setDrawStyle(DlDrawStyle::kStroke);
973 paint.setStrokeWidth(15.0);
974 paint.setStrokeCap(DlStrokeCap::kRound);
975
976 DlPathBuilder path_builder;
977 path_builder.MoveTo(DlPoint(100, 100));
978 path_builder.LineTo(DlPoint(150, 150));
979 path_builder.MoveTo(DlPoint(200, 200));
980 path_builder.LineTo(DlPoint(200, 200));
981
982 builder.DrawPath(path_builder.TakePath(), paint);
983
984 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
985}
986
987TEST_P(AiksTest, StrokeCapsAndJoins) {
988 DisplayListBuilder builder;
989 builder.Scale(GetContentScale().x, GetContentScale().y);
990
991 builder.Translate(100, 0);
992
993 builder.Save();
994 for (auto cap : std::vector<DlStrokeCap>{
995 DlStrokeCap::kButt, DlStrokeCap::kRound, DlStrokeCap::kSquare}) {
996 DlPathBuilder path_builder;
997 path_builder.MoveTo({20, 50});
998 path_builder.LineTo({50, 50});
999 path_builder.MoveTo({120, 50});
1000 path_builder.LineTo({120, 80});
1001 path_builder.MoveTo({180, 50});
1002 path_builder.LineTo({180, 50});
1003 DlPath path = path_builder.TakePath();
1004
1005 DlPaint paint;
1006 paint.setColor(DlColor::kRed());
1007 paint.setDrawStyle(DlDrawStyle::kStroke);
1008 paint.setStrokeWidth(20.0f);
1009 paint.setStrokeCap(cap);
1010 paint.setStrokeJoin(DlStrokeJoin::kBevel);
1011
1012 builder.DrawPath(path, paint);
1013
1014 paint.setColor(DlColor::kYellow());
1015 paint.setStrokeWidth(1.0f);
1016 paint.setStrokeCap(DlStrokeCap::kButt);
1017
1018 builder.DrawPath(path, paint);
1019
1020 builder.Translate(250, 0);
1021 }
1022 builder.Restore();
1023
1024 builder.Translate(0, 100);
1025
1026 builder.Save();
1027 for (auto join : std::vector<DlStrokeJoin>{
1028 DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
1029 DlPathBuilder path_builder;
1030 path_builder.MoveTo({20, 50}); // 0 degree right turn
1031 path_builder.LineTo({50, 50});
1032 path_builder.LineTo({80, 50});
1033 path_builder.MoveTo({20, 150}); // 90 degree right turn
1034 path_builder.LineTo({50, 150});
1035 path_builder.LineTo({50, 180});
1036 path_builder.MoveTo({20, 250}); // 45 degree right turn
1037 path_builder.LineTo({50, 250});
1038 path_builder.LineTo({70, 270});
1039 path_builder.MoveTo({20, 350}); // 135 degree right turn
1040 path_builder.LineTo({50, 350});
1041 path_builder.LineTo({30, 370});
1042 path_builder.MoveTo({20, 450}); // 180 degree right turn
1043 path_builder.LineTo({50, 450});
1044 path_builder.LineTo({20, 450});
1045 path_builder.MoveTo({120, 80}); // 0 degree left turn
1046 path_builder.LineTo({150, 80});
1047 path_builder.LineTo({180, 80});
1048 path_builder.MoveTo({120, 180}); // 90 degree left turn
1049 path_builder.LineTo({150, 180});
1050 path_builder.LineTo({150, 150});
1051 path_builder.MoveTo({120, 280}); // 45 degree left turn
1052 path_builder.LineTo({150, 280});
1053 path_builder.LineTo({170, 260});
1054 path_builder.MoveTo({120, 380}); // 135 degree left turn
1055 path_builder.LineTo({150, 380});
1056 path_builder.LineTo({130, 360});
1057 path_builder.MoveTo({120, 480}); // 180 degree left turn
1058 path_builder.LineTo({150, 480});
1059 path_builder.LineTo({120, 480});
1060 DlPath path = path_builder.TakePath();
1061
1062 DlPaint paint;
1063
1064 paint.setColor(DlColor::kRed());
1065 paint.setDrawStyle(DlDrawStyle::kStroke);
1066 paint.setStrokeWidth(20.0f);
1067 paint.setStrokeCap(DlStrokeCap::kSquare);
1068 paint.setStrokeJoin(join);
1069 builder.DrawPath(path, paint);
1070
1071 paint.setColor(DlColor::kYellow());
1072 paint.setStrokeWidth(1.0f);
1073 paint.setStrokeCap(DlStrokeCap::kButt);
1074 builder.DrawPath(path, paint);
1075
1076 builder.Translate(250, 0);
1077 }
1078 builder.Restore();
1079
1080 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1081}
1082
1083TEST_P(AiksTest, BlurredCircleWithStrokeWidth) {
1084 DisplayListBuilder builder;
1085 DlPaint paint;
1086 paint.setColor(DlColor::kGreen());
1087 paint.setDrawStyle(DlDrawStyle::kStroke);
1088 paint.setStrokeWidth(30);
1089 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 5));
1090
1091 builder.DrawCircle(DlPoint(200, 200), 100, paint);
1092
1093 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1094}
1095
1096} // namespace testing
1097} // 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:102
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()
Definition dl_builder.cc:66
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
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:266
constexpr Color WithAlpha(Scalar new_alpha) const
Definition color.h:278
Scalar red
Definition color.h:128
static constexpr Color Red()
Definition color.h:272
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 MakeSize(const TSize< U > &size)
Definition rect.h:150