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