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"
15 #include "flutter/testing/testing.h"
25 #include "txt/platform.h"
37 DlColor color = DlColor::kYellow();
39 std::shared_ptr<DlMaskFilter>
filter;
44 DisplayListBuilder& canvas,
45 const std::string& text,
46 const std::string_view& font_fixture,
48 const std::optional<SkFont>& font = std::nullopt) {
51 paint.setColor(DlColor::kAqua().withAlpha(255 * 0.25));
53 DlRect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
57 paint.setColor(DlColor::kRed().withAlpha(255 * 0.25));
58 canvas.DrawCircle(options.position, 5.0, paint);
62 if (!font.has_value()) {
63 auto c_font_fixture = std::string(font_fixture);
65 flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
69 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
70 selected_font = SkFont(font_mgr->makeFromData(mapping), options.font_size);
71 if (options.is_subpixel) {
72 selected_font.setSubpixel(
true);
75 selected_font = font.value();
77 auto blob = SkTextBlob::MakeFromString(text.c_str(), selected_font);
86 text_paint.setColor(options.color);
87 text_paint.setMaskFilter(options.filter);
88 text_paint.setStrokeWidth(options.stroke_width);
89 text_paint.setDrawStyle(options.stroke ? DlDrawStyle::kStroke
90 : DlDrawStyle::kFill);
91 canvas.DrawTextFrame(frame, options.position.x, options.position.y,
97 DisplayListBuilder builder;
100 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
101 builder.DrawPaint(paint);
103 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
104 "Roboto-Regular.ttf"));
106 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
110 DisplayListBuilder builder;
113 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
114 builder.DrawPaint(paint);
115 builder.Translate(1000, 0);
116 builder.Scale(-1, 1);
119 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
120 "Roboto-Regular.ttf"));
122 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
126 DisplayListBuilder builder;
129 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
130 builder.DrawPaint(paint);
133 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
134 "Roboto-Regular.ttf",
138 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
142 DisplayListBuilder builder;
145 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
146 builder.DrawPaint(paint);
154 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
158 DisplayListBuilder builder;
161 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
162 builder.DrawPaint(paint);
163 builder.Scale(0.5, 0.5);
166 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
167 "Roboto-Regular.ttf"));
168 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
173 DisplayListBuilder builder;
175 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
176 builder.DrawPaint(paint);
177 for (
int i = 0; i < 6; ++i) {
179 builder.Translate(300 * i, 0);
183 GetContext(), builder,
"k",
"Roboto-Regular.ttf",
186 GetContext(), builder,
"k",
"Roboto-Regular.ttf",
190 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
196 auto callback = [&]() -> sk_sp<DisplayList> {
197 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
198 ImGuiWindowFlags_AlwaysAutoResize)) {
199 ImGui::SliderFloat(
"Scale", &
scale, 4, 20);
203 DisplayListBuilder builder;
205 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
206 builder.DrawPaint(paint);
210 GetContext(), builder,
"HELLO",
"Roboto-Regular.ttf",
212 .color = (16 *
scale >= 250) ? DlColor::kYellow()
213 : DlColor::kOrange(),
215 return builder.Build();
218 ASSERT_TRUE(OpenPlaygroundHere(callback));
225 auto callback = [&]() -> sk_sp<DisplayList> {
226 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
227 ImGuiWindowFlags_AlwaysAutoResize)) {
228 ImGui::SliderFloat(
"scale", &
scale, 1.f, 300.f);
229 ImGui::SliderFloat(
"offsetx", &offsetx, -600.f, 100.f);
230 ImGui::SliderFloat(
"offsety", &offsety, 600.f, 2048.f);
233 DisplayListBuilder builder;
234 builder.Scale(GetContentScale().
x, GetContentScale().y);
236 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
237 builder.DrawPaint(paint);
241 GetContext(), builder,
"test",
"Roboto-Regular.ttf",
245 return builder.Build();
247 ASSERT_TRUE(OpenPlaygroundHere(callback));
253 auto callback = [&]() -> sk_sp<DisplayList> {
254 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
255 ImGuiWindowFlags_AlwaysAutoResize)) {
256 ImGui::SliderFloat(
"Fine Scale", &fine_scale, -1, 1);
261 DisplayListBuilder builder;
263 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
264 builder.DrawPaint(paint);
268 "the quick brown fox jumped over the lazy dog!.?",
269 "Roboto-Regular.ttf",
271 return builder.Build();
274 ASSERT_TRUE(OpenPlaygroundHere(callback));
279 float fpivot[2] = {200 + 30, 200 - 20};
280 float rotation = 180;
281 float foffset[2] = {200, 200};
283 auto callback = [&]() -> sk_sp<DisplayList> {
284 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
285 ImGuiWindowFlags_AlwaysAutoResize)) {
286 ImGui::SliderFloat(
"pivotx", &fpivot[0], 0, 300);
287 ImGui::SliderFloat(
"pivoty", &fpivot[1], 0, 300);
288 ImGui::SliderFloat(
"rotation", &rotation, 0, 360);
289 ImGui::SliderFloat(
"foffsetx", &foffset[0], 0, 300);
290 ImGui::SliderFloat(
"foffsety", &foffset[1], 0, 300);
293 DisplayListBuilder builder;
294 builder.Scale(GetContentScale().
x, GetContentScale().y);
295 builder.DrawPaint(DlPaint().setColor(DlColor(0xffffeeff)));
299 builder.Translate(pivot.x, pivot.y);
300 builder.Rotate(rotation);
301 builder.Translate(-pivot.x, -pivot.y);
305 .
color = DlColor::kBlack(),
306 .position =
DlPoint(foffset[0], foffset[1]),
310 return builder.Build();
312 ASSERT_TRUE(OpenPlaygroundHere(callback));
317 std::array<Scalar, 20> phase_offsets = {
318 7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
319 0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
320 0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
321 0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
322 auto callback = [&]() -> sk_sp<DisplayList> {
324 static float phase_variation = 0.2;
325 static float speed = 0.5;
326 static float magnitude = 100;
327 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
328 ImGuiWindowFlags_AlwaysAutoResize)) {
329 ImGui::SliderFloat(
"Font size", &
font_size, 5, 50);
330 ImGui::SliderFloat(
"Phase variation", &phase_variation, 0, 1);
331 ImGui::SliderFloat(
"Oscillation speed", &speed, 0, 2);
332 ImGui::SliderFloat(
"Oscillation magnitude", &magnitude, 0, 300);
336 DisplayListBuilder builder;
337 builder.Scale(GetContentScale().
x, GetContentScale().y);
339 for (
size_t i = 0; i < phase_offsets.size(); i++) {
342 magnitude * std::sin((-phase_offsets[i] *
k2Pi * phase_variation +
343 GetSecondsElapsed() * speed)),
347 GetContext(), builder,
348 "the quick brown fox jumped over "
350 "Roboto-Regular.ttf",
351 {.font_size =
font_size, .position = position})) {
355 return builder.Build();
358 ASSERT_TRUE(OpenPlaygroundHere(callback));
362 DisplayListBuilder builder;
365 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
366 builder.DrawPaint(paint);
369 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
370 "HomemadeApple.ttf"));
371 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
376 "Apple Color Emoji.ttc";
378 "NotoColorEmoji.ttf";
382 DisplayListBuilder builder;
385 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
386 builder.DrawPaint(paint);
389 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture));
390 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
394 DisplayListBuilder builder;
396 builder.Scale(GetContentScale().
x, GetContentScale().y);
398 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
399 builder.DrawPaint(paint);
402 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture,
404 .
color = DlColor::kBlue(),
405 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
406 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
410 DisplayListBuilder builder;
413 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
414 builder.DrawPaint(paint);
417 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture,
418 {.color = DlColor::kBlack().modulateOpacity(0.5)}));
419 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
423 DisplayListBuilder builder;
426 paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1));
427 builder.DrawPaint(paint);
429 builder.Translate(100, 100);
430 builder.Scale(0.5, 0.5);
433 paint.setBlendMode(DlBlendMode::kClear);
434 builder.SaveLayer(std::nullopt, &paint);
436 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
437 "Roboto-Regular.ttf"));
442 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
443 "Roboto-Regular.ttf"));
445 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
449 DisplayListBuilder builder;
450 builder.Translate(200, 150);
453 auto mapping = flutter::testing::OpenFixtureAsSkData(
"wtf.otf");
454 ASSERT_NE(mapping,
nullptr);
457 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
458 SkFont sk_font(font_mgr->makeFromData(mapping),
font_size);
461 text_paint.setColor(DlColor::kBlue().withAlpha(255 * 0.8));
466 } text[] = {{
DlPoint(0, 0),
"0F0F0F0"},
471 for (
auto& t : text) {
473 builder.Translate(t.position.x *
font_size * 2,
476 auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
477 ASSERT_NE(blob,
nullptr);
479 builder.DrawTextFrame(frame, 0, 0, text_paint);
484 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
488 DisplayListBuilder builder;
490 builder.Scale(GetContentScale().
x, GetContentScale().y);
492 paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 1.0));
493 builder.DrawPaint(paint);
495 builder.Transform(
Matrix(0.25, -0.3, 0, -0.002,
500 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
501 "Roboto-Regular.ttf"));
503 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
507 DisplayListBuilder builder;
512 0.0, 0.0, 0.0, 1.0) *
513 Matrix::MakeRotationY({
Degrees{10}});
518 "Roboto-Regular.ttf"));
519 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
523 DisplayListBuilder builder;
528 0.0, 0.0, 0.0, 1.0) *
529 Matrix::MakeRotationY({
Degrees{10}});
533 DlRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
535 builder.SaveLayer(window_bounds, &save_paint);
536 builder.Transform(matrix);
539 "Roboto-Regular.ttf"));
542 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
549 DisplayListBuilder builder;
552 builder.SaveLayer(std::nullopt, &save_paint);
553 builder.Transform(
Matrix(2000, 0, 0, 0,
560 "Roboto-Regular.ttf"));
561 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
565 DisplayListBuilder text_builder;
567 "Roboto-Regular.ttf"));
568 auto text_display_list = text_builder.Build();
570 DisplayListBuilder builder;
572 Matrix matrix = Matrix::MakeRow(2.0, 0.0, 0.0, 0.0,
575 0.0, 0.002, 0.0, 1.0);
579 DlRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
580 builder.SaveLayer(window_bounds, &save_paint);
581 builder.Transform(matrix);
582 builder.DrawDisplayList(text_display_list, 1.0f);
585 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
592 auto mapping = flutter::testing::OpenFixtureAsSkData(
"Roboto-Regular.ttf");
593 ASSERT_NE(mapping,
nullptr);
596 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
597 SkFont sk_font(font_mgr->makeFromData(mapping),
font_size);
600 text_paint.setColor(DlColor::kBlue());
602 std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
603 DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
604 std::vector<Scalar> stops = {
608 text_paint.setColorSource(DlColorSource::MakeLinear(
617 DisplayListBuilder builder;
618 builder.Translate(100, 100);
621 auto blob = SkTextBlob::MakeFromString(
"Hello", sk_font);
622 ASSERT_NE(blob,
nullptr);
624 builder.DrawTextFrame(frame, 0, 0, text_paint);
626 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
631 DisplayListBuilder builder;
634 DlColor clear_color(1.0, 0.5, 0.5, 0.5, DlColorSpace::kSRGB);
635 paint.setColor(clear_color);
636 builder.DrawPaint(paint);
638 DlMatrix identity = {
639 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
640 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
643 builder.Transform(identity);
645 DlRect frame = DlRect::MakeLTRB(1.0, 1.0, 1278.0, 763.0);
646 DlColor white(1.0, 1.0, 1.0, 1.0, DlColorSpace::kSRGB);
647 paint.setColor(white);
648 builder.DrawRect(frame, paint);
651 builder.ClipRect(frame, DlClipOp::kIntersect);
653 DlMatrix rect_xform = {
654 0.8241262, 0.56640625, 0.0, 0.0, -0.56640625, 0.8241262, 0.0, 0.0,
655 0.0, 0.0, 1.0, 0.0, 271.1137, 489.4733, 0.0, 1.0,
658 builder.Transform(rect_xform);
660 DlRect rect = DlRect::MakeLTRB(0.0, 0.0, 100.0, 100.0);
661 DlColor bluish(1.0, 0.184, 0.501, 0.929, DlColorSpace::kSRGB);
662 paint.setColor(bluish);
663 DlRoundRect rrect = DlRoundRect::MakeRectRadius(rect, 18.0);
664 builder.DrawRoundRect(rrect, paint);
667 builder.ClipRect(rect, DlClipOp::kIntersect);
672 DlMatrix path_xform = {
673 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
674 0.0, 0.0, 1.0, 0.0, 675.0, 279.5, 0.0, 1.0,
677 builder.Transform(path_xform);
679 DlPathBuilder path_builder;
680 path_builder.MoveTo(
DlPoint(87.5, 349.5));
681 path_builder.LineTo(
DlPoint(25.0, 29.5));
682 path_builder.LineTo(
DlPoint(150.0, 118.0));
683 path_builder.LineTo(
DlPoint(25.0, 118.0));
684 path_builder.LineTo(
DlPoint(150.0, 29.5));
685 path_builder.Close();
686 DlPath path(path_builder);
688 DlColor fill_color(1.0, 1.0, 0.0, 0.0, DlColorSpace::kSRGB);
689 DlColor stroke_color(1.0, 0.0, 0.0, 0.0, DlColorSpace::kSRGB);
690 paint.setColor(fill_color);
691 paint.setDrawStyle(DlDrawStyle::kFill);
692 builder.DrawPath(path, paint);
694 paint.setColor(stroke_color);
695 paint.setStrokeWidth(2.0);
696 paint.setDrawStyle(DlDrawStyle::kStroke);
697 builder.DrawPath(path, paint);
703 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
708 std::make_shared<TypographerContextSkia>());
712 constexpr
const char* font_fixture =
"Roboto-Regular.ttf";
715 auto c_font_fixture = std::string(font_fixture);
716 auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
717 ASSERT_TRUE(mapping);
719 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
720 SkFont sk_font(font_mgr->makeFromData(mapping), 16);
722 auto blob = SkTextBlob::MakeFromString(
"Hello World", sk_font);
729 Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
732 auto scale = TextFrame::RoundScaledFontSize(
733 (preroll_matrix * Matrix::MakeTranslation(preroll_point))
734 .GetMaxBasisLengthXY());
749 ->CreateOffscreenMSAA(*aiks_context.
GetContext(), {100, 100}, 1);
755 text_contents.
SetColor(Color::Aqua());
757 Matrix not_preroll_matrix =
758 Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
763 std::shared_ptr<CommandBuffer> command_buffer =
764 aiks_context.
GetContext()->CreateCommandBuffer();
765 std::shared_ptr<RenderPass> render_pass =
766 command_buffer->CreateRenderPass(render_target);
773 DisplayListBuilder builder;
774 builder.Scale(GetContentScale().
x, GetContentScale().y);
776 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
777 builder.DrawPaint(paint);
780 std::make_shared<TypographerContextSkia>());
790 .
color = DlColor::kBlue(),
791 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
803 DisplayListBuilder builder;
804 builder.Scale(GetContentScale().
x, GetContentScale().y);
806 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
807 builder.DrawPaint(paint);
810 std::make_shared<TypographerContextSkia>());
817 for (
auto i = 0; i < 5; i++) {
821 .
color = DlColor::kBlue(),
822 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
836 DisplayListBuilder builder;
837 builder.Scale(GetContentScale().
x, GetContentScale().y);
839 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
840 builder.DrawPaint(paint);
843 std::make_shared<TypographerContextSkia>());
852 auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
853 ASSERT_TRUE(mapping);
854 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
855 SkFont sk_font(font_mgr->makeFromData(mapping), 50);
857 for (
auto i = 0; i < 10; i++) {
861 .
color = DlColor::kBlue(),
862 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)},
876 DisplayListBuilder builder;
878 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
879 builder.DrawPaint(paint);
880 builder.Scale(GetContentScale().
x, GetContentScale().y);
882 std::vector<Scalar> scales = {4, 8, 16, 24, 32};
883 std::vector<Scalar> spacing = {8, 8, 8, 8, 8};
886 for (
auto i = 0u; i < scales.size(); i++) {
888 builder.Scale(scales[i], scales[i]);
890 GetContext(), builder,
"lo",
"Roboto-Regular.ttf",
899 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
ContentContext & GetContentContext() const
std::shared_ptr< Context > GetContext() const
const std::shared_ptr< LazyGlyphAtlas > & GetLazyGlyphAtlas() const
const std::shared_ptr< RenderTargetAllocator > & GetRenderTargetCache() const
TextShadowCache & GetTextShadowCache() const
void SetTransform(const Matrix &transform)
Set the global transform matrix for this Entity.
void SetOffset(Vector2 offset)
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
void SetTextFrame(const std::shared_ptr< TextFrame > &frame)
void SetScale(Scalar scale)
void SetColor(Color color)
size_t GetCacheSizeForTesting() const
bool RenderTextInCanvasSkia(const std::shared_ptr< Context > &context, DisplayListBuilder &canvas, const std::string &text, const std::string_view &font_fixture, const TextRenderOptions &options={}, const std::optional< SkFont > &font=std::nullopt)
TEST_P(AiksTest, VarietyOfTextScalesShowingRasterAndPath)
static constexpr std::string_view kFontFixture
std::shared_ptr< Texture > DisplayListToTexture(const sk_sp< flutter::DisplayList > &display_list, ISize size, AiksContext &context, bool reset_host_buffer, bool generate_mips)
Render the provided display list to a texture with the given size.
flutter::DlRoundRect DlRoundRect
std::shared_ptr< TextFrame > MakeTextFrameFromTextBlobSkia(const sk_sp< SkTextBlob > &blob)
const Scalar stroke_width
A 4x4 matrix using column-major storage.
constexpr Quad Transform(const Quad &quad) const
std::shared_ptr< DlMaskFilter > filter