Flutter Impeller
impeller::skia_conversions Namespace Reference

Functions

Rect ToRect (const SkRect &rect)
 
std::optional< RectToRect (const SkRect *rect)
 
std::vector< RectToRects (const SkRect tex[], int count)
 
std::vector< PointToPoints (const SkPoint points[], int count)
 
PathBuilder::RoundingRadii ToRoundingRadii (const SkRRect &rrect)
 
Path ToPath (const SkPath &path, Point shift)
 
Path ToPath (const SkRRect &rrect)
 
Point ToPoint (const SkPoint &point)
 
Color ToColor (const flutter::DlColor &color)
 
std::vector< MatrixToRSXForms (const SkRSXform xform[], int count)
 
Path PathDataFromTextBlob (const sk_sp< SkTextBlob > &blob, Point shift)
 
std::optional< impeller::PixelFormatToPixelFormat (SkColorType type)
 
void ConvertStops (const flutter::DlGradientColorSourceBase *gradient, std::vector< Color > &colors, std::vector< float > &stops)
 Convert display list colors + stops into impeller colors and stops, taking care to ensure that the stops monotonically increase from 0.0 to 1.0. More...
 

Function Documentation

◆ ConvertStops()

void impeller::skia_conversions::ConvertStops ( const flutter::DlGradientColorSourceBase *  gradient,
std::vector< Color > &  colors,
std::vector< float > &  stops 
)

Convert display list colors + stops into impeller colors and stops, taking care to ensure that the stops monotonically increase from 0.0 to 1.0.

The general process is:

  • Ensure that the first gradient stop value is 0.0. If not, insert a new stop with a value of 0.0 and use the first gradient color as this new stops color.
  • Ensure the last gradient stop value is 1.0. If not, insert a new stop with a value of 1.0 and use the last gradient color as this stops color.
  • Clamp all gradient values between the values of 0.0 and 1.0.
  • For all stop values, ensure that the values are monotonically increasing by clamping each value to a minimum of the previous stop value and itself. For example, with stop values of 0.0, 0.5, 0.4, 1.0, we would clamp such that the values were 0.0, 0.5, 0.5, 1.0.

Definition at line 192 of file skia_conversions.cc.

194  {
195  FML_DCHECK(gradient->stop_count() >= 2);
196 
197  auto* dl_colors = gradient->colors();
198  auto* dl_stops = gradient->stops();
199  if (dl_stops[0] != 0.0) {
200  colors.emplace_back(skia_conversions::ToColor(dl_colors[0]));
201  stops.emplace_back(0);
202  }
203  for (auto i = 0; i < gradient->stop_count(); i++) {
204  colors.emplace_back(skia_conversions::ToColor(dl_colors[i]));
205  stops.emplace_back(std::clamp(dl_stops[i], 0.0f, 1.0f));
206  }
207  if (dl_stops[gradient->stop_count() - 1] != 1.0) {
208  colors.emplace_back(colors.back());
209  stops.emplace_back(1.0);
210  }
211  for (auto i = 1; i < gradient->stop_count(); i++) {
212  stops[i] = std::clamp(stops[i], stops[i - 1], stops[i]);
213  }
214 }

References ToColor().

Referenced by impeller::DlDispatcher::setColorSource(), and impeller::testing::TEST().

◆ PathDataFromTextBlob()

Path impeller::skia_conversions::PathDataFromTextBlob ( const sk_sp< SkTextBlob > &  blob,
Point  shift 
)

Definition at line 168 of file skia_conversions.cc.

168  {
169  if (!blob) {
170  return {};
171  }
172 
173  return ToPath(skia::textlayout::Paragraph::GetPath(blob.get()), shift);
174 }

References ToPath().

◆ ToColor()

Color impeller::skia_conversions::ToColor ( const flutter::DlColor &  color)

Definition at line 142 of file skia_conversions.cc.

142  {
143  return {
144  static_cast<Scalar>(color.getRedF()), //
145  static_cast<Scalar>(color.getGreenF()), //
146  static_cast<Scalar>(color.getBlueF()), //
147  static_cast<Scalar>(color.getAlphaF()) //
148  };
149 }

Referenced by ConvertStops(), impeller::DlDispatcher::drawColor(), impeller::DlDispatcher::drawShadow(), impeller::MakeVertices(), impeller::testing::TEST(), impeller::ToColorFilter(), and impeller::ToColors().

◆ ToPath() [1/2]

Path impeller::skia_conversions::ToPath ( const SkPath &  path,
Point  shift 
)

Definition at line 49 of file skia_conversions.cc.

49  {
50  auto iterator = SkPath::Iter(path, false);
51 
52  struct PathData {
53  union {
54  SkPoint points[4];
55  };
56  };
57 
58  PathBuilder builder;
59  PathData data;
60  auto verb = SkPath::Verb::kDone_Verb;
61  do {
62  verb = iterator.next(data.points);
63  switch (verb) {
64  case SkPath::kMove_Verb:
65  builder.MoveTo(ToPoint(data.points[0]));
66  break;
67  case SkPath::kLine_Verb:
68  builder.LineTo(ToPoint(data.points[1]));
69  break;
70  case SkPath::kQuad_Verb:
71  builder.QuadraticCurveTo(ToPoint(data.points[1]),
72  ToPoint(data.points[2]));
73  break;
74  case SkPath::kConic_Verb: {
75  constexpr auto kPow2 = 1; // Only works for sweeps up to 90 degrees.
76  constexpr auto kQuadCount = 1 + (2 * (1 << kPow2));
77  SkPoint points[kQuadCount];
78  const auto curve_count =
79  SkPath::ConvertConicToQuads(data.points[0], //
80  data.points[1], //
81  data.points[2], //
82  iterator.conicWeight(), //
83  points, //
84  kPow2 //
85  );
86 
87  for (int curve_index = 0, point_index = 0; //
88  curve_index < curve_count; //
89  curve_index++, point_index += 2 //
90  ) {
91  builder.QuadraticCurveTo(ToPoint(points[point_index + 1]),
92  ToPoint(points[point_index + 2]));
93  }
94  } break;
95  case SkPath::kCubic_Verb:
96  builder.CubicCurveTo(ToPoint(data.points[1]), ToPoint(data.points[2]),
97  ToPoint(data.points[3]));
98  break;
99  case SkPath::kClose_Verb:
100  builder.Close();
101  break;
102  case SkPath::kDone_Verb:
103  break;
104  }
105  } while (verb != SkPath::Verb::kDone_Verb);
106 
107  FillType fill_type;
108  switch (path.getFillType()) {
109  case SkPathFillType::kWinding:
110  fill_type = FillType::kNonZero;
111  break;
112  case SkPathFillType::kEvenOdd:
113  fill_type = FillType::kOdd;
114  break;
115  case SkPathFillType::kInverseWinding:
116  case SkPathFillType::kInverseEvenOdd:
117  // Flutter doesn't expose these path fill types. These are only visible
118  // via the receiver interface. We should never get here.
119  fill_type = FillType::kNonZero;
120  break;
121  }
122  builder.SetConvexity(path.isConvex() ? Convexity::kConvex
123  : Convexity::kUnknown);
124  builder.Shift(shift);
125  auto sk_bounds = path.getBounds().makeOutset(shift.x, shift.y);
126  builder.SetBounds(ToRect(sk_bounds));
127  return builder.TakePath(fill_type);
128 }

References impeller::PathBuilder::Close(), impeller::PathBuilder::CubicCurveTo(), impeller::kConvex, impeller::kNonZero, impeller::kOdd, impeller::kUnknown, impeller::PathBuilder::LineTo(), impeller::PathBuilder::MoveTo(), impeller::PathBuilder::QuadraticCurveTo(), impeller::PathBuilder::SetBounds(), impeller::PathBuilder::SetConvexity(), impeller::PathBuilder::Shift(), impeller::PathBuilder::TakePath(), ToPoint(), ToRect(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by impeller::DlDispatcher::clipPath(), impeller::DlDispatcher::clipRRect(), impeller::DlDispatcher::drawDRRect(), impeller::DlDispatcher::drawPath(), impeller::DlDispatcher::drawRRect(), impeller::DlDispatcher::drawShadow(), PathDataFromTextBlob(), and impeller::testing::TEST_P().

◆ ToPath() [2/2]

Path impeller::skia_conversions::ToPath ( const SkRRect &  rrect)

Definition at line 130 of file skia_conversions.cc.

130  {
131  return PathBuilder{}
132  .AddRoundedRect(ToRect(rrect.getBounds()), ToRoundingRadii(rrect))
133  .SetConvexity(Convexity::kConvex)
134  .SetBounds(ToRect(rrect.getBounds()))
135  .TakePath();
136 }

References impeller::PathBuilder::AddRoundedRect(), impeller::kConvex, impeller::PathBuilder::SetBounds(), impeller::PathBuilder::SetConvexity(), impeller::PathBuilder::TakePath(), ToRect(), and ToRoundingRadii().

◆ ToPixelFormat()

std::optional< impeller::PixelFormat > impeller::skia_conversions::ToPixelFormat ( SkColorType  type)

Definition at line 176 of file skia_conversions.cc.

176  {
177  switch (type) {
178  case kRGBA_8888_SkColorType:
180  case kBGRA_8888_SkColorType:
182  case kRGBA_F16_SkColorType:
184  case kBGR_101010x_XR_SkColorType:
186  default:
187  return std::nullopt;
188  }
189  return std::nullopt;
190 }

References impeller::kB10G10R10XR, impeller::kB8G8R8A8UNormInt, impeller::kR16G16B16A16Float, and impeller::kR8G8B8A8UNormInt.

◆ ToPoint()

◆ ToPoints()

std::vector< Point > impeller::skia_conversions::ToPoints ( const SkPoint  points[],
int  count 
)

Definition at line 31 of file skia_conversions.cc.

31  {
32  std::vector<Point> result(count);
33  for (auto i = 0; i < count; i++) {
34  result[i] = ToPoint(points[i]);
35  }
36  return result;
37 }

References ToPoint().

Referenced by impeller::DlDispatcher::drawPoints().

◆ ToRect() [1/2]

◆ ToRect() [2/2]

std::optional< Rect > impeller::skia_conversions::ToRect ( const SkRect *  rect)

Definition at line 16 of file skia_conversions.cc.

16  {
17  if (rect == nullptr) {
18  return std::nullopt;
19  }
20  return Rect::MakeLTRB(rect->fLeft, rect->fTop, rect->fRight, rect->fBottom);
21 }

References impeller::TRect< Scalar >::MakeLTRB().

◆ ToRects()

std::vector< Rect > impeller::skia_conversions::ToRects ( const SkRect  tex[],
int  count 
)

Definition at line 23 of file skia_conversions.cc.

23  {
24  auto result = std::vector<Rect>();
25  for (int i = 0; i < count; i++) {
26  result.push_back(ToRect(tex[i]));
27  }
28  return result;
29 }

References ToRect().

Referenced by impeller::DlDispatcher::drawAtlas().

◆ ToRoundingRadii()

PathBuilder::RoundingRadii impeller::skia_conversions::ToRoundingRadii ( const SkRRect &  rrect)

Definition at line 39 of file skia_conversions.cc.

39  {
40  using Corner = SkRRect::Corner;
41  PathBuilder::RoundingRadii radii;
42  radii.bottom_left = ToPoint(rrect.radii(Corner::kLowerLeft_Corner));
43  radii.bottom_right = ToPoint(rrect.radii(Corner::kLowerRight_Corner));
44  radii.top_left = ToPoint(rrect.radii(Corner::kUpperLeft_Corner));
45  radii.top_right = ToPoint(rrect.radii(Corner::kUpperRight_Corner));
46  return radii;
47 }

References impeller::PathBuilder::RoundingRadii::bottom_left, impeller::PathBuilder::RoundingRadii::bottom_right, impeller::PathBuilder::RoundingRadii::top_left, impeller::PathBuilder::RoundingRadii::top_right, and ToPoint().

Referenced by ToPath().

◆ ToRSXForms()

std::vector< Matrix > impeller::skia_conversions::ToRSXForms ( const SkRSXform  xform[],
int  count 
)

Definition at line 151 of file skia_conversions.cc.

151  {
152  auto result = std::vector<Matrix>();
153  for (int i = 0; i < count; i++) {
154  auto form = xform[i];
155  // clang-format off
156  auto matrix = Matrix{
157  form.fSCos, form.fSSin, 0, 0,
158  -form.fSSin, form.fSCos, 0, 0,
159  0, 0, 1, 0,
160  form.fTx, form.fTy, 0, 1
161  };
162  // clang-format on
163  result.push_back(matrix);
164  }
165  return result;
166 }

Referenced by impeller::DlDispatcher::drawAtlas().

impeller::PixelFormat::kB10G10R10XR
@ kB10G10R10XR
impeller::Scalar
float Scalar
Definition: scalar.h:15
impeller::PixelFormat::kR16G16B16A16Float
@ kR16G16B16A16Float
impeller::skia_conversions::ToColor
Color ToColor(const flutter::DlColor &color)
Definition: skia_conversions.cc:142
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::skia_conversions::ToRoundingRadii
PathBuilder::RoundingRadii ToRoundingRadii(const SkRRect &rrect)
Definition: skia_conversions.cc:39
impeller::FillType
FillType
Definition: path.h:29
impeller::PixelFormat::kB8G8R8A8UNormInt
@ kB8G8R8A8UNormInt
impeller::skia_conversions::ToPoint
Point ToPoint(const SkPoint &point)
Definition: skia_conversions.cc:138
impeller::skia_conversions::ToRect
std::optional< Rect > ToRect(const SkRect *rect)
Definition: skia_conversions.cc:16
impeller::skia_conversions::ToPath
Path ToPath(const SkRRect &rrect)
Definition: skia_conversions.cc:130