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()));
165 bool is_subpixel =
false;
166 auto callback = [&]() -> sk_sp<DisplayList> {
167 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
168 ImGuiWindowFlags_AlwaysAutoResize)) {
169 ImGui::SliderFloat(
"Fine Scale", &fine_scale, -1, 1);
170 ImGui::Checkbox(
"subpixel", &is_subpixel);
174 DisplayListBuilder builder;
176 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
177 builder.DrawPaint(paint);
181 "the quick brown fox jumped over the lazy dog!.?",
182 "Roboto-Regular.ttf",
184 return builder.Build();
187 ASSERT_TRUE(OpenPlaygroundHere(callback));
192 float fpivot[2] = {200 + 30, 200 - 20};
193 float rotation = 180;
194 float foffset[2] = {200, 200};
196 auto callback = [&]() -> sk_sp<DisplayList> {
197 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
198 ImGuiWindowFlags_AlwaysAutoResize)) {
199 ImGui::SliderFloat(
"pivotx", &fpivot[0], 0, 300);
200 ImGui::SliderFloat(
"pivoty", &fpivot[1], 0, 300);
201 ImGui::SliderFloat(
"rotation", &rotation, 0, 360);
202 ImGui::SliderFloat(
"foffsetx", &foffset[0], 0, 300);
203 ImGui::SliderFloat(
"foffsety", &foffset[1], 0, 300);
206 DisplayListBuilder builder;
207 builder.Scale(GetContentScale().
x, GetContentScale().y);
208 builder.DrawPaint(DlPaint().setColor(DlColor(0xffffeeff)));
212 builder.Translate(pivot.x, pivot.y);
213 builder.Rotate(rotation);
214 builder.Translate(-pivot.x, -pivot.y);
217 GetContext(), builder,
"test",
"Roboto-Regular.ttf",
219 .
color = DlColor::kBlack(),
220 .position = SkPoint::Make(foffset[0], foffset[1]),
224 return builder.Build();
226 ASSERT_TRUE(OpenPlaygroundHere(callback));
231 std::array<Scalar, 20> phase_offsets = {
232 7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
233 0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
234 0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
235 0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
236 auto callback = [&]() -> sk_sp<DisplayList> {
237 static float font_size = 20;
238 static float phase_variation = 0.2;
239 static float speed = 0.5;
240 static float magnitude = 100;
241 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
242 ImGuiWindowFlags_AlwaysAutoResize)) {
243 ImGui::SliderFloat(
"Font size", &font_size, 5, 50);
244 ImGui::SliderFloat(
"Phase variation", &phase_variation, 0, 1);
245 ImGui::SliderFloat(
"Oscillation speed", &speed, 0, 2);
246 ImGui::SliderFloat(
"Oscillation magnitude", &magnitude, 0, 300);
250 DisplayListBuilder builder;
251 builder.Scale(GetContentScale().
x, GetContentScale().y);
253 for (
size_t i = 0; i < phase_offsets.size(); i++) {
254 SkPoint position = SkPoint::Make(
256 magnitude * std::sin((-phase_offsets[i] *
k2Pi * phase_variation +
257 GetSecondsElapsed() * speed)),
258 200 + i * font_size * 1.1
261 GetContext(), builder,
262 "the quick brown fox jumped over "
264 "Roboto-Regular.ttf",
265 {.font_size = font_size, .position = position})) {
269 return builder.Build();
272 ASSERT_TRUE(OpenPlaygroundHere(callback));
276 DisplayListBuilder builder;
279 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
280 builder.DrawPaint(paint);
283 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
284 "HomemadeApple.ttf"));
285 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
290 "Apple Color Emoji.ttc";
292 "NotoColorEmoji.ttf";
296 DisplayListBuilder builder;
299 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
300 builder.DrawPaint(paint);
303 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture));
304 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
308 DisplayListBuilder builder;
310 builder.Scale(GetContentScale().
x, GetContentScale().y);
312 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
313 builder.DrawPaint(paint);
316 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture,
318 .
color = DlColor::kBlue(),
319 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
320 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
324 DisplayListBuilder builder;
327 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
328 builder.DrawPaint(paint);
331 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture,
332 {.color = DlColor::kBlack().modulateOpacity(0.5)}));
333 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
337 DisplayListBuilder builder;
340 paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1));
341 builder.DrawPaint(paint);
343 builder.Translate(100, 100);
344 builder.Scale(0.5, 0.5);
347 paint.setBlendMode(DlBlendMode::kClear);
348 builder.SaveLayer(
nullptr, &paint);
350 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
351 "Roboto-Regular.ttf"));
356 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
357 "Roboto-Regular.ttf"));
359 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
363 DisplayListBuilder builder;
364 builder.Translate(200, 150);
367 auto mapping = flutter::testing::OpenFixtureAsSkData(
"wtf.otf");
368 ASSERT_NE(mapping,
nullptr);
371 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
372 SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
375 text_paint.setColor(DlColor::kBlue().withAlpha(255 * 0.8));
380 } text[] = {{SkPoint::Make(0, 0),
"0F0F0F0"},
381 {SkPoint::Make(1, 2),
"789"},
382 {SkPoint::Make(1, 3),
"456"},
383 {SkPoint::Make(1, 4),
"123"},
384 {SkPoint::Make(0, 6),
"0F0F0F0"}};
385 for (
auto& t : text) {
387 builder.Translate(t.position.x() * font_size * 2,
388 t.position.y() * font_size * 1.1);
390 auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
391 ASSERT_NE(blob,
nullptr);
393 builder.DrawTextFrame(frame, 0, 0, text_paint);
398 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
402 DisplayListBuilder builder;
404 builder.Scale(GetContentScale().
x, GetContentScale().y);
406 paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 1.0));
407 builder.DrawPaint(paint);
409 builder.Transform(SkM44::ColMajor(
Matrix(0.25, -0.3, 0, -0.002,
415 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
416 "Roboto-Regular.ttf"));
418 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
422 DisplayListBuilder builder;
427 0.0, 0.0, 0.0, 1.0) *
428 Matrix::MakeRotationY({
Degrees{10}});
433 "Roboto-Regular.ttf"));
434 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
438 DisplayListBuilder builder;
443 0.0, 0.0, 0.0, 1.0) *
444 Matrix::MakeRotationY({
Degrees{10}});
447 SkRect window_bounds =
448 SkRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
450 builder.SaveLayer(&window_bounds, &save_paint);
451 builder.Transform(SkM44::ColMajor(matrix.
m));
454 "Roboto-Regular.ttf"));
457 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
464 DisplayListBuilder builder;
467 builder.SaveLayer(
nullptr, &save_paint);
468 builder.Transform(SkM44::ColMajor(
Matrix(2000, 0, 0, 0,
476 "Roboto-Regular.ttf"));
477 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
481 DisplayListBuilder text_builder;
483 "Roboto-Regular.ttf"));
484 auto text_display_list = text_builder.Build();
486 DisplayListBuilder builder;
488 Matrix matrix = Matrix::MakeRow(2.0, 0.0, 0.0, 0.0,
491 0.0, 0.002, 0.0, 1.0);
494 SkRect window_bounds =
495 SkRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
496 builder.SaveLayer(&window_bounds, &save_paint);
497 builder.Transform(SkM44::ColMajor(matrix.
m));
498 builder.DrawDisplayList(text_display_list, 1.0f);
501 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
508 auto mapping = flutter::testing::OpenFixtureAsSkData(
"Roboto-Regular.ttf");
509 ASSERT_NE(mapping,
nullptr);
512 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
513 SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
516 text_paint.setColor(DlColor::kBlue());
518 std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
519 DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
520 std::vector<Scalar> stops = {
524 text_paint.setColorSource(DlColorSource::MakeLinear(
533 DisplayListBuilder builder;
534 builder.Translate(100, 100);
537 auto blob = SkTextBlob::MakeFromString(
"Hello", sk_font);
538 ASSERT_NE(blob,
nullptr);
540 builder.DrawTextFrame(frame, 0, 0, text_paint);
542 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
547 DisplayListBuilder builder;
550 DlColor clear_color(1.0, 0.5, 0.5, 0.5, DlColorSpace::kSRGB);
551 paint.setColor(clear_color);
552 builder.DrawPaint(paint);
554 DlMatrix identity = {
555 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
556 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
559 builder.Transform(identity);
561 DlRect frame = DlRect::MakeLTRB(1.0, 1.0, 1278.0, 763.0);
562 DlColor white(1.0, 1.0, 1.0, 1.0, DlColorSpace::kSRGB);
563 paint.setColor(white);
564 builder.DrawRect(frame, paint);
567 builder.ClipRect(frame, DlCanvas::ClipOp::kIntersect);
569 DlMatrix rect_xform = {
570 0.8241262, 0.56640625, 0.0, 0.0, -0.56640625, 0.8241262, 0.0, 0.0,
571 0.0, 0.0, 1.0, 0.0, 271.1137, 489.4733, 0.0, 1.0,
574 builder.Transform(rect_xform);
576 DlRect rect = DlRect::MakeLTRB(0.0, 0.0, 100.0, 100.0);
577 DlColor bluish(1.0, 0.184, 0.501, 0.929, DlColorSpace::kSRGB);
578 paint.setColor(bluish);
579 DlRoundRect rrect = DlRoundRect::MakeRectRadius(rect, 18.0);
580 builder.DrawRoundRect(rrect, paint);
583 builder.ClipRect(rect, DlCanvas::ClipOp::kIntersect);
588 DlMatrix path_xform = {
589 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
590 0.0, 0.0, 1.0, 0.0, 675.0, 279.5, 0.0, 1.0,
593 builder.Transform(path_xform);
596 path.moveTo(87.5, 349.5);
597 path.lineTo(25.0, 29.5);
598 path.lineTo(150.0, 118.0);
599 path.lineTo(25.0, 118.0);
600 path.lineTo(150.0, 29.5);
603 DlColor fill_color(1.0, 1.0, 0.0, 0.0, DlColorSpace::kSRGB);
604 DlColor stroke_color(1.0, 0.0, 0.0, 0.0, DlColorSpace::kSRGB);
605 paint.setColor(fill_color);
606 paint.setDrawStyle(DlDrawStyle::kFill);
607 builder.DrawPath(
DlPath(path), paint);
609 paint.setColor(stroke_color);
610 paint.setStrokeWidth(2.0);
611 paint.setDrawStyle(DlDrawStyle::kStroke);
612 builder.DrawPath(path, paint);
618 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
623 std::make_shared<TypographerContextSkia>());
627 constexpr
const char* font_fixture =
"Roboto-Regular.ttf";
630 auto c_font_fixture = std::string(font_fixture);
631 auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
632 ASSERT_TRUE(mapping);
634 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
635 SkFont sk_font(font_mgr->makeFromData(mapping), 16);
637 auto blob = SkTextBlob::MakeFromString(
"Hello World", sk_font);
644 Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
647 auto scale = TextFrame::RoundScaledFontSize(
648 (preroll_matrix * Matrix::MakeTranslation(preroll_point))
649 .GetMaxBasisLengthXY());
664 ->CreateOffscreenMSAA(*aiks_context.
GetContext(), {100, 100}, 1);
670 text_contents.
SetColor(Color::Aqua());
672 Matrix not_preroll_matrix =
673 Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
678 std::shared_ptr<CommandBuffer> command_buffer =
679 aiks_context.
GetContext()->CreateCommandBuffer();
680 std::shared_ptr<RenderPass> render_pass =
681 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