10 #include "flutter/fml/logging.h"
19 : point_buffer_(point_buffer), index_buffer_(index_buffer) {}
31 index_buffer_[index_count_++] = 0xFFFF;
35 index_buffer_[index_count_++] = count_;
36 point_buffer_[count_++] = point;
42 uint16_t* index_buffer)
43 : point_buffer_(point_buffer), index_buffer_(index_buffer) {}
52 if (count_ == 0u || contour_start_ == count_ - 1) {
57 size_t start = contour_start_;
58 size_t end = count_ - 1;
60 index_buffer_[index_count_++] = start;
65 index_buffer_[index_count_++] = a;
66 index_buffer_[index_count_++] =
b;
71 index_buffer_[index_count_++] = a;
74 contour_start_ = count_;
75 index_buffer_[index_count_++] = 0xFFFF;
79 point_buffer_[count_++] = point;
90 if (offset_ >= points_.size()) {
91 overflow_.push_back(point);
93 points_[offset_++] = point;
102 return std::make_pair(offset_, overflow_.size());
108 std::vector<uint16_t>& indices)
109 : points_(points), indices_(indices) {}
112 if (points_.size() == 0u || contour_start_ == points_.size() - 1) {
117 auto start = contour_start_;
118 auto end = points_.size() - 1;
123 if (points_[end] == points_[start]) {
128 if (contour_start_ != 0) {
129 auto back = indices_.back();
130 indices_.push_back(back);
131 indices_.push_back(start);
132 indices_.push_back(start);
137 if (previous_contour_odd_points_) {
138 indices_.push_back(start);
141 indices_.push_back(start);
144 size_t a = start + 1;
147 indices_.push_back(a);
148 indices_.push_back(
b);
153 indices_.push_back(a);
154 previous_contour_odd_points_ =
false;
156 previous_contour_odd_points_ =
true;
158 contour_start_ = points_.size();
162 points_.push_back(point);
170 return p0 + t * (p1 - p0);
174 return (1 - t) * (1 - t) * p0 +
175 2 * (1 - t) * t * p1 +
183 return 2 * (1 - t) * (p1 - p0) +
193 auto coefficient_p0 = u * u;
194 auto coefficient_p1 = 2 * t * u * w;
195 auto coefficient_p2 = t * t;
197 return ((p0 * coefficient_p0 + p1 * coefficient_p1 + p2 * coefficient_p2) /
198 (coefficient_p0 + coefficient_p1 + coefficient_p2));
206 return (1 - t) * (1 - t) * (1 - t) * p0 +
207 3 * (1 - t) * (1 - t) * t * p1 +
208 3 * (1 - t) * t * t * p2 +
217 return -3 * p0 * (1 - t) * (1 - t) +
218 p1 * (3 * (1 - t) * (1 - t) - 6 * (1 - t) * t) +
219 p2 * (6 * (1 - t) * t - 3 * t * t) +
231 std::vector<Point>& points)
const {
232 if (points.size() == 0 || points.back() !=
p2) {
233 points.push_back(
p2);
245 return (
p1 -
p2).Normalize();
252 return (
p2 -
p1).Normalize();
273 for (
size_t i = 1; i < line_count; i += 1) {
281 std::vector<Point>& points)
const {
283 points.emplace_back(point);
292 for (
size_t i = 1; i < line_count; i += 1) {
293 proc(
Solve(i / line_count));
309 return (
p1 -
cp).Normalize();
312 return (
p1 -
p2).Normalize();
319 return (
p2 -
cp).Normalize();
322 return (
p2 -
p1).Normalize();
337 for (
size_t i = 1; i < line_count; i += 1) {
338 proc(
Solve(i / line_count));
345 std::vector<Point>& points)
const {
347 if (point != points.back()) {
348 points.emplace_back(point);
356 for (
size_t i = 1; i < line_count; i += 1) {
367 std::vector<Point> points;
369 auto quad_extrema = quad.Extrema();
370 points.insert(points.end(), quad_extrema.begin(), quad_extrema.end());
377 return (
p1 -
cp).Normalize();
380 return (
p1 -
p2).Normalize();
387 return (
p2 -
cp).Normalize();
390 return (
p2 -
p1).Normalize();
396 std::array<Point, 5>& points)
const {
412 Point sub_cp1 = tp1 + tcp;
413 Point sub_cp2 = tcp + tp2;
417 Point sub_mid = (tp1 + tcp + tcp + tp2) * 0.5f;
434 std::array<QuadraticPathComponent, 2>
436 std::array<Point, 5> points;
461 std::vector<Point>& points)
const {
463 scale, [&points](
const Point& point) { points.emplace_back(point); });
469 for (
size_t i = 1; i < line_count; i++) {
488 auto scale = (t1 - t0) * (1.0 / 3.0);
489 auto p1 = p0 +
scale * d.Solve(t0);
490 auto p2 = p3 -
scale * d.Solve(t1);
497 for (
size_t i = 1; i < line_count; i++) {
498 proc(
Solve(i / line_count));
504 return (a > (
b - epsilon)) && (a < (
b + epsilon));
516 const Scalar a = 3.0 * (-p1 + 3.0 * p2 - 3.0 * p3 + p4);
517 const Scalar b = 6.0 * (p1 - 2.0 * p2 + p3);
518 const Scalar c = 3.0 * (p2 - p1);
529 if (t >= 0.0 && t <= 1.0) {
530 values.emplace_back(t);
535 Scalar b2Minus4AC = (
b *
b) - (4.0 * a * c);
537 if (b2Minus4AC < 0.0) {
541 Scalar rootB2Minus4AC = ::sqrt(b2Minus4AC);
549 Scalar q = (
b < 0) ? -(
b - rootB2Minus4AC) / 2 : -(
b + rootB2Minus4AC) / 2;
553 if (t >= 0.0 && t <= 1.0) {
554 values.emplace_back(t);
560 if (t >= 0.0 && t <= 1.0) {
561 values.emplace_back(t);
570 std::vector<Scalar> values;
575 std::vector<Point> points = {
p1,
p2};
577 for (
const auto&
value : values) {
586 return (
p1 -
cp1).Normalize();
589 return (
p1 -
cp2).Normalize();
592 return (
p1 -
p2).Normalize();
599 return (
p2 -
cp2).Normalize();
602 return (
p2 -
cp1).Normalize();
605 return (
p2 -
p1).Normalize();
void EndContour() override
size_t GetIndexCount() const
void Write(Point point) override
FanVertexWriter(Point *point_buffer, uint16_t *index_buffer)
GLESVertexWriter(std::vector< Point > &points, std::vector< uint16_t > &indices)
void Write(Point point) override
void EndContour() override
std::pair< size_t, size_t > GetVertexCount() const
LineStripVertexWriter(std::vector< Point > &points)
void Write(Point point) override
void EndContour() override
const std::vector< Point > & GetOversizedBuffer() const
void Write(Point point) override
size_t GetIndexCount() const
StripVertexWriter(Point *point_buffer, uint16_t *index_buffer)
void EndContour() override
An interface for generating a multi contour polyline as a triangle strip.
virtual void Write(Point point)=0
static void CubicPathBoundingPopulateValues(std::vector< Scalar > &values, Scalar p1, Scalar p2, Scalar p3, Scalar p4)
static bool NearZero(Scalar a)
Scalar ComputeConicSubdivisions(Scalar scale_factor, Point p0, Point p1, Point p2, Scalar w)
static Scalar LinearSolve(Scalar t, Scalar p0, Scalar p1)
static Scalar CubicSolve(Scalar t, Scalar p0, Scalar p1, Scalar p2, Scalar p3)
static Scalar CubicSolveDerivative(Scalar t, Scalar p0, Scalar p1, Scalar p2, Scalar p3)
static Scalar ConicSolve(Scalar t, Scalar p0, Scalar p1, Scalar p2, Scalar w)
static Scalar QuadraticSolve(Scalar t, Scalar p0, Scalar p1, Scalar p2)
static Scalar QuadraticSolveDerivative(Scalar t, Scalar p0, Scalar p1, Scalar p2)
Scalar ComputeQuadradicSubdivisions(Scalar scale_factor, Point p0, Point p1, Point p2)
Scalar ComputeCubicSubdivisions(Scalar scale_factor, Point p0, Point p1, Point p2, Point p3)
static bool NearEqual(Scalar a, Scalar b, Scalar epsilon)
std::optional< Vector2 > GetEndDirection() const
std::array< QuadraticPathComponent, 2 > ToQuadraticPathComponents() const
size_t CountLinearPathComponents(Scalar scale) const
Point Solve(Scalar time) const
void ToLinearPathComponents(Scalar scale_factor, const PointProc &proc) const
std::vector< Point > Extrema() const
std::optional< Vector2 > GetStartDirection() const
void SubdivideToQuadraticPoints(std::array< Point, 5 > &points) const
std::function< void(const Point &point)> PointProc
void AppendPolylinePoints(Scalar scale_factor, std::vector< Point > &points) const
void ToLinearPathComponents(Scalar scale, const PointProc &proc) const
size_t CountLinearPathComponents(Scalar scale) const
void AppendPolylinePoints(Scalar scale, std::vector< Point > &points) const
std::function< void(const Point &point)> PointProc
CubicPathComponent Subsegment(Scalar t0, Scalar t1) const
Point Solve(Scalar time) const
std::optional< Vector2 > GetStartDirection() const
std::vector< Point > Extrema() const
std::optional< Vector2 > GetEndDirection() const
Point SolveDerivative(Scalar time) const
std::optional< Vector2 > GetEndDirection() const
std::optional< Vector2 > GetStartDirection() const
std::vector< Point > Extrema() const
Point Solve(Scalar time) const
void AppendPolylinePoints(std::vector< Point > &points) const
size_t CountLinearPathComponents(Scalar scale) const
std::optional< Vector2 > GetEndDirection() const
void AppendPolylinePoints(Scalar scale_factor, std::vector< Point > &points) const
std::function< void(const Point &point)> PointProc
std::vector< Point > Extrema() const
Point SolveDerivative(Scalar time) const
std::optional< Vector2 > GetStartDirection() const
void ToLinearPathComponents(Scalar scale_factor, const PointProc &proc) const
Point Solve(Scalar time) const