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));
318 bool supports_primitive_restart,
319 bool supports_triangle_fan) {
320 if (supports_primitive_restart) {
322 const auto [point_count, contour_count] =
325 nullptr,
sizeof(
Point) * point_count,
alignof(
Point));
327 nullptr,
sizeof(uint16_t) * (point_count + contour_count),
330 if (supports_triangle_fan) {
331 FanPathVertexWriter writer(
334 reinterpret_cast<uint16_t*
>(
338 FML_DCHECK(writer.GetPointCount() <= point_count);
339 FML_DCHECK(writer.GetIndexCount() <= (point_count + contour_count));
345 .index_buffer = std::move(index_buffer),
346 .vertex_count = writer.GetIndexCount(),
350 StripPathVertexWriter writer(
353 reinterpret_cast<uint16_t*
>(
357 FML_DCHECK(writer.GetPointCount() <= point_count);
358 FML_DCHECK(writer.GetIndexCount() <= (point_count + contour_count));
364 .index_buffer = std::move(index_buffer),
365 .vertex_count = writer.GetIndexCount(),
394 .index_buffer = std::move(index_buffer),
401 std::vector<Point>& point_buffer,
402 std::vector<uint16_t>& index_buffer,
404 point_buffer.clear();
405 index_buffer.clear();
407 GLESPathVertexWriter writer(point_buffer, index_buffer);
415 void Tessellator::Trigs::init(
size_t divisions) {
416 if (!trigs_.empty()) {
421 trigs_.reserve(divisions + 1);
423 double angle_scale =
kPiOver2 / divisions;
425 trigs_.emplace_back(1.0, 0.0);
426 for (
size_t i = 1; i < divisions; i++) {
427 trigs_.emplace_back(
Radians(i * angle_scale));
429 trigs_.emplace_back(0.0, 1.0);
432 Tessellator::Trigs Tessellator::GetTrigsForDivisions(
size_t divisions) {
433 return divisions < Tessellator::kCachedTrigCount
434 ? Trigs(precomputed_trigs_[divisions], divisions)
442 EllipticalVertexGenerator::EllipticalVertexGenerator(
443 EllipticalVertexGenerator::GeneratorProc& generator,
446 size_t vertices_per_trig,
449 trigs_(
std::move(trigs)),
451 vertices_per_trig_(vertices_per_trig) {}
454 const Matrix& view_transform,
460 GetTrigsForDivisions(divisions),
461 PrimitiveType::kTriangleStrip, 4,
463 .reference_centers = {center, center},
464 .radii = {radius, radius},
470 const Matrix& view_transform,
474 if (half_width > 0) {
475 auto divisions = ComputeQuadrantDivisions(
478 GetTrigsForDivisions(divisions),
479 PrimitiveType::kTriangleStrip, 8,
481 .reference_centers = {center, center},
482 .radii = {radius, radius},
483 .half_width = half_width,
486 return FilledCircle(view_transform, center, radius);
492 const Rect& oval_bounds,
494 bool supports_triangle_fans)
495 : iteration_(iteration),
496 trigs_(
std::move(trigs)),
497 oval_bounds_(oval_bounds),
501 supports_triangle_fans_(supports_triangle_fans) {}
503 ArcVertexGenerator::ArcVertexGenerator(
const Arc::Iteration& iteration,
505 const Rect& oval_bounds,
508 : iteration_(iteration),
509 trigs_(
std::move(trigs)),
510 oval_bounds_(oval_bounds),
512 half_width_(half_width),
514 supports_triangle_fans_(false) {}
517 return (half_width_ < 0 && supports_triangle_fans_)
524 if (half_width_ > 0) {
525 FML_DCHECK(!use_center_);
531 }
else if (supports_triangle_fans_) {
537 count += (count + 1) / 2;
544 if (half_width_ > 0) {
545 FML_DCHECK(!use_center_);
546 Tessellator::GenerateStrokedArc(trigs_, iteration_, oval_bounds_,
547 half_width_, cap_, proc);
548 }
else if (supports_triangle_fans_) {
549 Tessellator::GenerateFilledArcFan(trigs_, iteration_, oval_bounds_,
552 Tessellator::GenerateFilledArcStrip(trigs_, iteration_, oval_bounds_,
559 bool supports_triangle_fans) {
560 size_t divisions = ComputeQuadrantDivisions(
572 FML_DCHECK(half_width > 0);
580 GetTrigsForDivisions(divisions),
585 const Matrix& view_transform,
589 auto along = p1 - p0;
595 GetTrigsForDivisions(divisions),
598 .reference_centers = {p0, p1},
599 .radii = {radius, radius},
608 const Matrix& view_transform,
609 const Rect& bounds) {
614 auto max_radius = bounds.
GetSize().MaxDimension();
615 auto divisions = ComputeQuadrantDivisions(
619 GetTrigsForDivisions(divisions),
622 .reference_centers = {center, center},
623 .radii = bounds.
GetSize() * 0.5f,
629 const Matrix& view_transform,
635 auto divisions = ComputeQuadrantDivisions(
637 auto upper_left = bounds.
GetLeftTop() + radii;
640 GetTrigsForDivisions(divisions),
656 void Tessellator::GenerateFilledCircle(
658 const EllipticalVertexGenerator::Data&
data,
660 auto center =
data.reference_centers[0];
661 auto radius =
data.radii.width;
663 FML_DCHECK(center ==
data.reference_centers[1]);
664 FML_DCHECK(radius ==
data.radii.height);
665 FML_DCHECK(
data.half_width < 0);
668 for (
auto& trig : trigs) {
669 auto offset = trig * radius;
670 proc({center.x - offset.x, center.y + offset.y});
671 proc({center.x - offset.x, center.y - offset.y});
679 for (
auto& trig : trigs) {
680 auto offset = trig * radius;
681 proc({center.x + offset.y, center.y + offset.x});
682 proc({center.x + offset.y, center.y - offset.x});
686 void Tessellator::GenerateStrokedCircle(
688 const EllipticalVertexGenerator::Data&
data,
690 auto center =
data.reference_centers[0];
692 FML_DCHECK(center ==
data.reference_centers[1]);
693 FML_DCHECK(
data.radii.IsSquare());
694 FML_DCHECK(
data.half_width > 0 &&
data.half_width <
data.radii.width);
696 auto outer_radius =
data.radii.width +
data.half_width;
697 auto inner_radius =
data.radii.width -
data.half_width;
705 for (
auto& trig : trigs) {
706 auto outer = trig * outer_radius;
707 auto inner = trig * inner_radius;
708 proc({center.x - outer.x, center.y - outer.y});
709 proc({center.x - inner.x, center.y - inner.y});
717 for (
auto& trig : trigs) {
718 auto outer = trig * outer_radius;
719 auto inner = trig * inner_radius;
720 proc({center.x + outer.y, center.y - outer.x});
721 proc({center.x + inner.y, center.y - inner.x});
725 for (
auto& trig : trigs) {
726 auto outer = trig * outer_radius;
727 auto inner = trig * inner_radius;
728 proc({center.x + outer.x, center.y + outer.y});
729 proc({center.x + inner.x, center.y + inner.y});
733 for (
auto& trig : trigs) {
734 auto outer = trig * outer_radius;
735 auto inner = trig * inner_radius;
736 proc({center.x - outer.y, center.y + outer.x});
737 proc({center.x - inner.y, center.y + inner.x});
741 void Tessellator::GenerateFilledArcFan(
const Trigs& trigs,
742 const Arc::Iteration& iteration,
743 const Rect& oval_bounds,
746 Point center = oval_bounds.GetCenter();
747 Size radii = oval_bounds.GetSize() * 0.5f;
752 proc(center + iteration.start * radii);
753 for (
size_t i = 0; i < iteration.quadrant_count; i++) {
754 auto quadrant = iteration.quadrants[i];
755 for (
size_t j = quadrant.start_index; j < quadrant.end_index; j++) {
756 proc(center + trigs[j] * quadrant.axis * radii);
759 proc(center + iteration.end * radii);
762 void Tessellator::GenerateFilledArcStrip(
const Trigs& trigs,
763 const Arc::Iteration& iteration,
764 const Rect& oval_bounds,
767 Point center = oval_bounds.GetCenter();
768 Size radii = oval_bounds.GetSize() * 0.5f;
774 Point midpoint = (iteration.start + iteration.end) * 0.5f;
775 origin = center + midpoint * radii;
779 proc(center + iteration.start * radii);
780 bool insert_origin =
false;
781 for (
size_t i = 0; i < iteration.quadrant_count; i++) {
782 auto quadrant = iteration.quadrants[i];
783 for (
size_t j = quadrant.start_index; j < quadrant.end_index; j++) {
787 insert_origin = !insert_origin;
788 proc(center + trigs[j] * quadrant.axis * radii);
794 proc(center + iteration.end * radii);
797 void Tessellator::GenerateStrokedArc(
const Trigs& trigs,
798 const Arc::Iteration& iteration,
799 const Rect& oval_bounds,
803 Point center = oval_bounds.GetCenter();
804 Size base_radii = oval_bounds.GetSize() * 0.5f;
805 Size inner_radii = base_radii -
Size(half_width, half_width);
806 Size outer_radii = base_radii +
Size(half_width, half_width);
811 Vector2{iteration.start.
y, -iteration.start.x} * half_width;
812 proc(center + iteration.start * inner_radii + offset);
813 proc(center + iteration.start * outer_radii + offset);
815 proc(center + iteration.start * inner_radii);
816 proc(center + iteration.start * outer_radii);
817 for (
size_t i = 0; i < iteration.quadrant_count; i++) {
818 auto quadrant = iteration.quadrants[i];
819 for (
size_t j = quadrant.start_index; j < quadrant.end_index; j++) {
820 proc(center + trigs[j] * quadrant.axis * inner_radii);
821 proc(center + trigs[j] * quadrant.axis * outer_radii);
824 proc(center + iteration.end * inner_radii);
825 proc(center + iteration.end * outer_radii);
827 Vector2 offset =
Vector2{-iteration.end.
y, iteration.end.x} * half_width;
828 proc(center + iteration.end * inner_radii + offset);
829 proc(center + iteration.end * outer_radii + offset);
833 void Tessellator::GenerateRoundCapLine(
835 const EllipticalVertexGenerator::Data&
data,
837 auto p0 =
data.reference_centers[0];
838 auto p1 =
data.reference_centers[1];
839 auto radius =
data.radii.width;
841 FML_DCHECK(radius ==
data.radii.height);
842 FML_DCHECK(
data.half_width < 0);
844 auto along = p1 - p0;
845 along *= radius / along.GetLength();
846 auto across =
Point(-along.y, along.x);
848 for (
auto& trig : trigs) {
849 auto relative_along = along * trig.cos;
850 auto relative_across = across * trig.sin;
851 proc(p0 - relative_along + relative_across);
852 proc(p0 - relative_along - relative_across);
858 for (
auto& trig : trigs) {
859 auto relative_along = along * trig.sin;
860 auto relative_across = across * trig.cos;
861 proc(p1 + relative_along + relative_across);
862 proc(p1 + relative_along - relative_across);
866 void Tessellator::GenerateFilledEllipse(
868 const EllipticalVertexGenerator::Data&
data,
870 auto center =
data.reference_centers[0];
871 auto radii =
data.radii;
873 FML_DCHECK(center ==
data.reference_centers[1]);
874 FML_DCHECK(
data.half_width < 0);
877 for (
auto& trig : trigs) {
878 auto offset = trig * radii;
879 proc({center.x - offset.x, center.y + offset.y});
880 proc({center.x - offset.x, center.y - offset.y});
888 for (
auto& trig : trigs) {
889 auto offset =
Point(trig.sin * radii.width, trig.cos * radii.height);
890 proc({center.x + offset.x, center.y + offset.y});
891 proc({center.x + offset.x, center.y - offset.y});
895 void Tessellator::GenerateFilledRoundRect(
897 const EllipticalVertexGenerator::Data&
data,
903 auto radii =
data.radii;
905 FML_DCHECK(
data.half_width < 0);
908 for (
auto& trig : trigs) {
909 auto offset = trig * radii;
910 proc({left - offset.x, bottom + offset.y});
911 proc({left - offset.x, top - offset.y});
919 for (
auto& trig : trigs) {
920 auto offset =
Point(trig.sin * radii.width, trig.cos * radii.height);
921 proc({right + offset.x, bottom + offset.y});
922 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 ...
static constexpr Scalar kCircleTolerance
The pixel tolerance used by the algorighm to determine how many divisions to create for a circle.
VertexBuffer TessellateConvex(const PathSource &path, HostBuffer &data_host_buffer, HostBuffer &indexes_host_buffer, Scalar tolerance, bool supports_primitive_restart=false, bool supports_triangle_fan=false)
Given a convex path, create a triangle fan structure.
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
Return the maximum scale applied specifically to either the X axis or Y axis unit vectors (the bases)...
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