Flutter Engine
 
Loading...
Searching...
No Matches
aiks_dl_gradient_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
13
19
20using namespace flutter;
21////////////////////////////////////////////////////////////////////////////////
22// This is for tests of Canvas that are interested the results of rendering
23// gradients.
24////////////////////////////////////////////////////////////////////////////////
25
26namespace impeller {
27namespace testing {
28
29namespace {
30
31/// Test body for linear gradient tile mode tests (ex.
32/// CanRenderLinearGradientClamp).
33void CanRenderLinearGradient(AiksTest* aiks_test, DlTileMode tile_mode) {
34 DisplayListBuilder builder;
35 Point scale = aiks_test->GetContentScale();
36 builder.Scale(scale.x, scale.y);
37 DlPaint paint;
38 builder.Translate(100.0f, 0);
39
40 std::vector<DlColor> colors = {
41 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
42 DlColor(Color{0.1294, 0.5882, 0.9529, 0.0}.ToARGB())};
43 std::vector<Scalar> stops = {0.0, 1.0};
44
45 auto gradient = DlColorSource::MakeLinear(
46 {0, 0}, {200, 200}, 2, colors.data(), stops.data(), tile_mode);
47 paint.setColorSource(gradient);
49 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
50 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
51}
52
53} // namespace
54
55TEST_P(AiksTest, CanRenderLinearGradientClamp) {
56 CanRenderLinearGradient(this, DlTileMode::kClamp);
57}
58TEST_P(AiksTest, CanRenderLinearGradientRepeat) {
59 CanRenderLinearGradient(this, DlTileMode::kRepeat);
60}
61TEST_P(AiksTest, CanRenderLinearGradientMirror) {
62 CanRenderLinearGradient(this, DlTileMode::kMirror);
63}
64TEST_P(AiksTest, CanRenderLinearGradientDecal) {
65 CanRenderLinearGradient(this, DlTileMode::kDecal);
66}
67
68TEST_P(AiksTest, CanRenderLinearGradientDecalWithColorFilter) {
69 DisplayListBuilder builder;
70 Point scale = GetContentScale();
71 builder.Scale(scale.x, scale.y);
72 DlPaint paint;
73 builder.Translate(100.0f, 0);
74
75 std::vector<DlColor> colors = {
76 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
77 DlColor(Color{0.1294, 0.5882, 0.9529, 0.0}.ToARGB())};
78 std::vector<Scalar> stops = {0.0, 1.0};
79
81 {0, 0}, {200, 200}, 2, colors.data(), stops.data(), DlTileMode::kDecal));
82 // Overlay the gradient with 25% green. This should appear as the entire
83 // rectangle being drawn with 25% green, including the border area outside the
84 // decal gradient.
86 DlBlendMode::kSrcOver));
88 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
89 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
90}
91
93 DisplayListBuilder builder;
94 DlPaint paint;
95 builder.Translate(100.0, 100.0);
96
97 // 0xffcccccc --> 0xff333333, taken from
98 // https://github.com/flutter/flutter/issues/118073#issue-1521699748
99 std::vector<DlColor> colors = {DlColor(0xFFCCCCCC), DlColor(0xFF333333)};
100 std::vector<Scalar> stops = {0.0, 1.0};
101
103 {0, 0}, {800, 500}, 2, colors.data(), stops.data(), DlTileMode::kClamp));
104 builder.DrawRect(DlRect::MakeXYWH(0, 0, 800, 500), paint);
105 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
106}
107
108TEST_P(AiksTest, CanRenderLinearGradientWithDitheringEnabled) {
110}
111
113 DisplayListBuilder builder;
114 DlPaint paint;
115 builder.Translate(100.0, 100.0);
116
117 // #FFF -> #000
118 std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
119 DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
120 std::vector<Scalar> stops = {0.0, 1.0};
121
123 {600, 600}, 600, 2, colors.data(), stops.data(), DlTileMode::kClamp));
124 builder.DrawRect(DlRect::MakeXYWH(0, 0, 1200, 1200), paint);
125 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
126}
127
128TEST_P(AiksTest, CanRenderRadialGradientWithDitheringEnabled) {
130}
131
133 DisplayListBuilder builder;
134 builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
135 DlPaint paint;
136 builder.Translate(100.0, 100.0);
137
138 // #FFF -> #000
139 std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
140 DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
141 std::vector<Scalar> stops = {0.0, 1.0};
142
144 {100, 100}, /*start=*/45, /*end=*/135, 2, colors.data(), stops.data(),
145 DlTileMode::kMirror));
146
147 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
148 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
149}
150
151TEST_P(AiksTest, CanRenderSweepGradientWithDitheringEnabled) {
153}
154
156 DisplayListBuilder builder;
157 builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
158 DlPaint paint;
159 builder.Translate(100.0, 100.0);
160
161 // #FFF -> #000
162 std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
163 DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
164 std::vector<Scalar> stops = {0.0, 1.0};
165
166 paint.setColorSource(DlColorSource::MakeConical({0, 1}, 0, {100, 100}, 100, 2,
167 colors.data(), stops.data(),
168 DlTileMode::kMirror));
169
170 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
171 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
172}
173
174TEST_P(AiksTest, CanRenderConicalGradientWithDitheringEnabled) {
176}
177
178namespace {
179void CanRenderLinearGradientWithOverlappingStops(AiksTest* aiks_test,
180 DlTileMode tile_mode) {
181 DisplayListBuilder builder;
182 DlPaint paint;
183 builder.Translate(100.0, 100.0);
184
185 std::vector<DlColor> colors = {
186 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
187 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
188 DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB()),
189 DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
190 std::vector<Scalar> stops = {0.0, 0.5, 0.5, 1.0};
191
192 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {500, 500},
193 stops.size(), colors.data(),
194 stops.data(), tile_mode));
195
196 paint.setColor(DlColor::kWhite());
197 builder.DrawRect(DlRect::MakeXYWH(0, 0, 500, 500), paint);
198 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
199}
200} // namespace
201
202// Only clamp is necessary. All tile modes are the same output.
203TEST_P(AiksTest, CanRenderLinearGradientWithOverlappingStopsClamp) {
204 CanRenderLinearGradientWithOverlappingStops(this, DlTileMode::kClamp);
205}
206
207namespace {
208void CanRenderGradientWithIncompleteStops(AiksTest* aiks_test,
210 const DlTileMode tile_modes[4] = {
211 DlTileMode::kClamp,
212 DlTileMode::kRepeat,
213 DlTileMode::kMirror,
214 DlTileMode::kDecal,
215 };
216 const DlScalar test_size = 250;
217 const DlScalar test_border = 25;
218 const DlScalar gradient_size = 50;
219 const DlScalar quadrant_size = test_size + test_border * 2;
220
221 DisplayListBuilder builder;
222 builder.DrawRect(DlRect::MakeWH(quadrant_size * 2, quadrant_size * 2),
223 DlPaint().setColor(DlColor::kDarkGrey()));
224
225 for (int quadrant = 0; quadrant < 4; quadrant++) {
226 builder.Save();
227 builder.Translate((quadrant & 1) * quadrant_size + test_border,
228 (quadrant >> 1) * quadrant_size + test_border);
229
230 if (type == DlColorSourceType::kLinearGradient) {
231 // Alignment lines for the gradient edges/repeats/mirrors/etc.
232 // (rendered under the gradient so as not to obscure it)
233 DlPoint center = DlPoint(test_size, test_size) * 0.5;
234 DlScalar ten_percent = gradient_size * 0.1;
235 for (int i = gradient_size / 2; i <= test_size / 2; i += gradient_size) {
236 auto draw_at = [=](DlCanvas& canvas, DlScalar offset, DlColor color) {
237 DlPaint line_paint;
238 line_paint.setColor(color);
239 // strokewidth of 2 straddles the dividing line
240 line_paint.setStrokeWidth(2.0f);
241 line_paint.setDrawStyle(DlDrawStyle::kStroke);
242
243 DlPoint along(offset, offset);
244 DlScalar across_distance = test_size / 2 + 10 - offset;
245 DlPoint across(across_distance, -across_distance);
246
247 canvas.DrawLine(center - along - across, //
248 center - along + across, //
249 line_paint);
250 canvas.DrawLine(center + along - across, //
251 center + along + across, //
252 line_paint);
253 };
254 // White line is at the edge of the gradient
255 // Grey lines are where the 0.1 and 0.9 color stops land
256 draw_at(builder, i - ten_percent, DlColor::kMidGrey());
257 draw_at(builder, i, DlColor::kWhite());
258 draw_at(builder, i + ten_percent, DlColor::kMidGrey());
259 }
260 }
261
262 std::vector<DlColor> colors = {
267 };
268 std::vector<Scalar> stops = {0.1, 0.3, 0.7, 0.9};
269
270 DlPaint paint;
271 switch (type) {
272 case DlColorSourceType::kLinearGradient:
274 {test_size / 2 - gradient_size / 2,
275 test_size / 2 - gradient_size / 2},
276 {test_size / 2 + gradient_size / 2,
277 test_size / 2 + gradient_size / 2},
278 stops.size(), colors.data(), stops.data(), tile_modes[quadrant]));
279 break;
280 case DlColorSourceType::kRadialGradient:
282 {test_size / 2, test_size / 2}, gradient_size, //
283 stops.size(), colors.data(), stops.data(), tile_modes[quadrant]));
284 break;
285 case DlColorSourceType::kConicalGradient:
287 {test_size / 2, test_size / 2}, 0,
288 {test_size / 2 + 20, test_size / 2 - 10}, gradient_size,
289 stops.size(), colors.data(), stops.data(), tile_modes[quadrant]));
290 break;
291 case DlColorSourceType::kSweepGradient:
293 {test_size / 2, test_size / 2}, 0, 45, //
294 stops.size(), colors.data(), stops.data(), tile_modes[quadrant]));
295 break;
296 default:
298 }
299
300 builder.DrawRect(DlRect::MakeXYWH(0, 0, test_size, test_size), paint);
301 builder.Restore();
302 }
303
304 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
305}
306} // namespace
307
308TEST_P(AiksTest, CanRenderLinearGradientWithIncompleteStops) {
309 CanRenderGradientWithIncompleteStops(this,
310 DlColorSourceType::kLinearGradient);
311}
312TEST_P(AiksTest, CanRenderRadialGradientWithIncompleteStops) {
313 CanRenderGradientWithIncompleteStops(this,
314 DlColorSourceType::kRadialGradient);
315}
316TEST_P(AiksTest, CanRenderConicalGradientWithIncompleteStops) {
317 CanRenderGradientWithIncompleteStops(this,
318 DlColorSourceType::kConicalGradient);
319}
320TEST_P(AiksTest, CanRenderSweepGradientWithIncompleteStops) {
321 CanRenderGradientWithIncompleteStops(this, DlColorSourceType::kSweepGradient);
322}
323
324namespace {
325void CanRenderLinearGradientManyColors(AiksTest* aiks_test,
326 DlTileMode tile_mode) {
327 DisplayListBuilder builder;
328 builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
329 DlPaint paint;
330 builder.Translate(100, 100);
331
332 std::vector<DlColor> colors = {
333 DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
334 DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
335 DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
336 DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
337 DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
338 DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
339 DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
340 std::vector<Scalar> stops = {
341 0.0,
342 (1.0 / 6.0) * 1,
343 (1.0 / 6.0) * 2,
344 (1.0 / 6.0) * 3,
345 (1.0 / 6.0) * 4,
346 (1.0 / 6.0) * 5,
347 1.0,
348 };
349
350 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {200, 200},
351 stops.size(), colors.data(),
352 stops.data(), tile_mode));
353
354 paint.setColor(DlColor::kWhite());
355 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
356 builder.Restore();
357 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
358}
359} // namespace
360
361TEST_P(AiksTest, CanRenderLinearGradientManyColorsClamp) {
362 CanRenderLinearGradientManyColors(this, DlTileMode::kClamp);
363}
364TEST_P(AiksTest, CanRenderLinearGradientManyColorsRepeat) {
365 CanRenderLinearGradientManyColors(this, DlTileMode::kRepeat);
366}
367TEST_P(AiksTest, CanRenderLinearGradientManyColorsMirror) {
368 CanRenderLinearGradientManyColors(this, DlTileMode::kMirror);
369}
370TEST_P(AiksTest, CanRenderLinearGradientManyColorsDecal) {
371 CanRenderLinearGradientManyColors(this, DlTileMode::kDecal);
372}
373
374namespace {
375void CanRenderLinearGradientWayManyColors(AiksTest* aiks_test,
376 DlTileMode tile_mode) {
377 DisplayListBuilder builder;
378 DlPaint paint;
379 builder.Translate(100.0, 100.0);
380 auto color = DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB());
381 std::vector<DlColor> colors;
382 std::vector<Scalar> stops;
383 auto current_stop = 0.0;
384 for (int i = 0; i < 2000; i++) {
385 colors.push_back(color);
386 stops.push_back(current_stop);
387 current_stop += 1 / 2000.0;
388 }
389 stops[2000 - 1] = 1.0;
390
391 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {200, 200},
392 stops.size(), colors.data(),
393 stops.data(), tile_mode));
394
395 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
396 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
397}
398} // namespace
399
400// Only test clamp on purpose since they all look the same.
401TEST_P(AiksTest, CanRenderLinearGradientWayManyColorsClamp) {
402 CanRenderLinearGradientWayManyColors(this, DlTileMode::kClamp);
403}
404
405TEST_P(AiksTest, CanRenderLinearGradientManyColorsUnevenStops) {
406 auto callback = [&]() -> sk_sp<DisplayList> {
407 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
408 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
409 DlTileMode::kMirror, DlTileMode::kDecal};
410
411 static int selected_tile_mode = 0;
412 static Matrix matrix;
413 if (AiksTest::ImGuiBegin("Controls", nullptr,
414 ImGuiWindowFlags_AlwaysAutoResize)) {
415 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
416 sizeof(tile_mode_names) / sizeof(char*));
417 std::string label = "##1";
418 for (int i = 0; i < 4; i++) {
419 ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
420 &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
421 label[2]++;
422 }
423 ImGui::End();
424 }
425
426 DisplayListBuilder builder;
427 DlPaint paint;
428 builder.Translate(100.0, 100.0);
429 auto tile_mode = tile_modes[selected_tile_mode];
430
431 std::vector<DlColor> colors = {
432 DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
433 DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
434 DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
435 DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
436 DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
437 DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
438 DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
439 std::vector<Scalar> stops = {
440 0.0, 2.0 / 62.0, 4.0 / 62.0, 8.0 / 62.0, 16.0 / 62.0, 32.0 / 62.0, 1.0,
441 };
442
443 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {200, 200},
444 stops.size(), colors.data(),
445 stops.data(), tile_mode));
446
447 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
448 return builder.Build();
449 };
450 ASSERT_TRUE(OpenPlaygroundHere(callback));
451}
452
453TEST_P(AiksTest, CanRenderLinearGradientMaskBlur) {
454 DisplayListBuilder builder;
455
456 std::vector<DlColor> colors = {
460 std::vector<Scalar> stops = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5,
461 0.6, 0.7, 0.8, 0.9, 1.0};
462
463 DlPaint paint;
464 paint.setColor(DlColor::kWhite());
466 {200, 200}, {400, 400}, stops.size(), colors.data(), stops.data(),
467 DlTileMode::kClamp));
468 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
469
470 builder.DrawCircle(DlPoint(300, 300), 200, paint);
471 builder.DrawRect(DlRect::MakeLTRB(100, 300, 500, 600), paint);
472
473 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
474}
475
476TEST_P(AiksTest, CanRenderRadialGradient) {
477 auto callback = [&]() -> sk_sp<DisplayList> {
478 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
479 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
480 DlTileMode::kMirror, DlTileMode::kDecal};
481
482 static int selected_tile_mode = 0;
483 static Matrix matrix;
484 if (AiksTest::ImGuiBegin("Controls", nullptr,
485 ImGuiWindowFlags_AlwaysAutoResize)) {
486 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
487 sizeof(tile_mode_names) / sizeof(char*));
488 std::string label = "##1";
489 for (int i = 0; i < 4; i++) {
490 ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
491 &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
492 label[2]++;
493 }
494 ImGui::End();
495 }
496
497 DisplayListBuilder builder;
498 DlPaint paint;
499 builder.Translate(100.0, 100.0);
500 auto tile_mode = tile_modes[selected_tile_mode];
501
502 std::vector<DlColor> colors = {
503 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
504 DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
505 std::vector<Scalar> stops = {0.0, 1.0};
506
508 {100, 100}, 100, 2, colors.data(), stops.data(), tile_mode));
509
510 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
511 return builder.Build();
512 };
513 ASSERT_TRUE(OpenPlaygroundHere(callback));
514}
515
516TEST_P(AiksTest, CanRenderRadialGradientManyColors) {
517 auto callback = [&]() -> sk_sp<DisplayList> {
518 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
519 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
520 DlTileMode::kMirror, DlTileMode::kDecal};
521
522 static int selected_tile_mode = 0;
523 static Matrix matrix = {
524 1, 0, 0, 0, //
525 0, 1, 0, 0, //
526 0, 0, 1, 0, //
527 0, 0, 0, 1 //
528 };
529 if (AiksTest::ImGuiBegin("Controls", nullptr,
530 ImGuiWindowFlags_AlwaysAutoResize)) {
531 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
532 sizeof(tile_mode_names) / sizeof(char*));
533 std::string label = "##1";
534 for (int i = 0; i < 4; i++) {
535 ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
536 &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
537 label[2]++;
538 }
539 ImGui::End();
540 }
541
542 DisplayListBuilder builder;
543 DlPaint paint;
544 builder.Translate(100.0, 100.0);
545 auto tile_mode = tile_modes[selected_tile_mode];
546
547 std::vector<DlColor> colors = {
548 DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
549 DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
550 DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
551 DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
552 DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
553 DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
554 DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
555 std::vector<Scalar> stops = {
556 0.0,
557 (1.0 / 6.0) * 1,
558 (1.0 / 6.0) * 2,
559 (1.0 / 6.0) * 3,
560 (1.0 / 6.0) * 4,
561 (1.0 / 6.0) * 5,
562 1.0,
563 };
564
566 {100, 100}, 100, stops.size(), colors.data(), stops.data(), tile_mode));
567
568 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
569 return builder.Build();
570 };
571 ASSERT_TRUE(OpenPlaygroundHere(callback));
572}
573
574namespace {
575void CanRenderSweepGradient(AiksTest* aiks_test, DlTileMode tile_mode) {
576 DisplayListBuilder builder;
577 builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
578 DlPaint paint;
579 builder.Translate(100, 100);
580
581 std::vector<DlColor> colors = {
582 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
583 DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
584 std::vector<Scalar> stops = {0.0, 1.0};
585
587 {100, 100}, /*start=*/45, /*end=*/135, /*stop_count=*/2, colors.data(),
588 stops.data(), tile_mode));
589
590 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
591 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
592}
593} // namespace
594
595TEST_P(AiksTest, CanRenderSweepGradientClamp) {
596 CanRenderSweepGradient(this, DlTileMode::kClamp);
597}
598TEST_P(AiksTest, CanRenderSweepGradientRepeat) {
599 CanRenderSweepGradient(this, DlTileMode::kRepeat);
600}
601TEST_P(AiksTest, CanRenderSweepGradientMirror) {
602 CanRenderSweepGradient(this, DlTileMode::kMirror);
603}
604TEST_P(AiksTest, CanRenderSweepGradientDecal) {
605 CanRenderSweepGradient(this, DlTileMode::kDecal);
606}
607
608namespace {
609void CanRenderSweepGradientManyColors(AiksTest* aiks_test,
610 DlTileMode tile_mode) {
611 DisplayListBuilder builder;
612 DlPaint paint;
613 builder.Translate(100.0, 100.0);
614
615 std::vector<DlColor> colors = {
616 DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
617 DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
618 DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
619 DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
620 DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
621 DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
622 DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
623 std::vector<Scalar> stops = {
624 0.0,
625 (1.0 / 6.0) * 1,
626 (1.0 / 6.0) * 2,
627 (1.0 / 6.0) * 3,
628 (1.0 / 6.0) * 4,
629 (1.0 / 6.0) * 5,
630 1.0,
631 };
632
633 paint.setColorSource(DlColorSource::MakeSweep({100, 100}, 45, 135,
634 stops.size(), colors.data(),
635 stops.data(), tile_mode));
636
637 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
638 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
639}
640} // namespace
641
642TEST_P(AiksTest, CanRenderSweepGradientManyColorsClamp) {
643 CanRenderSweepGradientManyColors(this, DlTileMode::kClamp);
644}
645TEST_P(AiksTest, CanRenderSweepGradientManyColorsRepeat) {
646 CanRenderSweepGradientManyColors(this, DlTileMode::kRepeat);
647}
648TEST_P(AiksTest, CanRenderSweepGradientManyColorsMirror) {
649 CanRenderSweepGradientManyColors(this, DlTileMode::kMirror);
650}
651TEST_P(AiksTest, CanRenderSweepGradientManyColorsDecal) {
652 CanRenderSweepGradientManyColors(this, DlTileMode::kDecal);
653}
654
655TEST_P(AiksTest, CanRenderConicalGradient) {
656 Scalar size = 256;
657 DisplayListBuilder builder;
658 DlPaint paint;
659 paint.setColor(DlColor::kWhite());
660 builder.DrawRect(DlRect::MakeXYWH(0, 0, size * 3, size * 3), paint);
661 std::vector<DlColor> colors = {
662 DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
663 DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
664 DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
665 DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
666 std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
667 std::array<std::tuple<DlPoint, float, DlPoint, float>, 8> array{
668 std::make_tuple(DlPoint(size / 2.f, size / 2.f), 0.f,
669 DlPoint(size / 2.f, size / 2.f), size / 2.f),
670 std::make_tuple(DlPoint(size / 2.f, size / 2.f), size / 4.f,
671 DlPoint(size / 2.f, size / 2.f), size / 2.f),
672 std::make_tuple(DlPoint(size / 4.f, size / 4.f), 0.f,
673 DlPoint(size / 2.f, size / 2.f), size / 2.f),
674 std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 2.f,
675 DlPoint(size / 2.f, size / 2.f), 0),
676 std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 4.f,
677 DlPoint(size / 2.f, size / 2.f), size / 2.f),
678 std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 16.f,
679 DlPoint(size / 2.f, size / 2.f), size / 8.f),
680 std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 8.f,
681 DlPoint(size / 2.f, size / 2.f), size / 16.f),
682 std::make_tuple(DlPoint(size / 8.f, size / 8.f), size / 8.f,
683 DlPoint(size / 2.f, size / 2.f), size / 8.f),
684 };
685 for (int i = 0; i < 8; i++) {
686 builder.Save();
687 builder.Translate((i % 3) * size, i / 3 * size);
689 /*start_center=*/std::get<2>(array[i]),
690 /*start_radius=*/std::get<3>(array[i]),
691 /*end_center=*/std::get<0>(array[i]),
692 /*end_radius=*/std::get<1>(array[i]),
693 /*stop_count=*/stops.size(),
694 /*colors=*/colors.data(),
695 /*stops=*/stops.data(),
696 /*tile_mode=*/DlTileMode::kClamp));
697 builder.DrawRect(DlRect::MakeXYWH(0, 0, size, size), paint);
698 builder.Restore();
699 }
700 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
701}
702
703TEST_P(AiksTest, CanRenderGradientDecalWithBackground) {
704 std::vector<DlColor> colors = {
705 DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
706 DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
707 DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
708 DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
709 std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
710
711 std::array<std::shared_ptr<DlColorSource>, 3> color_sources = {
712 DlColorSource::MakeLinear({0, 0}, {100, 100}, stops.size(), colors.data(),
713 stops.data(), DlTileMode::kDecal),
714 DlColorSource::MakeRadial({100, 100}, 100, stops.size(), colors.data(),
715 stops.data(), DlTileMode::kDecal),
716 DlColorSource::MakeSweep({100, 100}, 45, 135, stops.size(), colors.data(),
717 stops.data(), DlTileMode::kDecal),
718 };
719
720 DisplayListBuilder builder;
721 DlPaint paint;
722 paint.setColor(DlColor::kWhite());
723 builder.DrawRect(DlRect::MakeLTRB(0, 0, 605, 205), paint);
724 for (int i = 0; i < 3; i++) {
725 builder.Save();
726 builder.Translate(i * 200.0f, 0);
727 paint.setColorSource(color_sources[i]);
728 builder.DrawRect(DlRect::MakeLTRB(0, 0, 200, 200), paint);
729 builder.Restore();
730 }
731 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
732}
733
734TEST_P(AiksTest, GradientStrokesRenderCorrectly) {
735 // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
736 auto callback = [&]() -> sk_sp<DisplayList> {
737 static float scale = 3;
738 static bool add_circle_clip = true;
739 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
740 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
741 DlTileMode::kMirror, DlTileMode::kDecal};
742 static int selected_tile_mode = 0;
743 static float alpha = 1;
744
745 if (AiksTest::ImGuiBegin("Controls", nullptr,
746 ImGuiWindowFlags_AlwaysAutoResize)) {
747 ImGui::SliderFloat("Scale", &scale, 0, 6);
748 ImGui::Checkbox("Circle clip", &add_circle_clip);
749 ImGui::SliderFloat("Alpha", &alpha, 0, 1);
750 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
751 sizeof(tile_mode_names) / sizeof(char*));
752 ImGui::End();
753 }
754
755 DisplayListBuilder builder;
756 builder.Scale(GetContentScale().x, GetContentScale().y);
757 DlPaint paint;
758 paint.setColor(DlColor::kWhite());
759 builder.DrawPaint(paint);
760
761 paint.setDrawStyle(DlDrawStyle::kStroke);
762 paint.setColor(DlColor::kWhite().withAlpha(alpha * 255));
763 paint.setStrokeWidth(10);
764 auto tile_mode = tile_modes[selected_tile_mode];
765
766 std::vector<DlColor> colors = {
767 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
768 DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
769 std::vector<Scalar> stops = {0.0, 1.0};
770
771 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {50, 50},
772 stops.size(), colors.data(),
773 stops.data(), tile_mode));
774
775 DlPathBuilder path_builder;
776 path_builder.MoveTo(DlPoint(20, 20));
777 path_builder.QuadraticCurveTo(DlPoint(60, 20), DlPoint(60, 60));
778 path_builder.Close();
779 path_builder.MoveTo(DlPoint(60, 20));
780 path_builder.QuadraticCurveTo(DlPoint(60, 60), DlPoint(20, 60));
781 DlPath path = path_builder.TakePath();
782
783 builder.Scale(scale, scale);
784
785 if (add_circle_clip) {
786 static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
787 Color::Red());
788 static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
789 Color::Red());
790 auto [handle_a, handle_b] =
791 DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
792
793 Matrix ip_matrix = builder.GetMatrix();
794 if (!ip_matrix.IsInvertible()) {
795 return nullptr;
796 }
797 ip_matrix = ip_matrix.Invert();
798 Point point_a = ip_matrix * handle_a * GetContentScale();
799 Point point_b = ip_matrix * handle_b * GetContentScale();
800
801 Point middle = (point_a + point_b) / 2;
802 auto radius = point_a.GetDistance(middle);
803 builder.ClipPath(DlPath::MakeCircle(middle, radius));
804 }
805
806 for (auto join :
807 {DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
808 paint.setStrokeJoin(join);
809 for (auto cap :
810 {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
811 paint.setStrokeCap(cap);
812 builder.DrawPath(path, paint);
813 builder.Translate(80, 0);
814 }
815 builder.Translate(-240, 60);
816 }
817
818 return builder.Build();
819 };
820
821 ASSERT_TRUE(OpenPlaygroundHere(callback));
822}
823
824// Draws two gradients that should look identical (except that one is an RRECT).
825TEST_P(AiksTest, FastGradientTestHorizontal) {
826 DisplayListBuilder builder;
827 DlPaint paint;
828 builder.Translate(100.0f, 0);
829
830 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
832 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
833
834 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {300, 0}, stops.size(),
835 colors.data(), stops.data(),
836 DlTileMode::kClamp));
837
838 paint.setColor(DlColor::kWhite());
839 builder.DrawRect(DlRect::MakeXYWH(0, 0, 300, 300), paint);
840 builder.Translate(400, 0);
841 builder.DrawRoundRect(
842 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 300, 300), 4, 4), paint);
843
844 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
845}
846
847// Draws two gradients that should look identical (except that one is an RRECT).
848TEST_P(AiksTest, FastGradientTestVertical) {
849 DisplayListBuilder builder;
850 DlPaint paint;
851 builder.Translate(100.0f, 0);
852
853 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
855 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
856
857 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {0, 300}, stops.size(),
858 colors.data(), stops.data(),
859 DlTileMode::kClamp));
860
861 paint.setColor(DlColor::kWhite());
862 builder.DrawRect(DlRect::MakeXYWH(0, 0, 300, 300), paint);
863 builder.Translate(400, 0);
864 builder.DrawRoundRect(
865 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 300, 300), 4, 4), paint);
866
867 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
868}
869
870// Draws two gradients that should look identical (except that one is an RRECT).
871TEST_P(AiksTest, FastGradientTestHorizontalReversed) {
872 DisplayListBuilder builder;
873 DlPaint paint;
874 builder.Translate(100.0f, 0);
875
876 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
878 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
879
880 paint.setColorSource(DlColorSource::MakeLinear({300, 0}, {0, 0}, stops.size(),
881 colors.data(), stops.data(),
882 DlTileMode::kClamp));
883
884 paint.setColor(DlColor::kWhite());
885 builder.DrawRect(DlRect::MakeXYWH(0, 0, 300, 300), paint);
886 builder.Translate(400, 0);
887 builder.DrawRoundRect(
888 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 300, 300), 4, 4), paint);
889
890 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
891}
892
893// Draws two gradients that should look identical (except that one is an RRECT).
894TEST_P(AiksTest, FastGradientTestVerticalReversed) {
895 DisplayListBuilder builder;
896 DlPaint paint;
897 builder.Translate(100.0f, 0);
898
899 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
901 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
902
903 paint.setColorSource(DlColorSource::MakeLinear({0, 300}, {0, 0}, stops.size(),
904 colors.data(), stops.data(),
905 DlTileMode::kClamp));
906
907 paint.setColor(DlColor::kWhite());
908 builder.DrawRect(DlRect::MakeXYWH(0, 0, 300, 300), paint);
909 builder.Translate(400, 0);
910 builder.DrawRoundRect(
911 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 300, 300), 4, 4), paint);
912
913 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
914}
915
916TEST_P(AiksTest, VerifyNonOptimizedGradient) {
917 DisplayListBuilder builder;
918 DlPaint paint;
919 builder.Translate(100.0f, 0);
920
921 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
923 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
924
925 // Inset the start and end point to verify that we do not apply
926 // the fast gradient condition.
927 paint.setColorSource(
928 DlColorSource::MakeLinear({0, 150}, {0, 100}, stops.size(), colors.data(),
929 stops.data(), DlTileMode::kRepeat));
930
931 paint.setColor(DlColor::kWhite());
932 builder.DrawRect(DlRect::MakeXYWH(0, 0, 300, 300), paint);
933 builder.Translate(400, 0);
934 builder.DrawRoundRect(
935 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 300, 300), 4, 4), paint);
936
937 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
938}
939
940} // namespace testing
941} // namespace impeller
GLenum type
void DrawRoundRect(const DlRoundRect &rrect, const DlPaint &paint) override
DlMatrix GetMatrix() const override
Definition dl_builder.h:102
void DrawCircle(const DlPoint &center, DlScalar radius, const DlPaint &paint) 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 DrawRect(const DlRect &rect, const DlPaint &paint) override
static std::shared_ptr< DlMaskFilter > Make(DlBlurStyle style, SkScalar sigma, bool respect_ctm=true)
Developer-facing API for rendering anything within the engine.
Definition dl_canvas.h:32
virtual void DrawLine(const DlPoint &p0, const DlPoint &p1, const DlPaint &paint)=0
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 > MakeLinear(const DlPoint start_point, const DlPoint end_point, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, const DlMatrix *matrix=nullptr)
static std::shared_ptr< DlColorSource > MakeConical(DlPoint start_center, DlScalar start_radius, DlPoint end_center, DlScalar end_radius, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, 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 & MoveTo(DlPoint p2)
Start a new contour that will originate at the indicated point p2.
const DlPath TakePath()
Returns the path constructed by this path builder and resets its internal state to the default state ...
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 ...
static DlPath MakeCircle(const DlPoint center, DlScalar radius)
Definition dl_path.cc:68
double x() const
Definition geometry.h:22
double y() const
Definition geometry.h:23
bool OpenPlaygroundHere(const AiksDlPlaygroundCallback &callback)
static bool ImGuiBegin(const char *name, bool *p_open, ImGuiWindowFlags flags)
Point GetContentScale() const
int32_t x
FlutterDesktopBinaryReply callback
#define FML_UNREACHABLE()
Definition logging.h:128
double y
impeller::Scalar DlScalar
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
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
AiksPlayground AiksTest
static void CanRenderLinearGradientWithDithering(AiksTest *aiks_test)
static void CanRenderRadialGradientWithDithering(AiksTest *aiks_test)
TEST_P(AiksTest, DrawAtlasNoColor)
static void CanRenderConicalGradientWithDithering(AiksTest *aiks_test)
static void CanRenderSweepGradientWithDithering(AiksTest *aiks_test)
float Scalar
Definition scalar.h:19
std::tuple< Point, Point > DrawPlaygroundLine(PlaygroundPoint &point_a, PlaygroundPoint &point_b)
Definition widgets.cc:51
static constexpr DlColor kWhite()
Definition dl_color.h:70
static constexpr DlColor kBlue()
Definition dl_color.h:73
static constexpr DlColor kPurple()
Definition dl_color.h:88
static constexpr DlColor kMidGrey()
Definition dl_color.h:78
static constexpr DlColor kRed()
Definition dl_color.h:71
static constexpr DlColor kGreen()
Definition dl_color.h:72
static constexpr DlColor kOrange()
Definition dl_color.h:87
static constexpr DlColor kDarkGrey()
Definition dl_color.h:77
uint32_t ToARGB() const
Convert to ARGB 32 bit color.
Definition color.h:259
static constexpr Color Red()
Definition color.h:272
static constexpr Color MakeRGBA8(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
Definition color.h:152
A 4x4 matrix using column-major storage.
Definition matrix.h:37
bool IsInvertible() const
Definition matrix.h:321
Matrix Invert() const
Definition matrix.cc:99
Vector4 vec[4]
Definition matrix.h:41
static RoundRect MakeRectXY(const Rect &rect, Scalar x_radius, Scalar y_radius)
Definition round_rect.h:31
static constexpr TRect MakeWH(Type width, Type height)
Definition rect.h:140
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition rect.h:136
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129