5 #include "flutter/display_list/display_list.h"
6 #include "flutter/display_list/dl_blend_mode.h"
7 #include "flutter/display_list/dl_builder.h"
8 #include "flutter/display_list/dl_color.h"
9 #include "flutter/display_list/dl_paint.h"
10 #include "flutter/display_list/dl_tile_mode.h"
11 #include "flutter/display_list/effects/dl_color_source.h"
12 #include "flutter/display_list/effects/dl_mask_filter.h"
13 #include "flutter/display_list/geometry/dl_path_builder.h"
14 #include "flutter/fml/build_config.h"
16 #include "flutter/testing/testing.h"
26 #include "txt/platform.h"
38 DlColor color = DlColor::kYellow();
40 std::shared_ptr<DlMaskFilter>
filter;
45 DisplayListBuilder& canvas,
46 const std::string& text,
47 const std::string_view& font_fixture,
49 const std::optional<SkFont>& font = std::nullopt) {
52 paint.setColor(DlColor::kAqua().withAlpha(255 * 0.25));
54 DlRect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
58 paint.setColor(DlColor::kRed().withAlpha(255 * 0.25));
59 canvas.DrawCircle(options.position, 5.0, paint);
63 if (!font.has_value()) {
64 auto c_font_fixture = std::string(font_fixture);
66 flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
70 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
71 selected_font = SkFont(font_mgr->makeFromData(mapping), options.font_size);
72 if (options.is_subpixel) {
73 selected_font.setSubpixel(
true);
76 selected_font = font.value();
78 auto blob = SkTextBlob::MakeFromString(text.c_str(), selected_font);
87 text_paint.setColor(options.color);
88 text_paint.setMaskFilter(options.filter);
89 text_paint.setStrokeWidth(options.stroke_width);
90 text_paint.setDrawStyle(options.stroke ? DlDrawStyle::kStroke
91 : DlDrawStyle::kFill);
92 canvas.DrawTextFrame(frame, options.position.x, options.position.y,
98 DisplayListBuilder builder;
101 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
102 builder.DrawPaint(paint);
104 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
105 "Roboto-Regular.ttf"));
107 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
111 DisplayListBuilder builder;
114 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
115 builder.DrawPaint(paint);
116 builder.Translate(1000, 0);
117 builder.Scale(-1, 1);
120 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
121 "Roboto-Regular.ttf"));
123 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
127 DisplayListBuilder builder;
130 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
131 builder.DrawPaint(paint);
134 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
135 "Roboto-Regular.ttf",
139 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
143 DisplayListBuilder builder;
146 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
147 builder.DrawPaint(paint);
155 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
159 DisplayListBuilder builder;
162 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
163 builder.DrawPaint(paint);
164 builder.Scale(0.5, 0.5);
167 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
168 "Roboto-Regular.ttf"));
169 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
174 DisplayListBuilder builder;
176 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
177 builder.DrawPaint(paint);
178 for (
int i = 0; i < 6; ++i) {
180 builder.Translate(300 * i, 0);
181 Scalar scale = 0.445 - (i / 1000.f);
182 builder.Scale(scale, scale);
184 GetContext(), builder,
"k",
"Roboto-Regular.ttf",
187 GetContext(), builder,
"k",
"Roboto-Regular.ttf",
191 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
197 auto callback = [&]() -> sk_sp<DisplayList> {
198 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
199 ImGuiWindowFlags_AlwaysAutoResize)) {
200 ImGui::SliderFloat(
"Scale", &scale, 4, 20);
204 DisplayListBuilder builder;
206 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
207 builder.DrawPaint(paint);
209 builder.Scale(scale, scale);
211 GetContext(), builder,
"HELLO",
"Roboto-Regular.ttf",
213 .color = (16 * scale >= 250) ? DlColor::kYellow()
214 : DlColor::kOrange(),
216 return builder.Build();
219 ASSERT_TRUE(OpenPlaygroundHere(callback));
226 auto callback = [&]() -> sk_sp<DisplayList> {
227 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
228 ImGuiWindowFlags_AlwaysAutoResize)) {
229 ImGui::SliderFloat(
"scale", &scale, 1.f, 300.f);
230 ImGui::SliderFloat(
"offsetx", &offsetx, -600.f, 100.f);
231 ImGui::SliderFloat(
"offsety", &offsety, 600.f, 2048.f);
234 DisplayListBuilder builder;
235 builder.Scale(GetContentScale().
x, GetContentScale().y);
237 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
238 builder.DrawPaint(paint);
239 builder.Scale(scale, scale);
242 GetContext(), builder,
"test",
"Roboto-Regular.ttf",
246 return builder.Build();
248 ASSERT_TRUE(OpenPlaygroundHere(callback));
254 auto callback = [&]() -> sk_sp<DisplayList> {
255 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
256 ImGuiWindowFlags_AlwaysAutoResize)) {
257 ImGui::SliderFloat(
"Fine Scale", &fine_scale, -1, 1);
262 DisplayListBuilder builder;
264 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
265 builder.DrawPaint(paint);
266 Scalar scale = 2.625 + fine_scale;
267 builder.Scale(scale, scale);
269 "the quick brown fox jumped over the lazy dog!.?",
270 "Roboto-Regular.ttf",
272 return builder.Build();
275 ASSERT_TRUE(OpenPlaygroundHere(callback));
280 float fpivot[2] = {200 + 30, 200 - 20};
281 float rotation = 180;
282 float foffset[2] = {200, 200};
284 auto callback = [&]() -> sk_sp<DisplayList> {
285 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
286 ImGuiWindowFlags_AlwaysAutoResize)) {
287 ImGui::SliderFloat(
"pivotx", &fpivot[0], 0, 300);
288 ImGui::SliderFloat(
"pivoty", &fpivot[1], 0, 300);
289 ImGui::SliderFloat(
"rotation", &rotation, 0, 360);
290 ImGui::SliderFloat(
"foffsetx", &foffset[0], 0, 300);
291 ImGui::SliderFloat(
"foffsety", &foffset[1], 0, 300);
294 DisplayListBuilder builder;
295 builder.Scale(GetContentScale().
x, GetContentScale().y);
296 builder.DrawPaint(DlPaint().setColor(DlColor(0xffffeeff)));
300 builder.Translate(pivot.x, pivot.y);
301 builder.Rotate(rotation);
302 builder.Translate(-pivot.x, -pivot.y);
306 .
color = DlColor::kBlack(),
307 .position =
DlPoint(foffset[0], foffset[1]),
311 return builder.Build();
313 ASSERT_TRUE(OpenPlaygroundHere(callback));
318 std::array<Scalar, 20> phase_offsets = {
319 7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
320 0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
321 0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
322 0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
323 auto callback = [&]() -> sk_sp<DisplayList> {
325 static float phase_variation = 0.2;
326 static float speed = 0.5;
327 static float magnitude = 100;
328 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
329 ImGuiWindowFlags_AlwaysAutoResize)) {
330 ImGui::SliderFloat(
"Font size", &
font_size, 5, 50);
331 ImGui::SliderFloat(
"Phase variation", &phase_variation, 0, 1);
332 ImGui::SliderFloat(
"Oscillation speed", &speed, 0, 2);
333 ImGui::SliderFloat(
"Oscillation magnitude", &magnitude, 0, 300);
337 DisplayListBuilder builder;
338 builder.Scale(GetContentScale().
x, GetContentScale().y);
340 for (
size_t i = 0; i < phase_offsets.size(); i++) {
343 magnitude * std::sin((-phase_offsets[i] *
k2Pi * phase_variation +
344 GetSecondsElapsed() * speed)),
348 GetContext(), builder,
349 "the quick brown fox jumped over "
351 "Roboto-Regular.ttf",
352 {.font_size =
font_size, .position = position})) {
356 return builder.Build();
359 ASSERT_TRUE(OpenPlaygroundHere(callback));
363 DisplayListBuilder builder;
366 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
367 builder.DrawPaint(paint);
370 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
371 "HomemadeApple.ttf"));
372 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
377 "Apple Color Emoji.ttc";
379 "NotoColorEmoji.ttf";
383 DisplayListBuilder builder;
386 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
387 builder.DrawPaint(paint);
390 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture));
391 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
395 DisplayListBuilder builder;
397 builder.Scale(GetContentScale().
x, GetContentScale().y);
399 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
400 builder.DrawPaint(paint);
403 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture,
405 .
color = DlColor::kBlue(),
406 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
407 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
411 DisplayListBuilder builder;
414 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
415 builder.DrawPaint(paint);
418 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture,
419 {.color = DlColor::kBlack().modulateOpacity(0.5)}));
420 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
424 DisplayListBuilder builder;
427 paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1));
428 builder.DrawPaint(paint);
430 builder.Translate(100, 100);
431 builder.Scale(0.5, 0.5);
434 paint.setBlendMode(DlBlendMode::kClear);
435 builder.SaveLayer(std::nullopt, &paint);
437 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
438 "Roboto-Regular.ttf"));
443 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
444 "Roboto-Regular.ttf"));
446 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
450 DisplayListBuilder builder;
451 builder.Translate(200, 150);
454 auto mapping = flutter::testing::OpenFixtureAsSkData(
"wtf.otf");
455 ASSERT_NE(mapping,
nullptr);
458 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
459 SkFont sk_font(font_mgr->makeFromData(mapping),
font_size);
462 text_paint.setColor(DlColor::kBlue().withAlpha(255 * 0.8));
467 } text[] = {{
DlPoint(0, 0),
"0F0F0F0"},
472 for (
auto& t : text) {
474 builder.Translate(t.position.x *
font_size * 2,
477 auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
478 ASSERT_NE(blob,
nullptr);
480 builder.DrawTextFrame(frame, 0, 0, text_paint);
485 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
489 DisplayListBuilder builder;
491 builder.Scale(GetContentScale().
x, GetContentScale().y);
493 paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 1.0));
494 builder.DrawPaint(paint);
496 builder.Transform(
Matrix(0.25, -0.3, 0, -0.002,
501 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
502 "Roboto-Regular.ttf"));
504 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
508 DisplayListBuilder builder;
513 0.0, 0.0, 0.0, 1.0) *
514 Matrix::MakeRotationY({
Degrees{10}});
519 "Roboto-Regular.ttf"));
520 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
524 DisplayListBuilder builder;
529 0.0, 0.0, 0.0, 1.0) *
530 Matrix::MakeRotationY({
Degrees{10}});
534 DlRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
536 builder.SaveLayer(window_bounds, &save_paint);
537 builder.Transform(matrix);
540 "Roboto-Regular.ttf"));
543 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
550 DisplayListBuilder builder;
553 builder.SaveLayer(std::nullopt, &save_paint);
554 builder.Transform(
Matrix(2000, 0, 0, 0,
561 "Roboto-Regular.ttf"));
562 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
566 DisplayListBuilder text_builder;
568 "Roboto-Regular.ttf"));
569 auto text_display_list = text_builder.Build();
571 DisplayListBuilder builder;
573 Matrix matrix = Matrix::MakeRow(2.0, 0.0, 0.0, 0.0,
576 0.0, 0.002, 0.0, 1.0);
580 DlRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
581 builder.SaveLayer(window_bounds, &save_paint);
582 builder.Transform(matrix);
583 builder.DrawDisplayList(text_display_list, 1.0f);
586 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
593 auto mapping = flutter::testing::OpenFixtureAsSkData(
"Roboto-Regular.ttf");
594 ASSERT_NE(mapping,
nullptr);
597 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
598 SkFont sk_font(font_mgr->makeFromData(mapping),
font_size);
601 text_paint.setColor(DlColor::kBlue());
603 std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
604 DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
605 std::vector<Scalar> stops = {
609 text_paint.setColorSource(DlColorSource::MakeLinear(
618 DisplayListBuilder builder;
619 builder.Translate(100, 100);
622 auto blob = SkTextBlob::MakeFromString(
"Hello", sk_font);
623 ASSERT_NE(blob,
nullptr);
625 builder.DrawTextFrame(frame, 0, 0, text_paint);
627 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
632 DisplayListBuilder builder;
635 DlColor clear_color(1.0, 0.5, 0.5, 0.5, DlColorSpace::kSRGB);
636 paint.setColor(clear_color);
637 builder.DrawPaint(paint);
639 DlMatrix identity = {
640 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
641 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
644 builder.Transform(identity);
646 DlRect frame = DlRect::MakeLTRB(1.0, 1.0, 1278.0, 763.0);
647 DlColor white(1.0, 1.0, 1.0, 1.0, DlColorSpace::kSRGB);
648 paint.setColor(white);
649 builder.DrawRect(frame, paint);
652 builder.ClipRect(frame, DlClipOp::kIntersect);
654 DlMatrix rect_xform = {
655 0.8241262, 0.56640625, 0.0, 0.0, -0.56640625, 0.8241262, 0.0, 0.0,
656 0.0, 0.0, 1.0, 0.0, 271.1137, 489.4733, 0.0, 1.0,
659 builder.Transform(rect_xform);
661 DlRect rect = DlRect::MakeLTRB(0.0, 0.0, 100.0, 100.0);
662 DlColor bluish(1.0, 0.184, 0.501, 0.929, DlColorSpace::kSRGB);
663 paint.setColor(bluish);
664 DlRoundRect rrect = DlRoundRect::MakeRectRadius(rect, 18.0);
665 builder.DrawRoundRect(rrect, paint);
668 builder.ClipRect(rect, DlClipOp::kIntersect);
673 DlMatrix path_xform = {
674 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
675 0.0, 0.0, 1.0, 0.0, 675.0, 279.5, 0.0, 1.0,
678 builder.Transform(path_xform);
680 DlPathBuilder path_builder;
681 path_builder.MoveTo(
DlPoint(87.5, 349.5));
682 path_builder.LineTo(
DlPoint(25.0, 29.5));
683 path_builder.LineTo(
DlPoint(150.0, 118.0));
684 path_builder.LineTo(
DlPoint(25.0, 118.0));
685 path_builder.LineTo(
DlPoint(150.0, 29.5));
686 path_builder.Close();
687 DlPath path = path_builder.TakePath();
689 DlColor fill_color(1.0, 1.0, 0.0, 0.0, DlColorSpace::kSRGB);
690 DlColor stroke_color(1.0, 0.0, 0.0, 0.0, DlColorSpace::kSRGB);
691 paint.setColor(fill_color);
692 paint.setDrawStyle(DlDrawStyle::kFill);
693 builder.DrawPath(path, paint);
695 paint.setColor(stroke_color);
696 paint.setStrokeWidth(2.0);
697 paint.setDrawStyle(DlDrawStyle::kStroke);
698 builder.DrawPath(path, paint);
704 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
709 std::make_shared<TypographerContextSkia>());
713 constexpr
const char* font_fixture =
"Roboto-Regular.ttf";
716 auto c_font_fixture = std::string(font_fixture);
717 auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
718 ASSERT_TRUE(mapping);
720 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
721 SkFont sk_font(font_mgr->makeFromData(mapping), 16);
723 auto blob = SkTextBlob::MakeFromString(
"Hello World", sk_font);
730 Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
733 auto scale = TextFrame::RoundScaledFontSize(
734 (preroll_matrix * Matrix::MakeTranslation(preroll_point))
735 .GetMaxBasisLengthXY());
750 ->CreateOffscreenMSAA(*aiks_context.
GetContext(), {100, 100}, 1);
756 text_contents.
SetColor(Color::Aqua());
758 Matrix not_preroll_matrix =
759 Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
764 std::shared_ptr<CommandBuffer> command_buffer =
765 aiks_context.
GetContext()->CreateCommandBuffer();
766 std::shared_ptr<RenderPass> render_pass =
767 command_buffer->CreateRenderPass(render_target);
774 DisplayListBuilder builder;
775 builder.Scale(GetContentScale().
x, GetContentScale().y);
777 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
778 builder.DrawPaint(paint);
781 std::make_shared<TypographerContextSkia>());
791 .
color = DlColor::kBlue(),
792 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
804 DisplayListBuilder builder;
805 builder.Scale(GetContentScale().
x, GetContentScale().y);
807 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
808 builder.DrawPaint(paint);
811 std::make_shared<TypographerContextSkia>());
818 for (
auto i = 0; i < 5; i++) {
822 .
color = DlColor::kBlue(),
823 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
837 DisplayListBuilder builder;
838 builder.Scale(GetContentScale().
x, GetContentScale().y);
840 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
841 builder.DrawPaint(paint);
844 std::make_shared<TypographerContextSkia>());
853 auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
854 ASSERT_TRUE(mapping);
855 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
856 SkFont sk_font(font_mgr->makeFromData(mapping), 50);
858 for (
auto i = 0; i < 10; i++) {
862 .
color = DlColor::kBlue(),
863 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)},
877 DisplayListBuilder builder;
879 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
880 builder.DrawPaint(paint);
881 builder.Scale(GetContentScale().
x, GetContentScale().y);
883 std::vector<Scalar> scales = {4, 8, 16, 24, 32};
884 std::vector<Scalar> spacing = {8, 8, 8, 8, 8};
887 for (
auto i = 0u; i < scales.size(); i++) {
889 builder.Scale(scales[i], scales[i]);
891 GetContext(), builder,
"lo",
"Roboto-Regular.ttf",
900 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)
A 4x4 matrix using column-major storage.
constexpr Quad Transform(const Quad &quad) const
std::shared_ptr< DlMaskFilter > filter