Flutter Impeller
path_builder.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 "path_builder.h"
6 
7 #include <cmath>
8 
10 
11 namespace impeller {
12 
14  AddContourComponent({});
15 }
16 
17 PathBuilder::~PathBuilder() = default;
18 
20  prototype_.fill = fill;
21  return Path(prototype_);
22 }
23 
25  prototype_.fill = fill;
26  UpdateBounds();
27  current_contour_location_ = 0u;
28  return Path(std::move(prototype_));
29 }
30 
31 void PathBuilder::Reserve(size_t point_size, size_t verb_size) {
32  prototype_.points.reserve(point_size);
33  prototype_.components.reserve(verb_size);
34 }
35 
36 PathBuilder& PathBuilder::MoveTo(Point point, bool relative) {
37  current_ = relative ? current_ + point : point;
38  subpath_start_ = current_;
39  AddContourComponent(current_);
40  return *this;
41 }
42 
44  // If the subpath start is the same as the current position, this
45  // is an empty contour and inserting a line segment will just
46  // confuse the tessellator.
47  if (subpath_start_ != current_) {
48  LineTo(subpath_start_);
49  }
50  SetContourClosed(true);
51  AddContourComponent(current_);
52  return *this;
53 }
54 
55 PathBuilder& PathBuilder::LineTo(Point point, bool relative) {
56  point = relative ? current_ + point : point;
57  AddLinearComponent(current_, point);
58  current_ = point;
59  return *this;
60 }
61 
63  Point endpoint =
64  relative ? Point{current_.x + x, current_.y} : Point{x, current_.y};
65  AddLinearComponent(current_, endpoint);
66  current_ = endpoint;
67  return *this;
68 }
69 
71  Point endpoint =
72  relative ? Point{current_.x, current_.y + y} : Point{current_.x, y};
73  AddLinearComponent(current_, endpoint);
74  current_ = endpoint;
75  return *this;
76 }
77 
79  Point point,
80  bool relative) {
81  point = relative ? current_ + point : point;
82  controlPoint = relative ? current_ + controlPoint : controlPoint;
83  AddQuadraticComponent(current_, controlPoint, point);
84  current_ = point;
85  return *this;
86 }
87 
89  prototype_.convexity = value;
90  return *this;
91 }
92 
94  Point controlPoint2,
95  Point point,
96  bool relative) {
97  controlPoint1 = relative ? current_ + controlPoint1 : controlPoint1;
98  controlPoint2 = relative ? current_ + controlPoint2 : controlPoint2;
99  point = relative ? current_ + point : point;
100  AddCubicComponent(current_, controlPoint1, controlPoint2, point);
101  current_ = point;
102  return *this;
103 }
104 
106  MoveTo(p1);
107  AddQuadraticComponent(p1, cp, p2);
108  return *this;
109 }
110 
112  Point cp1,
113  Point cp2,
114  Point p2) {
115  MoveTo(p1);
116  AddCubicComponent(p1, cp1, cp2, p2);
117  return *this;
118 }
119 
121  auto origin = rect.GetOrigin();
122  auto size = rect.GetSize();
123 
124  auto tl = origin;
125  auto bl = origin + Point{0.0, size.height};
126  auto br = origin + size;
127  auto tr = origin + Point{size.width, 0.0};
128 
129  MoveTo(tl);
130  LineTo(tr);
131  LineTo(br);
132  LineTo(bl);
133  Close();
134 
135  return *this;
136 }
137 
139  return AddOval(Rect::MakeXYWH(c.x - r, c.y - r, 2.0f * r, 2.0f * r));
140 }
141 
143  return radius <= 0.0 ? AddRect(rect)
144  : AddRoundedRect(rect, RoundingRadii(radius));
145 }
146 
148  return radii.width <= 0 || radii.height <= 0
149  ? AddRect(rect)
150  : AddRoundedRect(rect, RoundingRadii(radii));
151 }
152 
154  if (radii.AreAllZero()) {
155  return AddRect(rect);
156  }
157 
158  auto rect_origin = rect.GetOrigin();
159  auto rect_size = rect.GetSize();
160 
161  current_ = rect_origin + Point{radii.top_left.x, 0.0};
162 
163  MoveTo({rect_origin.x + radii.top_left.x, rect_origin.y});
164 
165  //----------------------------------------------------------------------------
166  // Top line.
167  //
168  AddLinearComponent(
169  {rect_origin.x + radii.top_left.x, rect_origin.y},
170  {rect_origin.x + rect_size.width - radii.top_right.x, rect_origin.y});
171 
172  //----------------------------------------------------------------------------
173  // Top right arc.
174  //
175  AddRoundedRectTopRight(rect, radii);
176 
177  //----------------------------------------------------------------------------
178  // Right line.
179  //
180  AddLinearComponent(
181  {rect_origin.x + rect_size.width, rect_origin.y + radii.top_right.y},
182  {rect_origin.x + rect_size.width,
183  rect_origin.y + rect_size.height - radii.bottom_right.y});
184 
185  //----------------------------------------------------------------------------
186  // Bottom right arc.
187  //
188  AddRoundedRectBottomRight(rect, radii);
189 
190  //----------------------------------------------------------------------------
191  // Bottom line.
192  //
193  AddLinearComponent(
194  {rect_origin.x + rect_size.width - radii.bottom_right.x,
195  rect_origin.y + rect_size.height},
196  {rect_origin.x + radii.bottom_left.x, rect_origin.y + rect_size.height});
197 
198  //----------------------------------------------------------------------------
199  // Bottom left arc.
200  //
201  AddRoundedRectBottomLeft(rect, radii);
202 
203  //----------------------------------------------------------------------------
204  // Left line.
205  //
206  AddLinearComponent(
207  {rect_origin.x, rect_origin.y + rect_size.height - radii.bottom_left.y},
208  {rect_origin.x, rect_origin.y + radii.top_left.y});
209 
210  //----------------------------------------------------------------------------
211  // Top left arc.
212  //
213  AddRoundedRectTopLeft(rect, radii);
214 
215  Close();
216 
217  return *this;
218 }
219 
220 PathBuilder& PathBuilder::AddRoundedRectTopLeft(Rect rect,
221  RoundingRadii radii) {
222  const auto magic_top_left = radii.top_left * kArcApproximationMagic;
223  const auto corner = rect.GetOrigin();
224  AddCubicComponent({corner.x, corner.y + radii.top_left.y},
225  {corner.x, corner.y + radii.top_left.y - magic_top_left.y},
226  {corner.x + radii.top_left.x - magic_top_left.x, corner.y},
227  {corner.x + radii.top_left.x, corner.y});
228  return *this;
229 }
230 
231 PathBuilder& PathBuilder::AddRoundedRectTopRight(Rect rect,
232  RoundingRadii radii) {
233  const auto magic_top_right = radii.top_right * kArcApproximationMagic;
234  const auto corner = rect.GetOrigin() + Point{rect.GetWidth(), 0};
235  AddCubicComponent(
236  {corner.x - radii.top_right.x, corner.y},
237  {corner.x - radii.top_right.x + magic_top_right.x, corner.y},
238  {corner.x, corner.y + radii.top_right.y - magic_top_right.y},
239  {corner.x, corner.y + radii.top_right.y});
240  return *this;
241 }
242 
243 PathBuilder& PathBuilder::AddRoundedRectBottomRight(Rect rect,
244  RoundingRadii radii) {
245  const auto magic_bottom_right = radii.bottom_right * kArcApproximationMagic;
246  const auto corner = rect.GetOrigin() + rect.GetSize();
247  AddCubicComponent(
248  {corner.x, corner.y - radii.bottom_right.y},
249  {corner.x, corner.y - radii.bottom_right.y + magic_bottom_right.y},
250  {corner.x - radii.bottom_right.x + magic_bottom_right.x, corner.y},
251  {corner.x - radii.bottom_right.x, corner.y});
252  return *this;
253 }
254 
255 PathBuilder& PathBuilder::AddRoundedRectBottomLeft(Rect rect,
256  RoundingRadii radii) {
257  const auto magic_bottom_left = radii.bottom_left * kArcApproximationMagic;
258  const auto corner = rect.GetOrigin() + Point{0, rect.GetHeight()};
259  AddCubicComponent(
260  {corner.x + radii.bottom_left.x, corner.y},
261  {corner.x + radii.bottom_left.x - magic_bottom_left.x, corner.y},
262  {corner.x, corner.y - radii.bottom_left.y + magic_bottom_left.y},
263  {corner.x, corner.y - radii.bottom_left.y});
264  return *this;
265 }
266 
267 void PathBuilder::AddContourComponent(const Point& destination,
268  bool is_closed) {
269  auto& components = prototype_.components;
270  auto& points = prototype_.points;
271  auto closed = is_closed ? Point{0, 0} : Point{1, 1};
272  if (components.size() > 0 &&
273  components.back() == Path::ComponentType::kContour) {
274  // Never insert contiguous contours.
275  points[current_contour_location_] = destination;
276  points[current_contour_location_ + 1] = closed;
277  } else {
278  current_contour_location_ = points.size();
279  points.push_back(destination);
280  points.push_back(closed);
281  components.push_back(Path::ComponentType::kContour);
282  }
283  prototype_.bounds.reset();
284 }
285 
286 void PathBuilder::AddLinearComponent(const Point& p1, const Point& p2) {
287  auto& points = prototype_.points;
288  points.push_back(p1);
289  points.push_back(p2);
290  prototype_.components.push_back(Path::ComponentType::kLinear);
291  prototype_.bounds.reset();
292 }
293 
294 void PathBuilder::AddQuadraticComponent(const Point& p1,
295  const Point& cp,
296  const Point& p2) {
297  auto& points = prototype_.points;
298  points.push_back(p1);
299  points.push_back(cp);
300  points.push_back(p2);
301  prototype_.components.push_back(Path::ComponentType::kQuadratic);
302  prototype_.bounds.reset();
303 }
304 
305 void PathBuilder::AddCubicComponent(const Point& p1,
306  const Point& cp1,
307  const Point& cp2,
308  const Point& p2) {
309  auto& points = prototype_.points;
310  points.push_back(p1);
311  points.push_back(cp1);
312  points.push_back(cp2);
313  points.push_back(p2);
314  prototype_.components.push_back(Path::ComponentType::kCubic);
315  prototype_.bounds.reset();
316 }
317 
318 void PathBuilder::SetContourClosed(bool is_closed) {
319  prototype_.points[current_contour_location_ + 1] =
320  is_closed ? Point{0, 0} : Point{1, 1};
321 }
322 
324  Radians start,
325  Radians sweep,
326  bool use_center) {
327  if (sweep.radians < 0) {
328  start.radians += sweep.radians;
329  sweep.radians *= -1;
330  }
331  sweep.radians = std::min(k2Pi, sweep.radians);
332  start.radians = std::fmod(start.radians, k2Pi);
333 
334  const Point center = oval_bounds.GetCenter();
335  const Point radius = center - oval_bounds.GetOrigin();
336 
337  Vector2 p1_unit(std::cos(start.radians), std::sin(start.radians));
338 
339  if (use_center) {
340  MoveTo(center);
341  LineTo(center + p1_unit * radius);
342  } else {
343  MoveTo(center + p1_unit * radius);
344  }
345 
346  while (sweep.radians > 0) {
347  Vector2 p2_unit;
348  Scalar quadrant_angle;
349  if (sweep.radians < kPiOver2) {
350  quadrant_angle = sweep.radians;
351  p2_unit = Vector2(std::cos(start.radians + quadrant_angle),
352  std::sin(start.radians + quadrant_angle));
353  } else {
354  quadrant_angle = kPiOver2;
355  p2_unit = Vector2(-p1_unit.y, p1_unit.x);
356  }
357 
358  Vector2 arc_cp_lengths =
359  (quadrant_angle / kPiOver2) * kArcApproximationMagic * radius;
360 
361  Point p1 = center + p1_unit * radius;
362  Point p2 = center + p2_unit * radius;
363  Point cp1 = p1 + Vector2(-p1_unit.y, p1_unit.x) * arc_cp_lengths;
364  Point cp2 = p2 + Vector2(p2_unit.y, -p2_unit.x) * arc_cp_lengths;
365 
366  AddCubicComponent(p1, cp1, cp2, p2);
367  current_ = p2;
368 
369  start.radians += quadrant_angle;
370  sweep.radians -= quadrant_angle;
371  p1_unit = p2_unit;
372  }
373 
374  if (use_center) {
375  Close();
376  }
377 
378  return *this;
379 }
380 
382  const Point c = container.GetCenter();
383  const Point r = c - container.GetOrigin();
384  const Point m = r * kArcApproximationMagic;
385 
386  MoveTo({c.x, c.y - r.y});
387 
388  //----------------------------------------------------------------------------
389  // Top right arc.
390  //
391  AddCubicComponent({c.x, c.y - r.y}, // p1
392  {c.x + m.x, c.y - r.y}, // cp1
393  {c.x + r.x, c.y - m.y}, // cp2
394  {c.x + r.x, c.y} // p2
395  );
396 
397  //----------------------------------------------------------------------------
398  // Bottom right arc.
399  //
400  AddCubicComponent({c.x + r.x, c.y}, // p1
401  {c.x + r.x, c.y + m.y}, // cp1
402  {c.x + m.x, c.y + r.y}, // cp2
403  {c.x, c.y + r.y} // p2
404  );
405 
406  //----------------------------------------------------------------------------
407  // Bottom left arc.
408  //
409  AddCubicComponent({c.x, c.y + r.y}, // p1
410  {c.x - m.x, c.y + r.y}, // cp1
411  {c.x - r.x, c.y + m.y}, // cp2
412  {c.x - r.x, c.y} // p2
413  );
414 
415  //----------------------------------------------------------------------------
416  // Top left arc.
417  //
418  AddCubicComponent({c.x - r.x, c.y}, // p1
419  {c.x - r.x, c.y - m.y}, // cp1
420  {c.x - m.x, c.y - r.y}, // cp2
421  {c.x, c.y - r.y} // p2
422  );
423 
424  Close();
425 
426  return *this;
427 }
428 
429 PathBuilder& PathBuilder::AddLine(const Point& p1, const Point& p2) {
430  MoveTo(p1);
431  AddLinearComponent(p1, p2);
432  return *this;
433 }
434 
436  auto& points = prototype_.points;
437  auto& components = prototype_.components;
438 
439  points.insert(points.end(), path.data_->points.begin(),
440  path.data_->points.end());
441  components.insert(components.end(), path.data_->components.begin(),
442  path.data_->components.end());
443 
444  size_t source_offset = points.size();
445  for (auto component : path.data_->components) {
446  if (component == Path::ComponentType::kContour) {
447  current_contour_location_ = source_offset;
448  }
449  source_offset += Path::VerbToOffset(component);
450  }
451  return *this;
452 }
453 
455  auto& points = prototype_.points;
456  size_t storage_offset = 0u;
457  for (const auto& component : prototype_.components) {
458  switch (component) {
460  auto* linear =
461  reinterpret_cast<LinearPathComponent*>(&points[storage_offset]);
462  linear->p1 += offset;
463  linear->p2 += offset;
464  break;
465  }
467  auto* quad =
468  reinterpret_cast<QuadraticPathComponent*>(&points[storage_offset]);
469  quad->p1 += offset;
470  quad->p2 += offset;
471  quad->cp += offset;
472  } break;
474  auto* cubic =
475  reinterpret_cast<CubicPathComponent*>(&points[storage_offset]);
476  cubic->p1 += offset;
477  cubic->p2 += offset;
478  cubic->cp1 += offset;
479  cubic->cp2 += offset;
480  } break;
482  auto* contour =
483  reinterpret_cast<ContourComponent*>(&points[storage_offset]);
484  contour->destination += offset;
485  break;
486  }
487  storage_offset += Path::VerbToOffset(component);
488  }
489 
490  prototype_.bounds.reset();
491  return *this;
492 }
493 
495  prototype_.bounds = bounds;
496  return *this;
497 }
498 
499 void PathBuilder::UpdateBounds() {
500  if (!prototype_.bounds.has_value()) {
501  auto min_max = GetMinMaxCoveragePoints();
502  if (!min_max.has_value()) {
503  prototype_.bounds.reset();
504  return;
505  }
506  auto min = min_max->first;
507  auto max = min_max->second;
508  const auto difference = max - min;
509  prototype_.bounds =
510  Rect::MakeXYWH(min.x, min.y, difference.x, difference.y);
511  }
512 }
513 
514 std::optional<std::pair<Point, Point>> PathBuilder::GetMinMaxCoveragePoints()
515  const {
516  auto& points = prototype_.points;
517 
518  if (points.empty()) {
519  return std::nullopt;
520  }
521 
522  std::optional<Point> min, max;
523 
524  auto clamp = [&min, &max](const Point& point) {
525  if (min.has_value()) {
526  min = min->Min(point);
527  } else {
528  min = point;
529  }
530 
531  if (max.has_value()) {
532  max = max->Max(point);
533  } else {
534  max = point;
535  }
536  };
537 
538  size_t storage_offset = 0u;
539  for (const auto& component : prototype_.components) {
540  switch (component) {
542  auto* linear = reinterpret_cast<const LinearPathComponent*>(
543  &points[storage_offset]);
544  clamp(linear->p1);
545  clamp(linear->p2);
546  break;
547  }
549  for (const auto& extrema :
550  reinterpret_cast<const QuadraticPathComponent*>(
551  &points[storage_offset])
552  ->Extrema()) {
553  clamp(extrema);
554  }
555  break;
557  for (const auto& extrema : reinterpret_cast<const CubicPathComponent*>(
558  &points[storage_offset])
559  ->Extrema()) {
560  clamp(extrema);
561  }
562  break;
564  break;
565  }
566  storage_offset += Path::VerbToOffset(component);
567  }
568 
569  if (!min.has_value() || !max.has_value()) {
570  return std::nullopt;
571  }
572 
573  return std::make_pair(min.value(), max.value());
574 }
575 
576 } // namespace impeller
impeller::PathBuilder::AddQuadraticCurve
PathBuilder & AddQuadraticCurve(Point p1, Point cp, Point p2)
Move to point p1, then insert a quadradic curve from p1 to p2 with the control point cp.
Definition: path_builder.cc:105
impeller::LinearPathComponent
Definition: path_component.h:38
impeller::TPoint::y
Type y
Definition: point.h:31
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::CubicPathComponent::p1
Point p1
Definition: path_component.h:102
impeller::TRect< Scalar >::MakeXYWH
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition: rect.h:136
impeller::Path::ComponentType::kLinear
@ kLinear
impeller::PathBuilder::SetBounds
PathBuilder & SetBounds(Rect bounds)
Set the bounding box that will be used by Path.GetBoundingBox in place of performing the computation.
Definition: path_builder.cc:494
impeller::QuadraticPathComponent::p1
Point p1
Definition: path_component.h:64
impeller::PathBuilder::CubicCurveTo
PathBuilder & CubicCurveTo(Point controlPoint1, Point controlPoint2, Point point, bool relative=false)
Insert a cubic curve from the curren position to point using the control points controlPoint1 and con...
Definition: path_builder.cc:93
impeller::PathBuilder::AddPath
PathBuilder & AddPath(const Path &path)
Definition: path_builder.cc:435
impeller::Path::ComponentType::kCubic
@ kCubic
impeller::PathBuilder
Definition: path_builder.h:14
impeller::Vector2
Point Vector2
Definition: point.h:331
path_builder.h
impeller::Convexity
Convexity
Definition: path.h:35
impeller::Path::ComponentType::kQuadratic
@ kQuadratic
impeller::PathBuilder::RoundingRadii::AreAllZero
bool AreAllZero() const
Definition: path_builder.h:140
impeller::PathBuilder::AddRoundedRect
PathBuilder & AddRoundedRect(Rect rect, RoundingRadii radii)
Definition: path_builder.cc:153
impeller::PathBuilder::HorizontalLineTo
PathBuilder & HorizontalLineTo(Scalar x, bool relative=false)
Definition: path_builder.cc:62
impeller::Radians::radians
Scalar radians
Definition: scalar.h:44
impeller::TRect::GetCenter
constexpr Point GetCenter() const
Get the center point as a |Point|.
Definition: rect.h:376
impeller::PathBuilder::~PathBuilder
~PathBuilder()
impeller::PathBuilder::SetConvexity
PathBuilder & SetConvexity(Convexity value)
Definition: path_builder.cc:88
impeller::PathBuilder::kArcApproximationMagic
constexpr static const Scalar kArcApproximationMagic
Definition: path_builder.h:23
impeller::TRect::GetOrigin
constexpr TPoint< Type > GetOrigin() const
Returns the upper left corner of the rectangle as specified by the left/top or x/y values when it was...
Definition: rect.h:314
offset
SeparatedVector2 offset
Definition: stroke_path_geometry.cc:304
impeller::PathBuilder::AddRect
PathBuilder & AddRect(Rect rect)
Definition: path_builder.cc:120
impeller::PathBuilder::RoundingRadii::bottom_right
Point bottom_right
Definition: path_builder.h:109
impeller::kPiOver2
constexpr float kPiOver2
Definition: constants.h:32
impeller::PathBuilder::RoundingRadii
Definition: path_builder.h:105
impeller::TSize< Scalar >
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
impeller::k2Pi
constexpr float k2Pi
Definition: constants.h:29
impeller::LinearPathComponent::p1
Point p1
Definition: path_component.h:39
impeller::PathBuilder::Shift
PathBuilder & Shift(Point offset)
Transform the existing path segments and contours by the given offset.
Definition: path_builder.cc:454
impeller::PathBuilder::QuadraticCurveTo
PathBuilder & QuadraticCurveTo(Point controlPoint, Point point, bool relative=false)
Insert a quadradic curve from the current position to point using the control point controlPoint.
Definition: path_builder.cc:78
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:52
impeller::PathBuilder::CopyPath
Path CopyPath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:19
impeller::PathBuilder::LineTo
PathBuilder & LineTo(Point point, bool relative=false)
Insert a line from the current position to point.
Definition: path_builder.cc:55
impeller::PathBuilder::AddCubicCurve
PathBuilder & AddCubicCurve(Point p1, Point cp1, Point cp2, Point p2)
Move to point p1, then insert a cubic curve from p1 to p2 with control points cp1 and cp2.
Definition: path_builder.cc:111
impeller::PathBuilder::RoundingRadii::top_left
Point top_left
Definition: path_builder.h:106
impeller::Radians
Definition: scalar.h:43
impeller::FillType
FillType
Definition: path.h:30
impeller::PathBuilder::AddLine
PathBuilder & AddLine(const Point &p1, const Point &p2)
Move to point p1, then insert a line from p1 to p2.
Definition: path_builder.cc:429
impeller::PathBuilder::TakePath
Path TakePath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:24
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:776
impeller::TSize::width
Type width
Definition: size.h:22
impeller::ContourComponent::destination
Point destination
Definition: path_component.h:151
impeller::TPoint::x
Type x
Definition: point.h:30
impeller::PathBuilder::PathBuilder
PathBuilder()
Definition: path_builder.cc:13
impeller::CubicPathComponent
Definition: path_component.h:100
impeller::PathBuilder::Reserve
void Reserve(size_t point_size, size_t verb_size)
Reserve [point_size] points and [verb_size] verbs in the underlying path buffer.
Definition: path_builder.cc:31
impeller::TRect::GetSize
constexpr TSize< Type > GetSize() const
Returns the size of the rectangle which may be negative in either width or height and may have been c...
Definition: rect.h:321
impeller::PathBuilder::Close
PathBuilder & Close()
Definition: path_builder.cc:43
impeller::PathBuilder::RoundingRadii::top_right
Point top_right
Definition: path_builder.h:108
impeller::TPoint< Scalar >
impeller::PathBuilder::MoveTo
PathBuilder & MoveTo(Point point, bool relative=false)
Definition: path_builder.cc:36
impeller::PathBuilder::RoundingRadii::bottom_left
Point bottom_left
Definition: path_builder.h:107
impeller::PathBuilder::VerticalLineTo
PathBuilder & VerticalLineTo(Scalar y, bool relative=false)
Definition: path_builder.cc:70
impeller::Path::VerbToOffset
static constexpr size_t VerbToOffset(Path::ComponentType verb)
Definition: path.h:61
impeller::PathBuilder::AddCircle
PathBuilder & AddCircle(const Point &center, Scalar radius)
Definition: path_builder.cc:138
impeller::TSize::height
Type height
Definition: size.h:23
impeller::PathBuilder::AddOval
PathBuilder & AddOval(const Rect &rect)
Definition: path_builder.cc:381
path_component.h
impeller::ContourComponent
Definition: path_component.h:150
impeller::PathBuilder::AddRoundedRect
PathBuilder & AddRoundedRect(Rect rect, Size radii)
Definition: path_builder.cc:147
impeller
Definition: allocation.cc:12
impeller::QuadraticPathComponent
Definition: path_component.h:62
impeller::Path::ComponentType::kContour
@ kContour
impeller::TRect< Scalar >
impeller::PathBuilder::AddArc
PathBuilder & AddArc(const Rect &oval_bounds, Radians start, Radians sweep, bool use_center=false)
Definition: path_builder.cc:323