18 : point_buffer_(point_buffer), index_buffer_(index_buffer) {}
30 index_buffer_[index_count_++] = 0xFFFF;
34 index_buffer_[index_count_++] = count_;
35 point_buffer_[count_++] = point;
41 uint16_t* index_buffer)
42 : point_buffer_(point_buffer), index_buffer_(index_buffer) {}
51 if (count_ == 0u || contour_start_ == count_ - 1) {
56 size_t start = contour_start_;
57 size_t end = count_ - 1;
59 index_buffer_[index_count_++] = start;
64 index_buffer_[index_count_++] = a;
65 index_buffer_[index_count_++] =
b;
70 index_buffer_[index_count_++] = a;
73 contour_start_ = count_;
74 index_buffer_[index_count_++] = 0xFFFF;
78 point_buffer_[count_++] = point;
89 if (offset_ >= points_.size()) {
90 overflow_.push_back(point);
92 points_[offset_++] = point;
101 return std::make_pair(offset_, overflow_.size());
107 std::vector<uint16_t>& indices)
108 : points_(points), indices_(indices) {}
111 if (points_.size() == 0u || contour_start_ == points_.size() - 1) {
116 auto start = contour_start_;
117 auto end = points_.size() - 1;
122 if (points_[end] == points_[start]) {
127 if (contour_start_ != 0) {
128 auto back = indices_.back();
129 indices_.push_back(back);
130 indices_.push_back(start);
131 indices_.push_back(start);
136 if (previous_contour_odd_points_) {
137 indices_.push_back(start);
140 indices_.push_back(start);
143 size_t a = start + 1;
146 indices_.push_back(a);
147 indices_.push_back(
b);
152 indices_.push_back(a);
153 previous_contour_odd_points_ =
false;
155 previous_contour_odd_points_ =
true;
157 contour_start_ = points_.size();
161 points_.push_back(point);
169 return p0 + t * (p1 - p0);
173 return (1 - t) * (1 - t) * p0 +
174 2 * (1 - t) * t * p1 +
182 return 2 * (1 - t) * (p1 - p0) +
191 return (1 - t) * (1 - t) * (1 - t) * p0 +
192 3 * (1 - t) * (1 - t) * t * p1 +
193 3 * (1 - t) * t * t * p2 +
202 return -3 * p0 * (1 - t) * (1 - t) +
203 p1 * (3 * (1 - t) * (1 - t) - 6 * (1 - t) * t) +
204 p2 * (6 * (1 - t) * t - 3 * t * t) +
216 std::vector<Point>& points)
const {
217 if (points.size() == 0 || points.back() !=
p2) {
218 points.push_back(
p2);
230 return (
p1 -
p2).Normalize();
237 return (
p2 -
p1).Normalize();
258 for (
size_t i = 1; i < line_count; i += 1) {
266 std::vector<Point>& points)
const {
268 points.emplace_back(point);
277 for (
size_t i = 1; i < line_count; i += 1) {
278 proc(
Solve(i / line_count));
294 return (
p1 -
cp).Normalize();
297 return (
p1 -
p2).Normalize();
304 return (
p2 -
cp).Normalize();
307 return (
p2 -
p1).Normalize();
328 std::vector<Point>& points)
const {
330 scale, [&points](
const Point& point) { points.emplace_back(point); });
336 for (
size_t i = 1; i < line_count; i++) {
355 auto scale = (t1 - t0) * (1.0 / 3.0);
356 auto p1 = p0 +
scale * d.Solve(t0);
357 auto p2 = p3 -
scale * d.Solve(t1);
364 for (
size_t i = 1; i < line_count; i++) {
365 proc(
Solve(i / line_count));
371 return (a > (
b - epsilon)) && (a < (
b + epsilon));
383 const Scalar a = 3.0 * (-p1 + 3.0 * p2 - 3.0 * p3 + p4);
384 const Scalar b = 6.0 * (p1 - 2.0 * p2 + p3);
385 const Scalar c = 3.0 * (p2 - p1);
396 if (t >= 0.0 && t <= 1.0) {
397 values.emplace_back(t);
402 Scalar b2Minus4AC = (
b *
b) - (4.0 * a * c);
404 if (b2Minus4AC < 0.0) {
408 Scalar rootB2Minus4AC = ::sqrt(b2Minus4AC);
416 Scalar q = (
b < 0) ? -(
b - rootB2Minus4AC) / 2 : -(
b + rootB2Minus4AC) / 2;
420 if (t >= 0.0 && t <= 1.0) {
421 values.emplace_back(t);
427 if (t >= 0.0 && t <= 1.0) {
428 values.emplace_back(t);
437 std::vector<Scalar> values;
442 std::vector<Point> points = {
p1,
p2};
444 for (
const auto&
value : values) {
453 return (
p1 -
cp1).Normalize();
456 return (
p1 -
cp2).Normalize();
459 return (
p1 -
p2).Normalize();
466 return (
p2 -
cp2).Normalize();
469 return (
p2 -
cp1).Normalize();
472 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)
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 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)
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