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"
27 #include "txt/platform.h"
39 DlColor color = DlColor::kYellow();
41 std::shared_ptr<DlMaskFilter>
filter;
46 DisplayListBuilder& canvas,
47 const std::string& text,
48 const std::string_view& font_fixture,
50 const std::optional<SkFont>& font = std::nullopt) {
53 paint.setColor(DlColor::kAqua().withAlpha(255 * 0.25));
55 DlRect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
59 paint.setColor(DlColor::kRed().withAlpha(255 * 0.25));
60 canvas.DrawCircle(options.position, 5.0, paint);
64 if (!font.has_value()) {
65 auto c_font_fixture = std::string(font_fixture);
67 flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
71 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
72 selected_font = SkFont(font_mgr->makeFromData(mapping), options.font_size);
73 if (options.is_subpixel) {
74 selected_font.setSubpixel(
true);
77 selected_font = font.value();
79 auto blob = SkTextBlob::MakeFromString(text.c_str(), selected_font);
88 text_paint.setColor(options.color);
89 text_paint.setMaskFilter(options.filter);
90 text_paint.setStrokeWidth(options.stroke_width);
91 text_paint.setDrawStyle(options.stroke ? DlDrawStyle::kStroke
92 : DlDrawStyle::kFill);
94 options.position.y, text_paint);
99 DisplayListBuilder builder;
102 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
103 builder.DrawPaint(paint);
105 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
106 "Roboto-Regular.ttf"));
108 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
112 DisplayListBuilder builder;
115 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
116 builder.DrawPaint(paint);
117 builder.Translate(1000, 0);
118 builder.Scale(-1, 1);
121 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
122 "Roboto-Regular.ttf"));
124 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
128 DisplayListBuilder builder;
131 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
132 builder.DrawPaint(paint);
135 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
136 "Roboto-Regular.ttf",
140 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
144 DisplayListBuilder builder;
147 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
148 builder.DrawPaint(paint);
156 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
160 DisplayListBuilder builder;
163 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
164 builder.DrawPaint(paint);
165 builder.Scale(0.5, 0.5);
168 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
169 "Roboto-Regular.ttf"));
170 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
175 DisplayListBuilder builder;
177 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
178 builder.DrawPaint(paint);
179 for (
int i = 0; i < 6; ++i) {
181 builder.Translate(300 * i, 0);
182 Scalar scale = 0.445 - (i / 1000.f);
183 builder.Scale(scale, scale);
185 GetContext(), builder,
"k",
"Roboto-Regular.ttf",
188 GetContext(), builder,
"k",
"Roboto-Regular.ttf",
192 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
198 auto callback = [&]() -> sk_sp<DisplayList> {
199 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
200 ImGuiWindowFlags_AlwaysAutoResize)) {
201 ImGui::SliderFloat(
"Scale", &scale, 4, 20);
205 DisplayListBuilder builder;
207 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
208 builder.DrawPaint(paint);
210 builder.Scale(scale, scale);
212 GetContext(), builder,
"HELLO",
"Roboto-Regular.ttf",
214 .color = (16 * scale >= 250) ? DlColor::kYellow()
215 : DlColor::kOrange(),
217 return builder.Build();
220 ASSERT_TRUE(OpenPlaygroundHere(callback));
227 auto callback = [&]() -> sk_sp<DisplayList> {
228 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
229 ImGuiWindowFlags_AlwaysAutoResize)) {
230 ImGui::SliderFloat(
"scale", &scale, 1.f, 300.f);
231 ImGui::SliderFloat(
"offsetx", &offsetx, -600.f, 100.f);
232 ImGui::SliderFloat(
"offsety", &offsety, 600.f, 2048.f);
235 DisplayListBuilder builder;
236 builder.Scale(GetContentScale().
x, GetContentScale().y);
238 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
239 builder.DrawPaint(paint);
240 builder.Scale(scale, scale);
243 GetContext(), builder,
"test",
"Roboto-Regular.ttf",
247 return builder.Build();
249 ASSERT_TRUE(OpenPlaygroundHere(callback));
255 auto callback = [&]() -> sk_sp<DisplayList> {
256 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
257 ImGuiWindowFlags_AlwaysAutoResize)) {
258 ImGui::SliderFloat(
"Fine Scale", &fine_scale, -1, 1);
263 DisplayListBuilder builder;
265 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
266 builder.DrawPaint(paint);
267 Scalar scale = 2.625 + fine_scale;
268 builder.Scale(scale, scale);
270 "the quick brown fox jumped over the lazy dog!.?",
271 "Roboto-Regular.ttf",
273 return builder.Build();
276 ASSERT_TRUE(OpenPlaygroundHere(callback));
281 float fpivot[2] = {200 + 30, 200 - 20};
282 float rotation = 180;
283 float foffset[2] = {200, 200};
285 auto callback = [&]() -> sk_sp<DisplayList> {
286 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
287 ImGuiWindowFlags_AlwaysAutoResize)) {
288 ImGui::SliderFloat(
"pivotx", &fpivot[0], 0, 300);
289 ImGui::SliderFloat(
"pivoty", &fpivot[1], 0, 300);
290 ImGui::SliderFloat(
"rotation", &rotation, 0, 360);
291 ImGui::SliderFloat(
"foffsetx", &foffset[0], 0, 300);
292 ImGui::SliderFloat(
"foffsety", &foffset[1], 0, 300);
295 DisplayListBuilder builder;
296 builder.Scale(GetContentScale().
x, GetContentScale().y);
297 builder.DrawPaint(DlPaint().setColor(DlColor(0xffffeeff)));
301 builder.Translate(pivot.x, pivot.y);
302 builder.Rotate(rotation);
303 builder.Translate(-pivot.x, -pivot.y);
307 .
color = DlColor::kBlack(),
308 .position =
DlPoint(foffset[0], foffset[1]),
312 return builder.Build();
314 ASSERT_TRUE(OpenPlaygroundHere(callback));
319 std::array<Scalar, 20> phase_offsets = {
320 7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
321 0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
322 0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
323 0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
324 auto callback = [&]() -> sk_sp<DisplayList> {
326 static float phase_variation = 0.2;
327 static float speed = 0.5;
328 static float magnitude = 100;
329 if (AiksTest::ImGuiBegin(
"Controls",
nullptr,
330 ImGuiWindowFlags_AlwaysAutoResize)) {
331 ImGui::SliderFloat(
"Font size", &
font_size, 5, 50);
332 ImGui::SliderFloat(
"Phase variation", &phase_variation, 0, 1);
333 ImGui::SliderFloat(
"Oscillation speed", &speed, 0, 2);
334 ImGui::SliderFloat(
"Oscillation magnitude", &magnitude, 0, 300);
338 DisplayListBuilder builder;
339 builder.Scale(GetContentScale().
x, GetContentScale().y);
341 for (
size_t i = 0; i < phase_offsets.size(); i++) {
344 magnitude * std::sin((-phase_offsets[i] *
k2Pi * phase_variation +
345 GetSecondsElapsed() * speed)),
349 GetContext(), builder,
350 "the quick brown fox jumped over "
352 "Roboto-Regular.ttf",
353 {.font_size =
font_size, .position = position})) {
357 return builder.Build();
360 ASSERT_TRUE(OpenPlaygroundHere(callback));
364 DisplayListBuilder builder;
367 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
368 builder.DrawPaint(paint);
371 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
372 "HomemadeApple.ttf"));
373 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
378 "Apple Color Emoji.ttc";
380 "NotoColorEmoji.ttf";
384 DisplayListBuilder builder;
387 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
388 builder.DrawPaint(paint);
391 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture));
392 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
396 DisplayListBuilder builder;
398 builder.Scale(GetContentScale().
x, GetContentScale().y);
400 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
401 builder.DrawPaint(paint);
404 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture,
406 .
color = DlColor::kBlue(),
407 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
408 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
412 DisplayListBuilder builder;
415 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
416 builder.DrawPaint(paint);
419 GetContext(), builder,
"😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
kFontFixture,
420 {.color = DlColor::kBlack().modulateOpacity(0.5)}));
421 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
425 DisplayListBuilder builder;
428 paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1));
429 builder.DrawPaint(paint);
431 builder.Translate(100, 100);
432 builder.Scale(0.5, 0.5);
435 paint.setBlendMode(DlBlendMode::kClear);
436 builder.SaveLayer(std::nullopt, &paint);
438 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
439 "Roboto-Regular.ttf"));
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;
452 builder.Translate(200, 150);
455 auto mapping = flutter::testing::OpenFixtureAsSkData(
"wtf.otf");
456 ASSERT_NE(mapping,
nullptr);
459 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
460 SkFont sk_font(font_mgr->makeFromData(mapping),
font_size);
463 text_paint.setColor(DlColor::kBlue().withAlpha(255 * 0.8));
468 } text[] = {{
DlPoint(0, 0),
"0F0F0F0"},
473 for (
auto& t : text) {
475 builder.Translate(t.position.x *
font_size * 2,
478 auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
479 ASSERT_NE(blob,
nullptr);
486 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
490 DisplayListBuilder builder;
492 builder.Scale(GetContentScale().
x, GetContentScale().y);
494 paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 1.0));
495 builder.DrawPaint(paint);
497 builder.Transform(
Matrix(0.25, -0.3, 0, -0.002,
502 GetContext(), builder,
"the quick brown fox jumped over the lazy dog!.?",
503 "Roboto-Regular.ttf"));
505 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
509 DisplayListBuilder builder;
514 0.0, 0.0, 0.0, 1.0) *
515 Matrix::MakeRotationY({
Degrees{10}});
520 "Roboto-Regular.ttf"));
521 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
525 DisplayListBuilder builder;
530 0.0, 0.0, 0.0, 1.0) *
531 Matrix::MakeRotationY({
Degrees{10}});
535 DlRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
537 builder.SaveLayer(window_bounds, &save_paint);
538 builder.Transform(matrix);
541 "Roboto-Regular.ttf"));
544 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
551 DisplayListBuilder builder;
554 builder.SaveLayer(std::nullopt, &save_paint);
555 builder.Transform(
Matrix(2000, 0, 0, 0,
562 "Roboto-Regular.ttf"));
563 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
567 DisplayListBuilder text_builder;
569 "Roboto-Regular.ttf"));
570 auto text_display_list = text_builder.Build();
572 DisplayListBuilder builder;
574 Matrix matrix = Matrix::MakeRow(2.0, 0.0, 0.0, 0.0,
577 0.0, 0.002, 0.0, 1.0);
581 DlRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
582 builder.SaveLayer(window_bounds, &save_paint);
583 builder.Transform(matrix);
584 builder.DrawDisplayList(text_display_list, 1.0f);
587 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
594 auto mapping = flutter::testing::OpenFixtureAsSkData(
"Roboto-Regular.ttf");
595 ASSERT_NE(mapping,
nullptr);
598 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
599 SkFont sk_font(font_mgr->makeFromData(mapping),
font_size);
602 text_paint.setColor(DlColor::kBlue());
604 std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
605 DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
606 std::vector<Scalar> stops = {
610 text_paint.setColorSource(DlColorSource::MakeLinear(
619 DisplayListBuilder builder;
620 builder.Translate(100, 100);
623 auto blob = SkTextBlob::MakeFromString(
"Hello", sk_font);
624 ASSERT_NE(blob,
nullptr);
628 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
633 DisplayListBuilder builder;
636 DlColor clear_color(1.0, 0.5, 0.5, 0.5, DlColorSpace::kSRGB);
637 paint.setColor(clear_color);
638 builder.DrawPaint(paint);
640 DlMatrix identity = {
641 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
642 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
645 builder.Transform(identity);
647 DlRect frame = DlRect::MakeLTRB(1.0, 1.0, 1278.0, 763.0);
648 DlColor white(1.0, 1.0, 1.0, 1.0, DlColorSpace::kSRGB);
649 paint.setColor(white);
650 builder.DrawRect(frame, paint);
653 builder.ClipRect(frame, DlClipOp::kIntersect);
655 DlMatrix rect_xform = {
656 0.8241262, 0.56640625, 0.0, 0.0, -0.56640625, 0.8241262, 0.0, 0.0,
657 0.0, 0.0, 1.0, 0.0, 271.1137, 489.4733, 0.0, 1.0,
660 builder.Transform(rect_xform);
662 DlRect rect = DlRect::MakeLTRB(0.0, 0.0, 100.0, 100.0);
663 DlColor bluish(1.0, 0.184, 0.501, 0.929, DlColorSpace::kSRGB);
664 paint.setColor(bluish);
665 DlRoundRect rrect = DlRoundRect::MakeRectRadius(rect, 18.0);
666 builder.DrawRoundRect(rrect, paint);
669 builder.ClipRect(rect, DlClipOp::kIntersect);
674 DlMatrix path_xform = {
675 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
676 0.0, 0.0, 1.0, 0.0, 675.0, 279.5, 0.0, 1.0,
679 builder.Transform(path_xform);
681 DlPathBuilder path_builder;
682 path_builder.MoveTo(
DlPoint(87.5, 349.5));
683 path_builder.LineTo(
DlPoint(25.0, 29.5));
684 path_builder.LineTo(
DlPoint(150.0, 118.0));
685 path_builder.LineTo(
DlPoint(25.0, 118.0));
686 path_builder.LineTo(
DlPoint(150.0, 29.5));
687 path_builder.Close();
688 DlPath path = path_builder.TakePath();
690 DlColor fill_color(1.0, 1.0, 0.0, 0.0, DlColorSpace::kSRGB);
691 DlColor stroke_color(1.0, 0.0, 0.0, 0.0, DlColorSpace::kSRGB);
692 paint.setColor(fill_color);
693 paint.setDrawStyle(DlDrawStyle::kFill);
694 builder.DrawPath(path, paint);
696 paint.setColor(stroke_color);
697 paint.setStrokeWidth(2.0);
698 paint.setDrawStyle(DlDrawStyle::kStroke);
699 builder.DrawPath(path, paint);
705 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
710 std::make_shared<TypographerContextSkia>());
714 constexpr
const char* font_fixture =
"Roboto-Regular.ttf";
717 auto c_font_fixture = std::string(font_fixture);
718 auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
719 ASSERT_TRUE(mapping);
721 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
722 SkFont sk_font(font_mgr->makeFromData(mapping), 16);
724 auto blob = SkTextBlob::MakeFromString(
"Hello World", sk_font);
731 Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
734 auto scale = TextFrame::RoundScaledFontSize(
735 (preroll_matrix * Matrix::MakeTranslation(preroll_point))
736 .GetMaxBasisLengthXY());
751 ->CreateOffscreenMSAA(*aiks_context.
GetContext(), {100, 100}, 1);
757 text_contents.
SetColor(Color::Aqua());
759 Matrix not_preroll_matrix =
760 Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
765 std::shared_ptr<CommandBuffer> command_buffer =
766 aiks_context.
GetContext()->CreateCommandBuffer();
767 std::shared_ptr<RenderPass> render_pass =
768 command_buffer->CreateRenderPass(render_target);
775 DisplayListBuilder builder;
776 builder.Scale(GetContentScale().
x, GetContentScale().y);
778 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
779 builder.DrawPaint(paint);
782 std::make_shared<TypographerContextSkia>());
792 .
color = DlColor::kBlue(),
793 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
805 DisplayListBuilder builder;
806 builder.Scale(GetContentScale().
x, GetContentScale().y);
808 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
809 builder.DrawPaint(paint);
812 std::make_shared<TypographerContextSkia>());
819 for (
auto i = 0; i < 5; i++) {
823 .
color = DlColor::kBlue(),
824 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
838 DisplayListBuilder builder;
839 builder.Scale(GetContentScale().
x, GetContentScale().y);
841 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
842 builder.DrawPaint(paint);
845 std::make_shared<TypographerContextSkia>());
854 auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
855 ASSERT_TRUE(mapping);
856 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
857 SkFont sk_font(font_mgr->makeFromData(mapping), 50);
859 for (
auto i = 0; i < 10; i++) {
863 .
color = DlColor::kBlue(),
864 .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)},
878 DisplayListBuilder builder;
880 paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
881 builder.DrawPaint(paint);
882 builder.Scale(GetContentScale().
x, GetContentScale().y);
884 std::vector<Scalar> scales = {4, 8, 16, 24, 32};
885 std::vector<Scalar> spacing = {8, 8, 8, 8, 8};
888 for (
auto i = 0u; i < scales.size(); i++) {
890 builder.Scale(scales[i], scales[i]);
892 GetContext(), builder,
"lo",
"Roboto-Regular.ttf",
901 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
static std::shared_ptr< DlTextImpeller > Make(const std::shared_ptr< impeller::TextFrame > &frame)
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