13 static constexpr
int kPrecomputedDivisionCount = 1024;
15 static int kPrecomputedDivisions[kPrecomputedDivisionCount] = {
17 1, 2, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7,
18 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10,
19 10, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 13,
20 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14,
21 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16,
22 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18,
23 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19,
24 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
25 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
26 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23,
27 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24,
28 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25,
29 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26,
30 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27,
31 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28,
32 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29,
33 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
34 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
35 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
36 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
37 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33,
38 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
39 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
40 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35,
41 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36,
42 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
43 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
44 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38,
45 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
46 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
47 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40,
48 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
49 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41,
50 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
51 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
52 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43,
53 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
54 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 44,
55 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
56 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
57 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
58 45, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
59 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47,
60 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
61 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48,
62 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
63 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49,
64 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
65 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50,
66 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
67 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51,
68 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
69 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 52, 52,
70 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
71 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53,
72 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
73 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54,
74 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
75 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
76 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
77 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
78 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
79 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
80 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57,
85 if (pixel_radius <= 0.0) {
88 int radius_index = ceil(pixel_radius);
89 if (radius_index < kPrecomputedDivisionCount) {
90 return kPrecomputedDivisions[radius_index];
145 uint16_t* index_buffer)
146 : point_buffer_(point_buffer), index_buffer_(index_buffer) {}
148 ~FanPathVertexWriter() =
default;
150 size_t GetIndexCount()
const {
return index_count_; }
151 size_t GetPointCount()
const {
return count_; }
157 index_buffer_[index_count_++] = 0xFFFF;
161 index_buffer_[index_count_++] = count_;
162 point_buffer_[count_++] = point;
167 size_t index_count_ = 0;
169 uint16_t* index_buffer_ =
nullptr;
177 uint16_t* index_buffer)
178 : point_buffer_(point_buffer), index_buffer_(index_buffer) {}
180 ~StripPathVertexWriter() =
default;
182 size_t GetIndexCount()
const {
return index_count_; }
183 size_t GetPointCount()
const {
return count_; }
186 if (count_ == 0u || contour_start_ == count_ - 1) {
191 size_t start = contour_start_;
192 size_t end = count_ - 1;
194 index_buffer_[index_count_++] =
start;
196 size_t a =
start + 1;
199 index_buffer_[index_count_++] = a;
200 index_buffer_[index_count_++] =
b;
205 index_buffer_[index_count_++] = a;
208 contour_start_ = count_;
209 index_buffer_[index_count_++] = 0xFFFF;
213 point_buffer_[count_++] = point;
218 size_t index_count_ = 0;
219 size_t contour_start_ = 0;
221 uint16_t* index_buffer_ =
nullptr;
227 explicit GLESPathVertexWriter(std::vector<impeller::Point>&
points,
228 std::vector<uint16_t>& indices)
229 : points_(
points), indices_(indices) {}
231 ~GLESPathVertexWriter() =
default;
234 if (points_.size() == 0u || contour_start_ == points_.size() - 1) {
239 auto start = contour_start_;
240 auto end = points_.size() - 1;
245 if (points_[
end] == points_[
start]) {
250 if (contour_start_ != 0) {
251 auto back = indices_.back();
252 indices_.push_back(back);
253 indices_.push_back(
start);
254 indices_.push_back(
start);
259 if (previous_contour_odd_points_) {
260 indices_.push_back(
start);
263 indices_.push_back(
start);
266 size_t a =
start + 1;
269 indices_.push_back(a);
270 indices_.push_back(
b);
275 indices_.push_back(a);
276 previous_contour_odd_points_ =
false;
278 previous_contour_odd_points_ =
true;
280 contour_start_ = points_.size();
286 bool previous_contour_odd_points_ =
false;
287 size_t contour_start_ = 0u;
288 std::vector<impeller::Point>& points_;
289 std::vector<uint16_t>& indices_;
297 : point_buffer_(
std::make_unique<
std::vector<
Point>>()),
298 index_buffer_(
std::make_unique<
std::vector<uint16_t>>()),
311 return GetTrigsForDivisions(ComputeQuadrantDivisions(pixel_radius));
317 bool supports_primitive_restart,
318 bool supports_triangle_fan) {
319 if (supports_primitive_restart) {
321 const auto [point_count, contour_count] =
324 nullptr,
sizeof(
Point) * point_count,
alignof(
Point));
326 nullptr,
sizeof(uint16_t) * (point_count + contour_count),
329 if (supports_triangle_fan) {
330 FanPathVertexWriter writer(
333 reinterpret_cast<uint16_t*
>(
337 FML_DCHECK(writer.GetPointCount() <= point_count);
338 FML_DCHECK(writer.GetIndexCount() <= (point_count + contour_count));
344 .index_buffer = std::move(index_buffer),
345 .vertex_count = writer.GetIndexCount(),
349 StripPathVertexWriter writer(
352 reinterpret_cast<uint16_t*
>(
356 FML_DCHECK(writer.GetPointCount() <= point_count);
357 FML_DCHECK(writer.GetIndexCount() <= (point_count + contour_count));
363 .index_buffer = std::move(index_buffer),
364 .vertex_count = writer.GetIndexCount(),
393 .index_buffer = std::move(index_buffer),
400 std::vector<Point>& point_buffer,
401 std::vector<uint16_t>& index_buffer,
403 point_buffer.clear();
404 index_buffer.clear();
406 GLESPathVertexWriter writer(point_buffer, index_buffer);
414 void Tessellator::Trigs::init(
size_t divisions) {
415 if (!trigs_.empty()) {
420 trigs_.reserve(divisions + 1);
422 double angle_scale =
kPiOver2 / divisions;
424 trigs_.emplace_back(1.0, 0.0);
425 for (
size_t i = 1; i < divisions; i++) {
426 trigs_.emplace_back(
Radians(i * angle_scale));
428 trigs_.emplace_back(0.0, 1.0);
431 Tessellator::Trigs Tessellator::GetTrigsForDivisions(
size_t divisions) {
432 return divisions < Tessellator::kCachedTrigCount
433 ? Trigs(precomputed_trigs_[divisions], divisions)
441 EllipticalVertexGenerator::EllipticalVertexGenerator(
442 EllipticalVertexGenerator::GeneratorProc& generator,
445 size_t vertices_per_trig,
448 trigs_(
std::move(trigs)),
450 vertices_per_trig_(vertices_per_trig) {}
453 const Matrix& view_transform,
459 GetTrigsForDivisions(divisions),
460 PrimitiveType::kTriangleStrip, 4,
462 .reference_centers = {center, center},
463 .radii = {radius, radius},
469 const Matrix& view_transform,
473 if (half_width > 0) {
474 auto divisions = ComputeQuadrantDivisions(
477 GetTrigsForDivisions(divisions),
478 PrimitiveType::kTriangleStrip, 8,
480 .reference_centers = {center, center},
481 .radii = {radius, radius},
482 .half_width = half_width,
485 return FilledCircle(view_transform, center, radius);
491 const Rect& oval_bounds,
493 bool supports_triangle_fans)
494 : iteration_(iteration),
495 trigs_(
std::move(trigs)),
496 oval_bounds_(oval_bounds),
500 supports_triangle_fans_(supports_triangle_fans) {}
502 ArcVertexGenerator::ArcVertexGenerator(
const Arc::Iteration& iteration,
504 const Rect& oval_bounds,
507 : iteration_(iteration),
508 trigs_(
std::move(trigs)),
509 oval_bounds_(oval_bounds),
511 half_width_(half_width),
513 supports_triangle_fans_(false) {}
516 return (half_width_ < 0 && supports_triangle_fans_)
523 if (half_width_ > 0) {
524 FML_DCHECK(!use_center_);
530 }
else if (supports_triangle_fans_) {
536 count += (count + 1) / 2;
543 if (half_width_ > 0) {
544 FML_DCHECK(!use_center_);
545 Tessellator::GenerateStrokedArc(trigs_, iteration_, oval_bounds_,
546 half_width_, cap_, proc);
547 }
else if (supports_triangle_fans_) {
548 Tessellator::GenerateFilledArcFan(trigs_, iteration_, oval_bounds_,
551 Tessellator::GenerateFilledArcStrip(trigs_, iteration_, oval_bounds_,
558 bool supports_triangle_fans) {
559 size_t divisions = ComputeQuadrantDivisions(
571 FML_DCHECK(half_width > 0);
579 GetTrigsForDivisions(divisions),
584 const Matrix& view_transform,
588 auto along = p1 - p0;
594 GetTrigsForDivisions(divisions),
597 .reference_centers = {p0, p1},
598 .radii = {radius, radius},
607 const Matrix& view_transform,
608 const Rect& bounds) {
613 auto max_radius = bounds.
GetSize().MaxDimension();
614 auto divisions = ComputeQuadrantDivisions(
618 GetTrigsForDivisions(divisions),
621 .reference_centers = {center, center},
622 .radii = bounds.
GetSize() * 0.5f,
628 const Matrix& view_transform,
634 auto divisions = ComputeQuadrantDivisions(
636 auto upper_left = bounds.
GetLeftTop() + radii;
639 GetTrigsForDivisions(divisions),
655 void Tessellator::GenerateFilledCircle(
657 const EllipticalVertexGenerator::Data&
data,
659 auto center =
data.reference_centers[0];
660 auto radius =
data.radii.width;
662 FML_DCHECK(center ==
data.reference_centers[1]);
663 FML_DCHECK(radius ==
data.radii.height);
664 FML_DCHECK(
data.half_width < 0);
667 for (
auto& trig : trigs) {
668 auto offset = trig * radius;
669 proc({center.x - offset.x, center.y + offset.y});
670 proc({center.x - offset.x, center.y - offset.y});
678 for (
auto& trig : trigs) {
679 auto offset = trig * radius;
680 proc({center.x + offset.y, center.y + offset.x});
681 proc({center.x + offset.y, center.y - offset.x});
685 void Tessellator::GenerateStrokedCircle(
687 const EllipticalVertexGenerator::Data&
data,
689 auto center =
data.reference_centers[0];
691 FML_DCHECK(center ==
data.reference_centers[1]);
692 FML_DCHECK(
data.radii.IsSquare());
693 FML_DCHECK(
data.half_width > 0 &&
data.half_width <
data.radii.width);
695 auto outer_radius =
data.radii.width +
data.half_width;
696 auto inner_radius =
data.radii.width -
data.half_width;
704 for (
auto& trig : trigs) {
705 auto outer = trig * outer_radius;
706 auto inner = trig * inner_radius;
707 proc({center.x - outer.x, center.y - outer.y});
708 proc({center.x - inner.x, center.y - inner.y});
716 for (
auto& trig : trigs) {
717 auto outer = trig * outer_radius;
718 auto inner = trig * inner_radius;
719 proc({center.x + outer.y, center.y - outer.x});
720 proc({center.x + inner.y, center.y - inner.x});
724 for (
auto& trig : trigs) {
725 auto outer = trig * outer_radius;
726 auto inner = trig * inner_radius;
727 proc({center.x + outer.x, center.y + outer.y});
728 proc({center.x + inner.x, center.y + inner.y});
732 for (
auto& trig : trigs) {
733 auto outer = trig * outer_radius;
734 auto inner = trig * inner_radius;
735 proc({center.x - outer.y, center.y + outer.x});
736 proc({center.x - inner.y, center.y + inner.x});
740 void Tessellator::GenerateFilledArcFan(
const Trigs& trigs,
741 const Arc::Iteration& iteration,
742 const Rect& oval_bounds,
745 Point center = oval_bounds.GetCenter();
746 Size radii = oval_bounds.GetSize() * 0.5f;
751 proc(center + iteration.start * radii);
752 for (
size_t i = 0; i < iteration.quadrant_count; i++) {
753 auto quadrant = iteration.quadrants[i];
754 for (
size_t j = quadrant.start_index; j < quadrant.end_index; j++) {
755 proc(center + trigs[j] * quadrant.axis * radii);
758 proc(center + iteration.end * radii);
761 void Tessellator::GenerateFilledArcStrip(
const Trigs& trigs,
762 const Arc::Iteration& iteration,
763 const Rect& oval_bounds,
766 Point center = oval_bounds.GetCenter();
767 Size radii = oval_bounds.GetSize() * 0.5f;
773 Point midpoint = (iteration.start + iteration.end) * 0.5f;
774 origin = center + midpoint * radii;
778 proc(center + iteration.start * radii);
779 bool insert_origin =
false;
780 for (
size_t i = 0; i < iteration.quadrant_count; i++) {
781 auto quadrant = iteration.quadrants[i];
782 for (
size_t j = quadrant.start_index; j < quadrant.end_index; j++) {
786 insert_origin = !insert_origin;
787 proc(center + trigs[j] * quadrant.axis * radii);
793 proc(center + iteration.end * radii);
796 void Tessellator::GenerateStrokedArc(
const Trigs& trigs,
797 const Arc::Iteration& iteration,
798 const Rect& oval_bounds,
802 Point center = oval_bounds.GetCenter();
803 Size base_radii = oval_bounds.GetSize() * 0.5f;
804 Size inner_radii = base_radii -
Size(half_width, half_width);
805 Size outer_radii = base_radii +
Size(half_width, half_width);
810 Vector2{iteration.start.
y, -iteration.start.x} * half_width;
811 proc(center + iteration.start * inner_radii + offset);
812 proc(center + iteration.start * outer_radii + offset);
814 proc(center + iteration.start * inner_radii);
815 proc(center + iteration.start * outer_radii);
816 for (
size_t i = 0; i < iteration.quadrant_count; i++) {
817 auto quadrant = iteration.quadrants[i];
818 for (
size_t j = quadrant.start_index; j < quadrant.end_index; j++) {
819 proc(center + trigs[j] * quadrant.axis * inner_radii);
820 proc(center + trigs[j] * quadrant.axis * outer_radii);
823 proc(center + iteration.end * inner_radii);
824 proc(center + iteration.end * outer_radii);
826 Vector2 offset =
Vector2{-iteration.end.
y, iteration.end.x} * half_width;
827 proc(center + iteration.end * inner_radii + offset);
828 proc(center + iteration.end * outer_radii + offset);
832 void Tessellator::GenerateRoundCapLine(
834 const EllipticalVertexGenerator::Data&
data,
836 auto p0 =
data.reference_centers[0];
837 auto p1 =
data.reference_centers[1];
838 auto radius =
data.radii.width;
840 FML_DCHECK(radius ==
data.radii.height);
841 FML_DCHECK(
data.half_width < 0);
843 auto along = p1 - p0;
844 along *= radius / along.GetLength();
845 auto across =
Point(-along.y, along.x);
847 for (
auto& trig : trigs) {
848 auto relative_along = along * trig.cos;
849 auto relative_across = across * trig.sin;
850 proc(p0 - relative_along + relative_across);
851 proc(p0 - relative_along - relative_across);
857 for (
auto& trig : trigs) {
858 auto relative_along = along * trig.sin;
859 auto relative_across = across * trig.cos;
860 proc(p1 + relative_along + relative_across);
861 proc(p1 + relative_along - relative_across);
865 void Tessellator::GenerateFilledEllipse(
867 const EllipticalVertexGenerator::Data&
data,
869 auto center =
data.reference_centers[0];
870 auto radii =
data.radii;
872 FML_DCHECK(center ==
data.reference_centers[1]);
873 FML_DCHECK(
data.half_width < 0);
876 for (
auto& trig : trigs) {
877 auto offset = trig * radii;
878 proc({center.x - offset.x, center.y + offset.y});
879 proc({center.x - offset.x, center.y - offset.y});
887 for (
auto& trig : trigs) {
888 auto offset =
Point(trig.sin * radii.width, trig.cos * radii.height);
889 proc({center.x + offset.x, center.y + offset.y});
890 proc({center.x + offset.x, center.y - offset.y});
894 void Tessellator::GenerateFilledRoundRect(
896 const EllipticalVertexGenerator::Data&
data,
902 auto radii =
data.radii;
904 FML_DCHECK(
data.half_width < 0);
907 for (
auto& trig : trigs) {
908 auto offset = trig * radii;
909 proc({left - offset.x, bottom + offset.y});
910 proc({left - offset.x, top - offset.y});
918 for (
auto& trig : trigs) {
919 auto offset =
Point(trig.sin * radii.width, trig.cos * radii.height);
920 proc({right + offset.x, bottom + offset.y});
921 proc({right + offset.x, top - offset.y});
virtual void Flush(std::optional< Range > range=std::nullopt) const
virtual uint8_t * OnGetContents() const =0
BufferView Emplace(const BufferType &buffer, size_t alignment=0)
Emplace non-uniform data (like contiguous vertices) onto the host buffer.
An interface for generating a multi contour polyline as a triangle strip.
virtual void EndContour()=0
virtual void Write(Point point)=0
static void PathToFilledVertices(const PathSource &source, VertexWriter &writer, Scalar scale)
static std::pair< size_t, size_t > CountFillStorage(const PathSource &source, Scalar scale)
The |VertexGenerator| implementation common to all shapes that are based on a polygonal representatio...
size_t GetVertexCount() const override
|VertexGenerator|
PrimitiveType GetTriangleType() const override
|VertexGenerator|
void GenerateVertices(const TessellatedVertexProc &proc) const override
|VertexGenerator|
The |VertexGenerator| implementation common to all shapes that are based on a polygonal representatio...
Trigs(Scalar pixel_radius)
A utility that generates triangles of the specified fill type given a polyline. This happens on the C...
Trigs GetTrigsForDeviceRadius(Scalar pixel_radius)
std::vector< Point > stroke_points_
Used for stroke path generation.
EllipticalVertexGenerator RoundCapLine(const Matrix &view_transform, const Point &p0, const Point &p1, Scalar radius)
Create a |VertexGenerator| that can produce vertices for a line with round end caps of the given radi...
std::vector< Point > & GetStrokePointCache()
Retrieve a pre-allocated arena of kPointArenaSize points.
EllipticalVertexGenerator FilledRoundRect(const Matrix &view_transform, const Rect &bounds, const Size &radii)
Create a |VertexGenerator| that can produce vertices for a filled round rect within the given bounds ...
VertexBuffer TessellateConvex(const PathSource &path, HostBuffer &host_buffer, Scalar tolerance, bool supports_primitive_restart=false, bool supports_triangle_fan=false)
Given a convex path, create a triangle fan structure.
static constexpr Scalar kCircleTolerance
The pixel tolerance used by the algorighm to determine how many divisions to create for a circle.
EllipticalVertexGenerator FilledCircle(const Matrix &view_transform, const Point ¢er, Scalar radius)
Create a |VertexGenerator| that can produce vertices for a filled circle of the given radius around t...
ArcVertexGenerator StrokedArc(const Matrix &view_transform, const Arc &arc, Cap cap, Scalar half_width)
Create a |VertexGenerator| that can produce vertices for a stroked arc inscribed within the given ova...
static void TessellateConvexInternal(const PathSource &path, std::vector< Point > &point_buffer, std::vector< uint16_t > &index_buffer, Scalar tolerance)
std::unique_ptr< std::vector< Point > > point_buffer_
Used for polyline generation.
std::unique_ptr< std::vector< uint16_t > > index_buffer_
EllipticalVertexGenerator FilledEllipse(const Matrix &view_transform, const Rect &bounds)
Create a |VertexGenerator| that can produce vertices for a filled ellipse inscribed within the given ...
std::function< void(const Point &p)> TessellatedVertexProc
A callback function for a |VertexGenerator| to deliver the vertices it computes as |Point| objects.
ArcVertexGenerator FilledArc(const Matrix &view_transform, const Arc &arc, bool supports_triangle_fans)
Create a |VertexGenerator| that can produce vertices for a stroked arc inscribed within the given ova...
Tessellator::TessellatedVertexProc TessellatedVertexProc
PrimitiveType
Decides how backend draws pixels based on input vertices.
constexpr float kEhCloseEnough
Cap
An enum that describes ways to decorate the end of a path contour.
Tessellator::EllipticalVertexGenerator EllipticalVertexGenerator
Tessellator::ArcVertexGenerator ArcVertexGenerator
static constexpr size_t kPointArenaSize
The size of the point arena buffer stored on the tessellator.
size_t GetPointCount() const
Iteration ComputeIterations(size_t step_count, bool simplify_360=true) const
constexpr bool IncludeCenter() const
const Size GetOvalSize() const
Returns the size of the oval bounds.
constexpr bool IsPerfectCircle() const
const Rect & GetOvalBounds() const
Return the bounds of the oval in which this arc is inscribed.
const DeviceBuffer * GetBuffer() const
A 4x4 matrix using column-major storage.
Scalar GetMaxBasisLengthXY() const
constexpr Type GetLength() const
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
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...
constexpr bool IsSquare() const
Returns true if width and height are equal and neither is NaN.
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
constexpr TPoint< T > GetRightBottom() const
constexpr Point GetCenter() const
Get the center point as a |Point|.
constexpr TPoint< T > GetLeftTop() const
constexpr Type MaxDimension() const
std::vector< Point > points
std::shared_ptr< const fml::Mapping > data