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"
20 #include "include/core/SkMatrix.h"
21 #include "include/core/SkRect.h"
24 #include "txt/platform.h"
36 DlColor color = DlColor::kYellow();
37 SkPoint position = SkPoint::Make(100, 200);
38 std::shared_ptr<DlMaskFilter>
filter;
39 bool is_subpixel =
false;
43 DisplayListBuilder& canvas,
44 const std::string& text,
45 const std::string_view& font_fixture,
49 paint.setColor(DlColor::kAqua().withAlpha(255 * 0.25));
50 canvas.DrawRect(SkRect::MakeXYWH(options.position.x() - 50,
51 options.position.y(), 900, 10),
55 paint.setColor(DlColor::kRed().withAlpha(255 * 0.25));
56 canvas.DrawCircle(options.position, 5.0, paint);
59 auto c_font_fixture = std::string(font_fixture);
60 auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
64 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
65 SkFont sk_font(font_mgr->makeFromData(mapping), options.font_size);
66 if (options.is_subpixel) {
67 sk_font.setSubpixel(
true);
69 auto blob = SkTextBlob::MakeFromString(text.c_str(), sk_font);
78 text_paint.setColor(options.color);
79 text_paint.setMaskFilter(options.filter);
80 text_paint.setStrokeWidth(options.stroke_width);
81 text_paint.setDrawStyle(options.stroke ? DlDrawStyle::kStroke
82 : DlDrawStyle::kFill);
83 canvas.DrawTextFrame(frame, options.position.x(), options.position.y(),
89 DisplayListBuilder builder;
92 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
93 builder.DrawPaint(paint);
95 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
96 "Roboto-Regular.ttf"));
98 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
102 DisplayListBuilder builder;
105 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
106 builder.DrawPaint(paint);
107 builder.Translate(1000, 0);
108 builder.Scale(-1, 1);
111 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
112 "Roboto-Regular.ttf"));
114 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
118 DisplayListBuilder builder;
121 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
122 builder.DrawPaint(paint);
125 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
126 "Roboto-Regular.ttf",
130 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
134 DisplayListBuilder builder;
137 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
138 builder.DrawPaint(paint);
146 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
150 DisplayListBuilder builder;
153 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
154 builder.DrawPaint(paint);
155 builder.Scale(0.5, 0.5);
158 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
159 "Roboto-Regular.ttf"));
160 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
167 auto callback = [&]() -> sk_sp<DisplayList> {
168 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
169 ImGuiWindowFlags_AlwaysAutoResize)) {
170 ImGui::SliderFloat(
"scale", &
scale, 1.f, 300.f);
171 ImGui::SliderFloat(
"offsetx", &offsetx, -600.f, 100.f);
172 ImGui::SliderFloat(
"offsety", &offsety, 600.f, 2048.f);
175 DisplayListBuilder builder;
176 builder.Scale(GetContentScale().
x, GetContentScale().y);
178 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
179 builder.DrawPaint(paint);
183 GetContext(), builder,
"test",
"Roboto-Regular.ttf",
187 return builder.Build();
189 ASSERT_TRUE(OpenPlaygroundHere(callback));
194 bool is_subpixel =
false;
195 auto callback = [&]() -> sk_sp<DisplayList> {
196 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
197 ImGuiWindowFlags_AlwaysAutoResize)) {
198 ImGui::SliderFloat(
"Fine Scale", &fine_scale, -1, 1);
199 ImGui::Checkbox(
"subpixel", &is_subpixel);
203 DisplayListBuilder builder;
205 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
206 builder.DrawPaint(paint);
210 "the quick brown fox jumped over the lazy dog!.?",
211 "Roboto-Regular.ttf",
213 return builder.Build();
216 ASSERT_TRUE(OpenPlaygroundHere(callback));
221 float fpivot[2] = {200 + 30, 200 - 20};
222 float rotation = 180;
223 float foffset[2] = {200, 200};
225 auto callback = [&]() -> sk_sp<DisplayList> {
226 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
227 ImGuiWindowFlags_AlwaysAutoResize)) {
228 ImGui::SliderFloat(
"pivotx", &fpivot[0], 0, 300);
229 ImGui::SliderFloat(
"pivoty", &fpivot[1], 0, 300);
230 ImGui::SliderFloat(
"rotation", &rotation, 0, 360);
231 ImGui::SliderFloat(
"foffsetx", &foffset[0], 0, 300);
232 ImGui::SliderFloat(
"foffsety", &foffset[1], 0, 300);
235 DisplayListBuilder builder;
236 builder.Scale(GetContentScale().
x, GetContentScale().y);
237 builder.DrawPaint(DlPaint().setColor(DlColor(0xffffeeff)));
241 builder.Translate(pivot.x, pivot.y);
242 builder.Rotate(rotation);
243 builder.Translate(-pivot.x, -pivot.y);
246 GetContext(), builder,
"test",
"Roboto-Regular.ttf",
248 .
color = DlColor::kBlack(),
249 .position = SkPoint::Make(foffset[0], foffset[1]),
253 return builder.Build();
255 ASSERT_TRUE(OpenPlaygroundHere(callback));
260 std::array<Scalar, 20> phase_offsets = {
261 7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
262 0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
263 0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
264 0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
265 auto callback = [&]() -> sk_sp<DisplayList> {
266 static float font_size = 20;
267 static float phase_variation = 0.2;
268 static float speed = 0.5;
269 static float magnitude = 100;
270 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
271 ImGuiWindowFlags_AlwaysAutoResize)) {
272 ImGui::SliderFloat(
"Font size", &font_size, 5, 50);
273 ImGui::SliderFloat(
"Phase variation", &phase_variation, 0, 1);
274 ImGui::SliderFloat(
"Oscillation speed", &speed, 0, 2);
275 ImGui::SliderFloat(
"Oscillation magnitude", &magnitude, 0, 300);
279 DisplayListBuilder builder;
280 builder.Scale(GetContentScale().
x, GetContentScale().y);
282 for (
size_t i = 0; i < phase_offsets.size(); i++) {
283 SkPoint position = SkPoint::Make(
285 magnitude * std::sin((-phase_offsets[i] *
k2Pi * phase_variation +
286 GetSecondsElapsed() * speed)),
287 200 + i * font_size * 1.1
290 GetContext(), builder,
291 "the quick brown fox jumped over "
293 "Roboto-Regular.ttf",
294 {.font_size = font_size, .position = position})) {
298 return builder.Build();
301 ASSERT_TRUE(OpenPlaygroundHere(callback));
305 DisplayListBuilder builder;
308 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
309 builder.DrawPaint(paint);
312 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
313 "HomemadeApple.ttf"));
314 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
319 "Apple Color Emoji.ttc";
321 "NotoColorEmoji.ttf";
325 DisplayListBuilder builder;
328 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
329 builder.DrawPaint(paint);
332 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture));
333 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
337 DisplayListBuilder builder;
339 builder.Scale(GetContentScale().
x, GetContentScale().y);
341 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
342 builder.DrawPaint(paint);
345 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture,
347 .
color = DlColor::kBlue(),
348 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
349 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
353 DisplayListBuilder builder;
356 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
357 builder.DrawPaint(paint);
360 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture,
361 {.color = DlColor::kBlack().modulateOpacity(0.5)}));
362 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
366 DisplayListBuilder builder;
369 paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1));
370 builder.DrawPaint(paint);
372 builder.Translate(100, 100);
373 builder.Scale(0.5, 0.5);
376 paint.setBlendMode(DlBlendMode::kClear);
377 builder.SaveLayer(
nullptr, &paint);
379 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
380 "Roboto-Regular.ttf"));
385 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
386 "Roboto-Regular.ttf"));
388 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
392 DisplayListBuilder builder;
393 builder.Translate(200, 150);
396 auto mapping = flutter::testing::OpenFixtureAsSkData(
"wtf.otf");
397 ASSERT_NE(mapping,
nullptr);
400 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
401 SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
404 text_paint.setColor(DlColor::kBlue().withAlpha(255 * 0.8));
409 } text[] = {{SkPoint::Make(0, 0),
"0F0F0F0"},
410 {SkPoint::Make(1, 2),
"789"},
411 {SkPoint::Make(1, 3),
"456"},
412 {SkPoint::Make(1, 4),
"123"},
413 {SkPoint::Make(0, 6),
"0F0F0F0"}};
414 for (
auto& t : text) {
416 builder.Translate(t.position.x() * font_size * 2,
417 t.position.y() * font_size * 1.1);
419 auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
420 ASSERT_NE(blob,
nullptr);
422 builder.DrawTextFrame(frame, 0, 0, text_paint);
427 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
431 DisplayListBuilder builder;
433 builder.Scale(GetContentScale().
x, GetContentScale().y);
435 paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 1.0));
436 builder.DrawPaint(paint);
438 builder.Transform(SkM44::ColMajor(
Matrix(0.25, -0.3, 0, -0.002,
444 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
445 "Roboto-Regular.ttf"));
447 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
451 DisplayListBuilder builder;
456 0.0, 0.0, 0.0, 1.0) *
457 Matrix::MakeRotationY({
Degrees{10}});
462 "Roboto-Regular.ttf"));
463 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
467 DisplayListBuilder builder;
472 0.0, 0.0, 0.0, 1.0) *
473 Matrix::MakeRotationY({
Degrees{10}});
476 SkRect window_bounds =
477 SkRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
479 builder.SaveLayer(&window_bounds, &save_paint);
480 builder.Transform(SkM44::ColMajor(matrix.
m));
483 "Roboto-Regular.ttf"));
486 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
493 DisplayListBuilder builder;
496 builder.SaveLayer(
nullptr, &save_paint);
497 builder.Transform(SkM44::ColMajor(
Matrix(2000, 0, 0, 0,
505 "Roboto-Regular.ttf"));
506 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
510 DisplayListBuilder text_builder;
512 "Roboto-Regular.ttf"));
513 auto text_display_list = text_builder.Build();
515 DisplayListBuilder builder;
517 Matrix matrix = Matrix::MakeRow(2.0, 0.0, 0.0, 0.0,
520 0.0, 0.002, 0.0, 1.0);
523 SkRect window_bounds =
524 SkRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
525 builder.SaveLayer(&window_bounds, &save_paint);
526 builder.Transform(SkM44::ColMajor(matrix.
m));
527 builder.DrawDisplayList(text_display_list, 1.0f);
530 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
537 auto mapping = flutter::testing::OpenFixtureAsSkData(
"Roboto-Regular.ttf");
538 ASSERT_NE(mapping,
nullptr);
541 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
542 SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
545 text_paint.setColor(DlColor::kBlue());
547 std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
548 DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
549 std::vector<Scalar> stops = {
553 text_paint.setColorSource(DlColorSource::MakeLinear(
562 DisplayListBuilder builder;
563 builder.Translate(100, 100);
566 auto blob = SkTextBlob::MakeFromString(
"Hello", sk_font);
567 ASSERT_NE(blob,
nullptr);
569 builder.DrawTextFrame(frame, 0, 0, text_paint);
571 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
576 DisplayListBuilder builder;
579 DlColor clear_color(1.0, 0.5, 0.5, 0.5, DlColorSpace::kSRGB);
580 paint.setColor(clear_color);
581 builder.DrawPaint(paint);
583 DlMatrix identity = {
584 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
585 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
588 builder.Transform(identity);
590 DlRect frame = DlRect::MakeLTRB(1.0, 1.0, 1278.0, 763.0);
591 DlColor white(1.0, 1.0, 1.0, 1.0, DlColorSpace::kSRGB);
592 paint.setColor(white);
593 builder.DrawRect(frame, paint);
596 builder.ClipRect(frame, DlCanvas::ClipOp::kIntersect);
598 DlMatrix rect_xform = {
599 0.8241262, 0.56640625, 0.0, 0.0, -0.56640625, 0.8241262, 0.0, 0.0,
600 0.0, 0.0, 1.0, 0.0, 271.1137, 489.4733, 0.0, 1.0,
603 builder.Transform(rect_xform);
605 DlRect rect = DlRect::MakeLTRB(0.0, 0.0, 100.0, 100.0);
606 DlColor bluish(1.0, 0.184, 0.501, 0.929, DlColorSpace::kSRGB);
607 paint.setColor(bluish);
608 DlRoundRect rrect = DlRoundRect::MakeRectRadius(rect, 18.0);
609 builder.DrawRoundRect(rrect, paint);
612 builder.ClipRect(rect, DlCanvas::ClipOp::kIntersect);
617 DlMatrix path_xform = {
618 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
619 0.0, 0.0, 1.0, 0.0, 675.0, 279.5, 0.0, 1.0,
622 builder.Transform(path_xform);
625 path.moveTo(87.5, 349.5);
626 path.lineTo(25.0, 29.5);
627 path.lineTo(150.0, 118.0);
628 path.lineTo(25.0, 118.0);
629 path.lineTo(150.0, 29.5);
632 DlColor fill_color(1.0, 1.0, 0.0, 0.0, DlColorSpace::kSRGB);
633 DlColor stroke_color(1.0, 0.0, 0.0, 0.0, DlColorSpace::kSRGB);
634 paint.setColor(fill_color);
635 paint.setDrawStyle(DlDrawStyle::kFill);
636 builder.DrawPath(
DlPath(path), paint);
638 paint.setColor(stroke_color);
639 paint.setStrokeWidth(2.0);
640 paint.setDrawStyle(DlDrawStyle::kStroke);
641 builder.DrawPath(path, paint);
647 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
652 std::make_shared<TypographerContextSkia>());
656 constexpr
const char* font_fixture =
"Roboto-Regular.ttf";
659 auto c_font_fixture = std::string(font_fixture);
660 auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
661 ASSERT_TRUE(mapping);
663 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
664 SkFont sk_font(font_mgr->makeFromData(mapping), 16);
666 auto blob = SkTextBlob::MakeFromString(
"Hello World", sk_font);
673 Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
676 auto scale = TextFrame::RoundScaledFontSize(
677 (preroll_matrix * Matrix::MakeTranslation(preroll_point))
678 .GetMaxBasisLengthXY());
693 ->CreateOffscreenMSAA(*aiks_context.
GetContext(), {100, 100}, 1);
699 text_contents.
SetColor(Color::Aqua());
701 Matrix not_preroll_matrix =
702 Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
707 std::shared_ptr<CommandBuffer> command_buffer =
708 aiks_context.
GetContext()->CreateCommandBuffer();
709 std::shared_ptr<RenderPass> render_pass =
710 command_buffer->CreateRenderPass(render_target);
ContentContext & GetContentContext() const
std::shared_ptr< Context > GetContext() const
const std::shared_ptr< LazyGlyphAtlas > & GetLazyGlyphAtlas() const
const std::shared_ptr< RenderTargetAllocator > & GetRenderTargetCache() 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)
TEST_P(AiksTest, TextContentsMismatchedTransformTest)
bool RenderTextInCanvasSkia(const std::shared_ptr< Context > &context, DisplayListBuilder &canvas, const std::string &text, const std::string_view &font_fixture, const TextRenderOptions &options={})
static constexpr std::string_view kFontFixture
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