Flutter Impeller
aiks_dl_text_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
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"
11 
12 #include "flutter/display_list/dl_builder.h"
13 #include "flutter/display_list/dl_color.h"
14 #include "flutter/display_list/dl_paint.h"
15 #include "flutter/testing/testing.h"
21 #include "include/core/SkMatrix.h"
22 #include "include/core/SkRect.h"
23 
24 #include "txt/platform.h"
25 
26 using namespace flutter;
27 /////////////////////////////////////////////////////
28 
29 namespace impeller {
30 namespace testing {
31 
33  bool stroke = false;
36  DlColor color = DlColor::kYellow();
37  SkPoint position = SkPoint::Make(100, 200);
38  std::shared_ptr<DlMaskFilter> filter;
39 };
40 
41 bool RenderTextInCanvasSkia(const std::shared_ptr<Context>& context,
42  DisplayListBuilder& canvas,
43  const std::string& text,
44  const std::string_view& font_fixture,
45  const TextRenderOptions& options = {}) {
46  // Draw the baseline.
47  DlPaint paint;
48  paint.setColor(DlColor::kAqua().withAlpha(255 * 0.25));
49  canvas.DrawRect(SkRect::MakeXYWH(options.position.x() - 50,
50  options.position.y(), 900, 10),
51  paint);
52 
53  // Mark the point at which the text is drawn.
54  paint.setColor(DlColor::kRed().withAlpha(255 * 0.25));
55  canvas.DrawCircle(options.position, 5.0, paint);
56 
57  // Construct the text blob.
58  auto c_font_fixture = std::string(font_fixture);
59  auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
60  if (!mapping) {
61  return false;
62  }
63  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
64  SkFont sk_font(font_mgr->makeFromData(mapping), options.font_size);
65  auto blob = SkTextBlob::MakeFromString(text.c_str(), sk_font);
66  if (!blob) {
67  return false;
68  }
69 
70  // Create the Impeller text frame and draw it at the designated baseline.
71  auto frame = MakeTextFrameFromTextBlobSkia(blob);
72 
73  DlPaint text_paint;
74  text_paint.setColor(options.color);
75  text_paint.setMaskFilter(options.filter);
76  text_paint.setStrokeWidth(options.stroke_width);
77  text_paint.setDrawStyle(options.stroke ? DlDrawStyle::kStroke
78  : DlDrawStyle::kFill);
79  canvas.DrawTextFrame(frame, options.position.x(), options.position.y(),
80  text_paint);
81  return true;
82 }
83 
84 bool RenderTextInCanvasSTB(const std::shared_ptr<Context>& context,
85  DisplayListBuilder& canvas,
86  const std::string& text,
87  const std::string& font_fixture,
88  const TextRenderOptions& options = {}) {
89  // Draw the baseline.
90  DlPaint paint;
91  paint.setColor(DlColor::kAqua().withAlpha(255 * 0.25));
92  canvas.DrawRect(SkRect::MakeXYWH(options.position.x() - 50,
93  options.position.y(), 900, 10),
94  paint);
95 
96  // Mark the point at which the text is drawn.
97  paint.setColor(DlColor::kRed().withAlpha(255 * 0.25));
98  canvas.DrawCircle(options.position, 5.0, paint);
99 
100  // Construct the text blob.
101  auto mapping = flutter::testing::OpenFixtureAsMapping(font_fixture.c_str());
102  if (!mapping) {
103  return false;
104  }
105  auto typeface_stb = std::make_shared<TypefaceSTB>(std::move(mapping));
106 
107  auto frame = MakeTextFrameSTB(
108  typeface_stb, Font::Metrics{.point_size = options.font_size}, text);
109 
110  DlPaint text_paint;
111  text_paint.setColor(options.color);
112 
113  canvas.DrawTextFrame(frame, options.position.x(), options.position.y(),
114  text_paint);
115  return true;
116 }
117 
118 TEST_P(AiksTest, CanRenderTextFrame) {
119  DisplayListBuilder builder;
120 
121  DlPaint paint;
122  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
123  builder.DrawPaint(paint);
124  ASSERT_TRUE(RenderTextInCanvasSkia(
125  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
126  "Roboto-Regular.ttf"));
127 
128  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
129 }
130 
131 TEST_P(AiksTest, CanRenderTextFrameWithInvertedTransform) {
132  DisplayListBuilder builder;
133 
134  DlPaint paint;
135  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
136  builder.DrawPaint(paint);
137  builder.Translate(1000, 0);
138  builder.Scale(-1, 1);
139 
140  ASSERT_TRUE(RenderTextInCanvasSkia(
141  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
142  "Roboto-Regular.ttf"));
143 
144  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
145 }
146 
147 TEST_P(AiksTest, CanRenderStrokedTextFrame) {
148  DisplayListBuilder builder;
149 
150  DlPaint paint;
151  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
152  builder.DrawPaint(paint);
153 
154  ASSERT_TRUE(RenderTextInCanvasSkia(
155  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
156  "Roboto-Regular.ttf",
157  {
158  .stroke = true,
159  }));
160  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
161 }
162 
163 TEST_P(AiksTest, CanRenderTextStrokeWidth) {
164  DisplayListBuilder builder;
165 
166  DlPaint paint;
167  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
168  builder.DrawPaint(paint);
169 
170  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "LMNOP VWXYZ",
171  "Roboto-Medium.ttf",
172  {
173  .stroke = true,
174  .stroke_width = 4,
175  }));
176  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
177 }
178 
179 TEST_P(AiksTest, CanRenderTextFrameWithHalfScaling) {
180  DisplayListBuilder builder;
181 
182  DlPaint paint;
183  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
184  builder.DrawPaint(paint);
185  builder.Scale(0.5, 0.5);
186 
187  ASSERT_TRUE(RenderTextInCanvasSkia(
188  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
189  "Roboto-Regular.ttf"));
190  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
191 }
192 
193 TEST_P(AiksTest, CanRenderTextFrameWithFractionScaling) {
194  DisplayListBuilder builder;
195 
196  DlPaint paint;
197  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
198  builder.DrawPaint(paint);
199  builder.Scale(2.625, 2.625);
200 
201  ASSERT_TRUE(RenderTextInCanvasSkia(
202  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
203  "Roboto-Regular.ttf"));
204  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
205 }
206 
207 TEST_P(AiksTest, CanRenderTextFrameSTB) {
208  DisplayListBuilder builder;
209 
210  DlPaint paint;
211  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
212  builder.DrawPaint(paint);
213 
214  ASSERT_TRUE(RenderTextInCanvasSTB(
215  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
216  "Roboto-Regular.ttf"));
217 
218  SetTypographerContext(TypographerContextSTB::Make());
219  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
220 }
221 
222 TEST_P(AiksTest, TextFrameSubpixelAlignment) {
223  // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens.
224  std::array<Scalar, 20> phase_offsets = {
225  7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
226  0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
227  0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
228  0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
229  auto callback = [&]() -> sk_sp<DisplayList> {
230  static float font_size = 20;
231  static float phase_variation = 0.2;
232  static float speed = 0.5;
233  static float magnitude = 100;
234  if (AiksTest::ImGuiBegin("Controls", nullptr,
235  ImGuiWindowFlags_AlwaysAutoResize)) {
236  ImGui::SliderFloat("Font size", &font_size, 5, 50);
237  ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1);
238  ImGui::SliderFloat("Oscillation speed", &speed, 0, 2);
239  ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300);
240  ImGui::End();
241  }
242 
243  DisplayListBuilder builder;
244  builder.Scale(GetContentScale().x, GetContentScale().y);
245 
246  for (size_t i = 0; i < phase_offsets.size(); i++) {
247  SkPoint position = SkPoint::Make(
248  200 +
249  magnitude * std::sin((-phase_offsets[i] * k2Pi * phase_variation +
250  GetSecondsElapsed() * speed)), //
251  200 + i * font_size * 1.1 //
252  );
254  GetContext(), builder,
255  "the quick brown fox jumped over "
256  "the lazy dog!.?",
257  "Roboto-Regular.ttf",
258  {.font_size = font_size, .position = position})) {
259  return nullptr;
260  }
261  }
262  return builder.Build();
263  };
264 
265  ASSERT_TRUE(OpenPlaygroundHere(callback));
266 }
267 
268 TEST_P(AiksTest, CanRenderItalicizedText) {
269  DisplayListBuilder builder;
270 
271  DlPaint paint;
272  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
273  builder.DrawPaint(paint);
274 
275  ASSERT_TRUE(RenderTextInCanvasSkia(
276  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
277  "HomemadeApple.ttf"));
278  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
279 }
280 
281 static constexpr std::string_view kFontFixture =
282 #if FML_OS_MACOSX
283  "Apple Color Emoji.ttc";
284 #else
285  "NotoColorEmoji.ttf";
286 #endif
287 
288 TEST_P(AiksTest, CanRenderEmojiTextFrame) {
289  DisplayListBuilder builder;
290 
291  DlPaint paint;
292  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
293  builder.DrawPaint(paint);
294 
295  ASSERT_TRUE(RenderTextInCanvasSkia(
296  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture));
297  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
298 }
299 
300 TEST_P(AiksTest, CanRenderEmojiTextFrameWithBlur) {
301  DisplayListBuilder builder;
302 
303  builder.Scale(GetContentScale().x, GetContentScale().y);
304  DlPaint paint;
305  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
306  builder.DrawPaint(paint);
307 
308  ASSERT_TRUE(RenderTextInCanvasSkia(
309  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
311  .color = DlColor::kBlue(),
312  .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
313  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
314 }
315 
316 TEST_P(AiksTest, CanRenderEmojiTextFrameWithAlpha) {
317  DisplayListBuilder builder;
318 
319  DlPaint paint;
320  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
321  builder.DrawPaint(paint);
322 
323  ASSERT_TRUE(RenderTextInCanvasSkia(
324  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
325  {.color = DlColor::kBlack().modulateOpacity(0.5)}));
326  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
327 }
328 
329 TEST_P(AiksTest, CanRenderTextInSaveLayer) {
330  DisplayListBuilder builder;
331 
332  DlPaint paint;
333  paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1));
334  builder.DrawPaint(paint);
335 
336  builder.Translate(100, 100);
337  builder.Scale(0.5, 0.5);
338 
339  // Blend the layer with the parent pass using kClear to expose the coverage.
340  paint.setBlendMode(DlBlendMode::kClear);
341  builder.SaveLayer(nullptr, &paint);
342  ASSERT_TRUE(RenderTextInCanvasSkia(
343  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
344  "Roboto-Regular.ttf"));
345  builder.Restore();
346 
347  // Render the text again over the cleared coverage rect.
348  ASSERT_TRUE(RenderTextInCanvasSkia(
349  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
350  "Roboto-Regular.ttf"));
351 
352  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
353 }
354 
355 TEST_P(AiksTest, CanRenderTextOutsideBoundaries) {
356  DisplayListBuilder builder;
357  builder.Translate(200, 150);
358 
359  // Construct the text blob.
360  auto mapping = flutter::testing::OpenFixtureAsSkData("wtf.otf");
361  ASSERT_NE(mapping, nullptr);
362 
363  Scalar font_size = 80;
364  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
365  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
366 
367  DlPaint text_paint;
368  text_paint.setColor(DlColor::kBlue().withAlpha(255 * 0.8));
369 
370  struct {
371  SkPoint position;
372  const char* text;
373  } text[] = {{SkPoint::Make(0, 0), "0F0F0F0"},
374  {SkPoint::Make(1, 2), "789"},
375  {SkPoint::Make(1, 3), "456"},
376  {SkPoint::Make(1, 4), "123"},
377  {SkPoint::Make(0, 6), "0F0F0F0"}};
378  for (auto& t : text) {
379  builder.Save();
380  builder.Translate(t.position.x() * font_size * 2,
381  t.position.y() * font_size * 1.1);
382  {
383  auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
384  ASSERT_NE(blob, nullptr);
385  auto frame = MakeTextFrameFromTextBlobSkia(blob);
386  builder.DrawTextFrame(frame, 0, 0, text_paint);
387  }
388  builder.Restore();
389  }
390 
391  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
392 }
393 
394 TEST_P(AiksTest, TextRotated) {
395  DisplayListBuilder builder;
396 
397  builder.Scale(GetContentScale().x, GetContentScale().y);
398  DlPaint paint;
399  paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 1.0));
400  builder.DrawPaint(paint);
401 
402  builder.Transform(SkM44::ColMajor(Matrix(0.25, -0.3, 0, -0.002, //
403  0, 0.5, 0, 0, //
404  0, 0, 0.3, 0, //
405  100, 100, 0, 1.3)
406  .m));
407  ASSERT_TRUE(RenderTextInCanvasSkia(
408  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
409  "Roboto-Regular.ttf"));
410 
411  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
412 }
413 
414 TEST_P(AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer) {
415  DisplayListBuilder builder;
416 
417  Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, //
418  0.0, 1.0, 0.0, 0.0, //
419  0.0, 0.0, 1.0, 0.01, //
420  0.0, 0.0, 0.0, 1.0) * //
421  Matrix::MakeRotationY({Degrees{10}});
422 
423  builder.Transform(SkM44::ColMajor(matrix.m));
424 
425  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
426  "Roboto-Regular.ttf"));
427  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
428 }
429 
430 TEST_P(AiksTest, DrawScaledTextWithPerspectiveSaveLayer) {
431  DisplayListBuilder builder;
432 
433  Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, //
434  0.0, 1.0, 0.0, 0.0, //
435  0.0, 0.0, 1.0, 0.01, //
436  0.0, 0.0, 0.0, 1.0) * //
437  Matrix::MakeRotationY({Degrees{10}});
438 
439  DlPaint save_paint;
440  SkRect window_bounds =
441  SkRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
442  // Note: bounds were not needed by the AIKS version, which may indicate a bug.
443  builder.SaveLayer(&window_bounds, &save_paint);
444  builder.Transform(SkM44::ColMajor(matrix.m));
445 
446  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
447  "Roboto-Regular.ttf"));
448 
449  builder.Restore();
450  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
451 }
452 
453 TEST_P(AiksTest, CanRenderTextWithLargePerspectiveTransform) {
454  // Verifies that text scales are clamped to work around
455  // https://github.com/flutter/flutter/issues/136112 .
456 
457  DisplayListBuilder builder;
458 
459  DlPaint save_paint;
460  builder.SaveLayer(nullptr, &save_paint);
461  builder.Transform(SkM44::ColMajor(Matrix(2000, 0, 0, 0, //
462  0, 2000, 0, 0, //
463  0, 0, -1, 9000, //
464  0, 0, -1, 7000 //
465  )
466  .m));
467 
468  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
469  "Roboto-Regular.ttf"));
470  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
471 }
472 
473 TEST_P(AiksTest, CanRenderTextWithPerspectiveTransformInSublist) {
474  DisplayListBuilder text_builder;
475  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), text_builder, "Hello world",
476  "Roboto-Regular.ttf"));
477  auto text_display_list = text_builder.Build();
478 
479  DisplayListBuilder builder;
480 
481  Matrix matrix = Matrix::MakeRow(2.0, 0.0, 0.0, 0.0, //
482  0.0, 2.0, 0.0, 0.0, //
483  0.0, 0.0, 1.0, 0.0, //
484  0.0, 0.002, 0.0, 1.0);
485 
486  DlPaint save_paint;
487  SkRect window_bounds =
488  SkRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
489  builder.SaveLayer(&window_bounds, &save_paint);
490  builder.Transform(SkM44::ColMajor(matrix.m));
491  builder.DrawDisplayList(text_display_list, 1.0f);
492  builder.Restore();
493 
494  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
495 }
496 
497 // This currently renders solid blue, as the support for text color sources was
498 // moved into DLDispatching. Path data requires the SkTextBlobs which are not
499 // used in impeller::TextFrames.
500 TEST_P(AiksTest, TextForegroundShaderWithTransform) {
501  auto mapping = flutter::testing::OpenFixtureAsSkData("Roboto-Regular.ttf");
502  ASSERT_NE(mapping, nullptr);
503 
504  Scalar font_size = 100;
505  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
506  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
507 
508  DlPaint text_paint;
509  text_paint.setColor(DlColor::kBlue());
510 
511  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
512  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
513  std::vector<Scalar> stops = {
514  0.0,
515  1.0,
516  };
517  text_paint.setColorSource(DlColorSource::MakeLinear(
518  /*start_point=*/{0, 0}, //
519  /*end_point=*/{100, 100}, //
520  /*stop_count=*/2, //
521  /*colors=*/colors.data(), //
522  /*stops=*/stops.data(), //
523  /*tile_mode=*/DlTileMode::kRepeat //
524  ));
525 
526  DisplayListBuilder builder;
527  builder.Translate(100, 100);
528  builder.Rotate(45);
529 
530  auto blob = SkTextBlob::MakeFromString("Hello", sk_font);
531  ASSERT_NE(blob, nullptr);
532  auto frame = MakeTextFrameFromTextBlobSkia(blob);
533  builder.DrawTextFrame(frame, 0, 0, text_paint);
534 
535  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
536 }
537 
538 } // namespace testing
539 } // namespace impeller
impeller::Matrix::m
Scalar m[16]
Definition: matrix.h:39
typeface_stb.h
impeller::testing::RenderTextInCanvasSkia
bool RenderTextInCanvasSkia(const std::shared_ptr< Context > &context, DisplayListBuilder &canvas, const std::string &text, const std::string_view &font_fixture, const TextRenderOptions &options={})
Definition: aiks_dl_text_unittests.cc:41
impeller::AiksPlayground
Definition: aiks_playground.h:16
impeller::Scalar
float Scalar
Definition: scalar.h:18
aiks_unittests.h
impeller::testing::TextRenderOptions::filter
std::shared_ptr< DlMaskFilter > filter
Definition: aiks_dl_text_unittests.cc:38
font_size
SkScalar font_size
Definition: dl_golden_blur_unittests.cc:23
impeller::testing::TextRenderOptions
Definition: aiks_dl_text_unittests.cc:32
stroke_width
const Scalar stroke_width
Definition: stroke_path_geometry.cc:297
impeller::MakeTextFrameSTB
std::shared_ptr< TextFrame > MakeTextFrameSTB(const std::shared_ptr< TypefaceSTB > &typeface_stb, Font::Metrics metrics, const std::string &text)
Definition: text_frame_stb.cc:11
matrix.h
text_frame_skia.h
impeller::k2Pi
constexpr float k2Pi
Definition: constants.h:29
text_frame_stb.h
flutter
Definition: dl_golden_blur_unittests.cc:15
impeller::Matrix::Transform
constexpr Quad Transform(const Quad &quad) const
Definition: matrix.h:513
impeller::testing::TEST_P
TEST_P(AiksTest, TextForegroundShaderWithTransform)
Definition: aiks_dl_text_unittests.cc:500
impeller::MakeTextFrameFromTextBlobSkia
std::shared_ptr< TextFrame > MakeTextFrameFromTextBlobSkia(const sk_sp< SkTextBlob > &blob)
Definition: text_frame_skia.cc:42
impeller::testing::TextRenderOptions::color
DlColor color
Definition: aiks_dl_text_unittests.cc:36
impeller::testing::kFontFixture
static constexpr std::string_view kFontFixture
Definition: aiks_dl_text_unittests.cc:281
impeller::Degrees
Definition: scalar.h:51
color
DlColor color
Definition: dl_golden_blur_unittests.cc:24
typographer_context_stb.h
impeller::testing::RenderTextInCanvasSTB
bool RenderTextInCanvasSTB(const std::shared_ptr< Context > &context, DisplayListBuilder &canvas, const std::string &text, const std::string &font_fixture, const TextRenderOptions &options={})
Definition: aiks_dl_text_unittests.cc:84
impeller
Definition: allocation.cc:12
stroke
bool stroke
Definition: dl_golden_blur_unittests.cc:22
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37