| Flutter Impeller |

aiks_dl_text_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
5 #include "display_list/display_list.h"
6 #include "display_list/dl_blend_mode.h"
7 #include "display_list/dl_tile_mode.h"
8 #include "display_list/effects/dl_color_source.h"
9 #include "display_list/effects/dl_mask_filter.h"
10 #include "flutter/display_list/dl_builder.h"
11 #include "flutter/display_list/dl_color.h"
12 #include "flutter/display_list/dl_paint.h"
13 #include "flutter/fml/build_config.h"
14 #include "flutter/impeller/display_list/aiks_unittests.h"
15 #include "flutter/testing/testing.h"
16 #include "impeller/geometry/matrix.h"
17 #include "impeller/typographer/backends/skia/text_frame_skia.h"
18 #include "include/core/SkMatrix.h"
19 #include "include/core/SkRect.h"
20
21 #include "txt/platform.h"
22
23 using namespace flutter;
24 /////////////////////////////////////////////////////
25
26 namespace impeller {
27 namespace testing {
28
29 struct TextRenderOptions {
30 bool stroke = false;
31 Scalar font_size = 50;
32 Scalar stroke_width = 1;
33 DlColor color = DlColor::kYellow();
34 SkPoint position = SkPoint::Make(100, 200);
35 std::shared_ptr<DlMaskFilter> filter;
36 bool is_subpixel = false;
37 };
38
39 bool RenderTextInCanvasSkia(const std::shared_ptr<Context>& context,
40 DisplayListBuilder& canvas,
41 const std::string& text,
42 const std::string_view& font_fixture,
43 const TextRenderOptions& options = {}) {
44 // Draw the baseline.
45 DlPaint paint;
46 paint.setColor(DlColor::kAqua().withAlpha(255 * 0.25));
47 canvas.DrawRect(SkRect::MakeXYWH(options.position.x() - 50,
48 options.position.y(), 900, 10),
49 paint);
50
51 // Mark the point at which the text is drawn.
52 paint.setColor(DlColor::kRed().withAlpha(255 * 0.25));
53 canvas.DrawCircle(options.position, 5.0, paint);
54
55 // Construct the text blob.
56 auto c_font_fixture = std::string(font_fixture);
57 auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
58 if (!mapping) {
59 return false;
60 }
61 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
62 SkFont sk_font(font_mgr->makeFromData(mapping), options.font_size);
63 if (options.is_subpixel) {
64 sk_font.setSubpixel(true);
65 }
66 auto blob = SkTextBlob::MakeFromString(text.c_str(), sk_font);
67 if (!blob) {
68 return false;
69 }
70
71 // Create the Impeller text frame and draw it at the designated baseline.
72 auto frame = MakeTextFrameFromTextBlobSkia(blob);
73
74 DlPaint text_paint;
75 text_paint.setColor(options.color);
76 text_paint.setMaskFilter(options.filter);
77 text_paint.setStrokeWidth(options.stroke_width);
78 text_paint.setDrawStyle(options.stroke ? DlDrawStyle::kStroke
79 : DlDrawStyle::kFill);
80 canvas.DrawTextFrame(frame, options.position.x(), options.position.y(),
81 text_paint);
82 return true;
83 }
84
85 TEST_P(AiksTest, CanRenderTextFrame) {
86 DisplayListBuilder builder;
87
88 DlPaint paint;
89 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
90 builder.DrawPaint(paint);
91 ASSERT_TRUE(RenderTextInCanvasSkia(
92 GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
93 "Roboto-Regular.ttf"));
94
95 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
96 }
97
98 TEST_P(AiksTest, CanRenderTextFrameWithInvertedTransform) {
99 DisplayListBuilder builder;
100
101 DlPaint paint;
102 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
103 builder.DrawPaint(paint);
104 builder.Translate(1000, 0);
105 builder.Scale(-1, 1);
106
107 ASSERT_TRUE(RenderTextInCanvasSkia(
108 GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
109 "Roboto-Regular.ttf"));
110
111 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
112 }
113
114 TEST_P(AiksTest, CanRenderStrokedTextFrame) {
115 DisplayListBuilder builder;
116
117 DlPaint paint;
118 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
119 builder.DrawPaint(paint);
120
121 ASSERT_TRUE(RenderTextInCanvasSkia(
122 GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
123 "Roboto-Regular.ttf",
124 {
125 .stroke = true,
126 }));
127 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
128 }
129
130 TEST_P(AiksTest, CanRenderTextStrokeWidth) {
131 DisplayListBuilder builder;
132
133 DlPaint paint;
134 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
135 builder.DrawPaint(paint);
136
137 ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "LMNOP VWXYZ",
138 "Roboto-Medium.ttf",
139 {
140 .stroke = true,
141 .stroke_width = 4,
142 }));
143 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
144 }
145
146 TEST_P(AiksTest, CanRenderTextFrameWithHalfScaling) {
147 DisplayListBuilder builder;
148
149 DlPaint paint;
150 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
151 builder.DrawPaint(paint);
152 builder.Scale(0.5, 0.5);
153
154 ASSERT_TRUE(RenderTextInCanvasSkia(
155 GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
156 "Roboto-Regular.ttf"));
157 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
158 }
159
160 TEST_P(AiksTest, CanRenderTextFrameWithFractionScaling) {
161 Scalar fine_scale = 0.f;
162 bool is_subpixel = false;
163 auto callback = [&]() -> sk_sp<DisplayList> {
164 if (AiksTest::ImGuiBegin("Controls", nullptr,
165 ImGuiWindowFlags_AlwaysAutoResize)) {
166 ImGui::SliderFloat("Fine Scale", &fine_scale, -1, 1);
167 ImGui::Checkbox("subpixel", &is_subpixel);
168 ImGui::End();
169 }
170
171 DisplayListBuilder builder;
172 DlPaint paint;
173 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
174 builder.DrawPaint(paint);
175 Scalar scale = 2.625 + fine_scale;
176 builder.Scale(scale, scale);
177 RenderTextInCanvasSkia(GetContext(), builder,
178 "the quick brown fox jumped over the lazy dog!.?",
179 "Roboto-Regular.ttf",
180 TextRenderOptions{.is_subpixel = is_subpixel});
181 return builder.Build();
182 };
183
184 ASSERT_TRUE(OpenPlaygroundHere(callback));
185 }
186
187 TEST_P(AiksTest, TextFrameSubpixelAlignment) {
188 // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens.
189 std::array<Scalar, 20> phase_offsets = {
190 7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
191 0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
192 0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
193 0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
194 auto callback = [&]() -> sk_sp<DisplayList> {
195 static float font_size = 20;
196 static float phase_variation = 0.2;
197 static float speed = 0.5;
198 static float magnitude = 100;
199 if (AiksTest::ImGuiBegin("Controls", nullptr,
200 ImGuiWindowFlags_AlwaysAutoResize)) {
201 ImGui::SliderFloat("Font size", &font_size, 5, 50);
202 ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1);
203 ImGui::SliderFloat("Oscillation speed", &speed, 0, 2);
204 ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300);
205 ImGui::End();
206 }
207
208 DisplayListBuilder builder;
209 builder.Scale(GetContentScale().x, GetContentScale().y);
210
211 for (size_t i = 0; i < phase_offsets.size(); i++) {
212 SkPoint position = SkPoint::Make(
213 200 +
214 magnitude * std::sin((-phase_offsets[i] * k2Pi * phase_variation +
215 GetSecondsElapsed() * speed)), //
216 200 + i * font_size * 1.1 //
217 );
218 if (!RenderTextInCanvasSkia(
219 GetContext(), builder,
220 "the quick brown fox jumped over "
221 "the lazy dog!.?",
222 "Roboto-Regular.ttf",
223 {.font_size = font_size, .position = position})) {
224 return nullptr;
225 }
226 }
227 return builder.Build();
228 };
229
230 ASSERT_TRUE(OpenPlaygroundHere(callback));
231 }
232
233 TEST_P(AiksTest, CanRenderItalicizedText) {
234 DisplayListBuilder builder;
235
236 DlPaint paint;
237 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
238 builder.DrawPaint(paint);
239
240 ASSERT_TRUE(RenderTextInCanvasSkia(
241 GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
242 "HomemadeApple.ttf"));
243 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
244 }
245
246 static constexpr std::string_view kFontFixture =
247 #if FML_OS_MACOSX
248 "Apple Color Emoji.ttc";
249 #else
250 "NotoColorEmoji.ttf";
251 #endif
252
253 TEST_P(AiksTest, CanRenderEmojiTextFrame) {
254 DisplayListBuilder builder;
255
256 DlPaint paint;
257 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
258 builder.DrawPaint(paint);
259
260 ASSERT_TRUE(RenderTextInCanvasSkia(
261 GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture));
262 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
263 }
264
265 TEST_P(AiksTest, CanRenderEmojiTextFrameWithBlur) {
266 DisplayListBuilder builder;
267
268 builder.Scale(GetContentScale().x, GetContentScale().y);
269 DlPaint paint;
270 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
271 builder.DrawPaint(paint);
272
273 ASSERT_TRUE(RenderTextInCanvasSkia(
274 GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
275 TextRenderOptions{
276 .color = DlColor::kBlue(),
277 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
278 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
279 }
280
281 TEST_P(AiksTest, CanRenderEmojiTextFrameWithAlpha) {
282 DisplayListBuilder builder;
283
284 DlPaint paint;
285 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
286 builder.DrawPaint(paint);
287
288 ASSERT_TRUE(RenderTextInCanvasSkia(
289 GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
290 {.color = DlColor::kBlack().modulateOpacity(0.5)}));
291 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
292 }
293
294 TEST_P(AiksTest, CanRenderTextInSaveLayer) {
295 DisplayListBuilder builder;
296
297 DlPaint paint;
298 paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1));
299 builder.DrawPaint(paint);
300
301 builder.Translate(100, 100);
302 builder.Scale(0.5, 0.5);
303
304 // Blend the layer with the parent pass using kClear to expose the coverage.
305 paint.setBlendMode(DlBlendMode::kClear);
306 builder.SaveLayer(nullptr, &paint);
307 ASSERT_TRUE(RenderTextInCanvasSkia(
308 GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
309 "Roboto-Regular.ttf"));
310 builder.Restore();
311
312 // Render the text again over the cleared coverage rect.
313 ASSERT_TRUE(RenderTextInCanvasSkia(
314 GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
315 "Roboto-Regular.ttf"));
316
317 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
318 }
319
320 TEST_P(AiksTest, CanRenderTextOutsideBoundaries) {
321 DisplayListBuilder builder;
322 builder.Translate(200, 150);
323
324 // Construct the text blob.
325 auto mapping = flutter::testing::OpenFixtureAsSkData("wtf.otf");
326 ASSERT_NE(mapping, nullptr);
327
328 Scalar font_size = 80;
329 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
330 SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
331
332 DlPaint text_paint;
333 text_paint.setColor(DlColor::kBlue().withAlpha(255 * 0.8));
334
335 struct {
336 SkPoint position;
337 const char* text;
338 } text[] = {{SkPoint::Make(0, 0), "0F0F0F0"},
339 {SkPoint::Make(1, 2), "789"},
340 {SkPoint::Make(1, 3), "456"},
341 {SkPoint::Make(1, 4), "123"},
342 {SkPoint::Make(0, 6), "0F0F0F0"}};
343 for (auto& t : text) {
344 builder.Save();
345 builder.Translate(t.position.x() * font_size * 2,
346 t.position.y() * font_size * 1.1);
347 {
348 auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
349 ASSERT_NE(blob, nullptr);
350 auto frame = MakeTextFrameFromTextBlobSkia(blob);
351 builder.DrawTextFrame(frame, 0, 0, text_paint);
352 }
353 builder.Restore();
354 }
355
356 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
357 }
358
359 TEST_P(AiksTest, TextRotated) {
360 DisplayListBuilder builder;
361
362 builder.Scale(GetContentScale().x, GetContentScale().y);
363 DlPaint paint;
364 paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 1.0));
365 builder.DrawPaint(paint);
366
367 builder.Transform(SkM44::ColMajor(Matrix(0.25, -0.3, 0, -0.002, //
368 0, 0.5, 0, 0, //
369 0, 0, 0.3, 0, //
370 100, 100, 0, 1.3)
371 .m));
372 ASSERT_TRUE(RenderTextInCanvasSkia(
373 GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
374 "Roboto-Regular.ttf"));
375
376 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
377 }
378
379 TEST_P(AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer) {
380 DisplayListBuilder builder;
381
382 Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, //
383 0.0, 1.0, 0.0, 0.0, //
384 0.0, 0.0, 1.0, 0.01, //
385 0.0, 0.0, 0.0, 1.0) * //
386 Matrix::MakeRotationY({Degrees{10}});
387
388 builder.Transform(SkM44::ColMajor(matrix.m));
389
390 ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
391 "Roboto-Regular.ttf"));
392 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
393 }
394
395 TEST_P(AiksTest, DrawScaledTextWithPerspectiveSaveLayer) {
396 DisplayListBuilder builder;
397
398 Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, //
399 0.0, 1.0, 0.0, 0.0, //
400 0.0, 0.0, 1.0, 0.01, //
401 0.0, 0.0, 0.0, 1.0) * //
402 Matrix::MakeRotationY({Degrees{10}});
403
404 DlPaint save_paint;
405 SkRect window_bounds =
406 SkRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
407 // Note: bounds were not needed by the AIKS version, which may indicate a bug.
408 builder.SaveLayer(&window_bounds, &save_paint);
409 builder.Transform(SkM44::ColMajor(matrix.m));
410
411 ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
412 "Roboto-Regular.ttf"));
413
414 builder.Restore();
415 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
416 }
417
418 TEST_P(AiksTest, CanRenderTextWithLargePerspectiveTransform) {
419 // Verifies that text scales are clamped to work around
420 // https://github.com/flutter/flutter/issues/136112 .
421
422 DisplayListBuilder builder;
423
424 DlPaint save_paint;
425 builder.SaveLayer(nullptr, &save_paint);
426 builder.Transform(SkM44::ColMajor(Matrix(2000, 0, 0, 0, //
427 0, 2000, 0, 0, //
428 0, 0, -1, 9000, //
429 0, 0, -1, 7000 //
430 )
431 .m));
432
433 ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
434 "Roboto-Regular.ttf"));
435 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
436 }
437
438 TEST_P(AiksTest, CanRenderTextWithPerspectiveTransformInSublist) {
439 DisplayListBuilder text_builder;
440 ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), text_builder, "Hello world",
441 "Roboto-Regular.ttf"));
442 auto text_display_list = text_builder.Build();
443
444 DisplayListBuilder builder;
445
446 Matrix matrix = Matrix::MakeRow(2.0, 0.0, 0.0, 0.0, //
447 0.0, 2.0, 0.0, 0.0, //
448 0.0, 0.0, 1.0, 0.0, //
449 0.0, 0.002, 0.0, 1.0);
450
451 DlPaint save_paint;
452 SkRect window_bounds =
453 SkRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
454 builder.SaveLayer(&window_bounds, &save_paint);
455 builder.Transform(SkM44::ColMajor(matrix.m));
456 builder.DrawDisplayList(text_display_list, 1.0f);
457 builder.Restore();
458
459 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
460 }
461
462 // This currently renders solid blue, as the support for text color sources was
463 // moved into DLDispatching. Path data requires the SkTextBlobs which are not
464 // used in impeller::TextFrames.
465 TEST_P(AiksTest, TextForegroundShaderWithTransform) {
466 auto mapping = flutter::testing::OpenFixtureAsSkData("Roboto-Regular.ttf");
467 ASSERT_NE(mapping, nullptr);
468
469 Scalar font_size = 100;
470 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
471 SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
472
473 DlPaint text_paint;
474 text_paint.setColor(DlColor::kBlue());
475
476 std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
477 DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
478 std::vector<Scalar> stops = {
479 0.0,
480 1.0,
481 };
482 text_paint.setColorSource(DlColorSource::MakeLinear(
483 /*start_point=*/DlPoint(0, 0), //
484 /*end_point=*/DlPoint(100, 100), //
485 /*stop_count=*/2, //
486 /*colors=*/colors.data(), //
487 /*stops=*/stops.data(), //
488 /*tile_mode=*/DlTileMode::kRepeat //
489 ));
490
491 DisplayListBuilder builder;
492 builder.Translate(100, 100);
493 builder.Rotate(45);
494
495 auto blob = SkTextBlob::MakeFromString("Hello", sk_font);
496 ASSERT_NE(blob, nullptr);
497 auto frame = MakeTextFrameFromTextBlobSkia(blob);
498 builder.DrawTextFrame(frame, 0, 0, text_paint);
499
500 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
501 }
502
503 // Regression test for https://github.com/flutter/flutter/issues/157885.
504 TEST_P(AiksTest, DifferenceClipsMustRenderIdenticallyAcrossBackends) {
505 DisplayListBuilder builder;
506
507 DlPaint paint;
508 DlColor clear_color(1.0, 0.5, 0.5, 0.5, DlColorSpace::kSRGB);
509 paint.setColor(clear_color);
510 builder.DrawPaint(paint);
511
512 DlMatrix identity = {
513 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
514 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
515 };
516 builder.Save();
517 builder.Transform(identity);
518
519 DlRect frame = DlRect::MakeLTRB(1.0, 1.0, 1278.0, 763.0);
520 DlColor white(1.0, 1.0, 1.0, 1.0, DlColorSpace::kSRGB);
521 paint.setColor(white);
522 builder.DrawRect(frame, paint);
523
524 builder.Save();
525 builder.ClipRect(frame, DlCanvas::ClipOp::kIntersect);
526
527 DlMatrix rect_xform = {
528 0.8241262, 0.56640625, 0.0, 0.0, -0.56640625, 0.8241262, 0.0, 0.0,
529 0.0, 0.0, 1.0, 0.0, 271.1137, 489.4733, 0.0, 1.0,
530 };
531 builder.Save();
532 builder.Transform(rect_xform);
533
534 DlRect rect = DlRect::MakeLTRB(0.0, 0.0, 100.0, 100.0);
535 DlColor bluish(1.0, 0.184, 0.501, 0.929, DlColorSpace::kSRGB);
536 paint.setColor(bluish);
537 DlRoundRect rrect = DlRoundRect::MakeRectRadius(rect, 18.0);
538 builder.DrawRoundRect(rrect, paint);
539
540 builder.Save();
541 builder.ClipRect(rect, DlCanvas::ClipOp::kIntersect);
542 builder.Restore();
543
544 builder.Restore();
545
546 DlMatrix path_xform = {
547 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
548 0.0, 0.0, 1.0, 0.0, 675.0, 279.5, 0.0, 1.0,
549 };
550 builder.Save();
551 builder.Transform(path_xform);
552
553 SkPath path;
554 path.moveTo(87.5, 349.5);
555 path.lineTo(25.0, 29.5);
556 path.lineTo(150.0, 118.0);
557 path.lineTo(25.0, 118.0);
558 path.lineTo(150.0, 29.5);
559 path.close();
560
561 DlColor fill_color(1.0, 1.0, 0.0, 0.0, DlColorSpace::kSRGB);
562 DlColor stroke_color(1.0, 0.0, 0.0, 0.0, DlColorSpace::kSRGB);
563 paint.setColor(fill_color);
564 paint.setDrawStyle(DlDrawStyle::kFill);
565 builder.DrawPath(DlPath(path), paint);
566
567 paint.setColor(stroke_color);
568 paint.setStrokeWidth(2.0);
569 paint.setDrawStyle(DlDrawStyle::kStroke);
570 builder.DrawPath(path, paint);
571
572 builder.Restore();
573 builder.Restore();
574 builder.Restore();
575
576 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
577 }
578
579 } // namespace testing
580 } // namespace impeller
impeller::Matrix::m
Scalar m[16]
Definition: matrix.h:39
impeller::testing::RenderTextInCanvasSkia
bool RenderTextInCanvasSkia(const std::shared_ptr< Context > &context, DisplayListBuilder &canvas, const std::string &text, const std::string_view &font_fixture, const TextRenderOptions &options={})
Definition: aiks_dl_text_unittests.cc:39
impeller::AiksPlayground
Definition: aiks_playground.h:16
impeller::Scalar
float Scalar
Definition: scalar.h:18
aiks_unittests.h
impeller::testing::TEST_P
TEST_P(AiksTest, DifferenceClipsMustRenderIdenticallyAcrossBackends)
Definition: aiks_dl_text_unittests.cc:504
impeller::testing::TextRenderOptions::filter
std::shared_ptr< DlMaskFilter > filter
Definition: aiks_dl_text_unittests.cc:35
impeller::DlPath
flutter::DlPath DlPath
Definition: dl_dispatcher.h:28
impeller::testing::TextRenderOptions
Definition: aiks_dl_text_unittests.cc:29
x
int32_t x
Definition: dl_golden_unittests.cc:443
stroke_width
const Scalar stroke_width
Definition: stroke_path_geometry.cc:312
matrix.h
text_frame_skia.h
impeller::k2Pi
constexpr float k2Pi
Definition: constants.h:29
impeller::DlRect
flutter::DlRect DlRect
Definition: dl_dispatcher.h:25
flutter
Definition: dl_golden_blur_unittests.cc:16
impeller::Matrix::Transform
constexpr Quad Transform(const Quad &quad) const
Definition: matrix.h:543
impeller::MakeTextFrameFromTextBlobSkia
std::shared_ptr< TextFrame > MakeTextFrameFromTextBlobSkia(const sk_sp< SkTextBlob > &blob)
Definition: text_frame_skia.cc:42
impeller::DlPoint
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:24
impeller::testing::TextRenderOptions::color
DlColor color
Definition: aiks_dl_text_unittests.cc:33
impeller::testing::kFontFixture
static constexpr std::string_view kFontFixture
Definition: aiks_dl_text_unittests.cc:246
scale
const Scalar scale
Definition: stroke_path_geometry.cc:316
impeller::Degrees
Definition: scalar.h:51
impeller::testing::TextRenderOptions::is_subpixel
bool is_subpixel
Definition: aiks_dl_text_unittests.cc:36
impeller::DlRoundRect
flutter::DlRoundRect DlRoundRect
Definition: dl_dispatcher.h:27
impeller
Definition: allocation.cc:12
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37