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