| Flutter Impeller |

path_tessellator.h
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 #ifndef FLUTTER_IMPELLER_TESSELLATOR_PATH_TESSELLATOR_H_
6 #define FLUTTER_IMPELLER_TESSELLATOR_PATH_TESSELLATOR_H_
7
8 #include <memory>
9 #include <tuple>
10
11 #include "flutter/impeller/geometry/path_source.h"
12 #include "flutter/impeller/geometry/scalar.h"
13 #include "flutter/impeller/geometry/wangs_formula.h"
14
15 namespace impeller {
16
17 class PathTessellator {
18 public:
19 /// @brief An interface for generating a multi contour polyline as a triangle
20 /// strip.
21 class VertexWriter {
22 public:
23 virtual void Write(Point point) = 0;
24 virtual void EndContour() = 0;
25 };
26
27 /// An interface for receiving pruned path segments.
28 class SegmentReceiver {
29 public:
30 /// Every set of path segments will be surrounded by a Begin/EndContour
31 /// pair with the same origin point.
32 virtual void BeginContour(Point origin, bool will_be_closed) = 0;
33
34 /// Guaranteed to be non-degenerate except in the single case of stroking
35 /// where we have a MoveTo followed by any number of degenerate (single
36 /// point, going nowhere) path segments.
37 /// p1 will always be the last recorded point.
38 virtual void RecordLine(Point p1, Point p2) = 0;
39
40 /// Guaranteed to be non-degenerate (not a line).
41 /// p1 will always be the last recorded point.
42 virtual void RecordQuad(Point p1, Point cp, Point p2) = 0;
43
44 /// Guaranteed to be non-degenerate (not a quad or line)
45 /// p1 will always be the last recorded point.
46 virtual void RecordConic(Point p1, Point cp, Point p2, Scalar weight) = 0;
47
48 /// Guaranteed to be trivially non-degenerate (not all 4 points the same).
49 /// p1 will always be the last recorded point.
50 virtual void RecordCubic(Point p1, Point cp1, Point cp2, Point p2) = 0;
51
52 /// Every set of path segments will be surrounded by a Begin/EndContour
53 /// pair with the same origin point.
54 /// The boolean indicates if the path was closed as the result of an
55 /// explicit PathReceiver::Close invocation which tells a stroking
56 /// sub-class whether to use end caps or a "join to first segment".
57 /// Contours which are closed by a MoveTo will supply "false".
58 virtual void EndContour(Point origin, bool with_close) = 0;
59 };
60
61 struct Quad {
62 const Point p1;
63 const Point cp;
64 const Point p2;
65
66 Point Last() const { return p2; }
67
68 Point Solve(Scalar t) const {
69 Scalar u = 1.0f - t;
70 return p1 * u * u + 2 * cp * u * t + p2 * t * t;
71 }
72
73 Scalar SubdivisionCount(Scalar scale) const {
74 return ComputeQuadradicSubdivisions(scale, p1, cp, p2);
75 }
76
77 std::optional<Vector2> GetStartDirection() const {
78 if (p1 != cp) {
79 return (p1 - cp).Normalize();
80 }
81 if (p1 != p2) {
82 return (p1 - p2).Normalize();
83 }
84 return std::nullopt;
85 }
86
87 std::optional<Vector2> GetEndDirection() const {
88 if (p2 != cp) {
89 return (p2 - cp).Normalize();
90 }
91 if (p2 != p1) {
92 return (p2 - p1).Normalize();
93 }
94 return std::nullopt;
95 }
96 };
97
98 struct Conic {
99 const Point p1;
100 const Point cp;
101 const Point p2;
102 const Scalar weight;
103
104 Point Last() const { return p2; }
105
106 Point Solve(Scalar t) const {
107 Scalar u = 1.0f - t;
108 Scalar coeff_1 = u * u;
109 Scalar coeff_c = 2 * u * t * weight;
110 Scalar coeff_2 = t * t;
111
112 return (p1 * coeff_1 + cp * coeff_c + p2 * coeff_2) /
113 (coeff_1 + coeff_c + coeff_2);
114 }
115
116 Scalar SubdivisionCount(Scalar scale) const {
117 return ComputeConicSubdivisions(scale, p1, cp, p2, weight);
118 }
119
120 std::optional<Vector2> GetStartDirection() const {
121 if (p1 != cp) {
122 return (p1 - cp).Normalize();
123 }
124 if (p1 != p2) {
125 return (p1 - p2).Normalize();
126 }
127 return std::nullopt;
128 }
129
130 std::optional<Vector2> GetEndDirection() const {
131 if (p2 != cp) {
132 return (p2 - cp).Normalize();
133 }
134 if (p2 != p1) {
135 return (p2 - p1).Normalize();
136 }
137 return std::nullopt;
138 }
139 };
140
141 struct Cubic {
142 const Point p1;
143 const Point cp1;
144 const Point cp2;
145 const Point p2;
146
147 Point Last() const { return p2; }
148
149 Point Solve(Scalar t) const {
150 Scalar u = 1.0f - t;
151 return p1 * u * u * u + //
152 3 * cp1 * u * u * t + //
153 3 * cp2 * u * t * t + //
154 p2 * t * t * t;
155 }
156
157 Scalar SubdivisionCount(Scalar scale) const {
158 return ComputeCubicSubdivisions(scale, p1, cp1, cp2, p2);
159 }
160
161 std::optional<Vector2> GetStartDirection() const {
162 if (p1 != cp1) {
163 return (p1 - cp1).Normalize();
164 }
165 if (p1 != cp2) {
166 return (p1 - cp2).Normalize();
167 }
168 if (p1 != p2) {
169 return (p1 - p2).Normalize();
170 }
171 return std::nullopt;
172 }
173
174 std::optional<Vector2> GetEndDirection() const {
175 if (p2 != cp2) {
176 return (p2 - cp2).Normalize();
177 }
178 if (p2 != cp1) {
179 return (p2 - cp1).Normalize();
180 }
181 if (p2 != p1) {
182 return (p2 - p1).Normalize();
183 }
184 return std::nullopt;
185 }
186 };
187
188 static void PathToFilledSegments(const PathSource& source,
189 SegmentReceiver& receiver);
190
191 static void PathToStrokedSegments(const PathSource& source,
192 SegmentReceiver& receiver);
193
194 static std::pair<size_t, size_t> CountFillStorage(const PathSource& source,
195 Scalar scale);
196
197 static void PathToFilledVertices(const PathSource& source,
198 VertexWriter& writer,
199 Scalar scale);
200
201 static void PathToTransformedFilledVertices(const PathSource& source,
202 VertexWriter& writer,
203 const Matrix& matrix);
204 };
205
206 } // namespace impeller
207
208 #endif // FLUTTER_IMPELLER_TESSELLATOR_PATH_TESSELLATOR_H_
impeller::PathSource
Definition: path_source.h:55
impeller::PathTessellator::SegmentReceiver
An interface for receiving pruned path segments.
Definition: path_tessellator.h:28
impeller::PathTessellator::SegmentReceiver::RecordLine
virtual void RecordLine(Point p1, Point p2)=0
impeller::PathTessellator::SegmentReceiver::RecordCubic
virtual void RecordCubic(Point p1, Point cp1, Point cp2, Point p2)=0
impeller::PathTessellator::SegmentReceiver::RecordConic
virtual void RecordConic(Point p1, Point cp, Point p2, Scalar weight)=0
impeller::PathTessellator::SegmentReceiver::RecordQuad
virtual void RecordQuad(Point p1, Point cp, Point p2)=0
impeller::PathTessellator::SegmentReceiver::EndContour
virtual void EndContour(Point origin, bool with_close)=0
impeller::PathTessellator::SegmentReceiver::BeginContour
virtual void BeginContour(Point origin, bool will_be_closed)=0
impeller::PathTessellator::VertexWriter
An interface for generating a multi contour polyline as a triangle strip.
Definition: path_tessellator.h:21
impeller::PathTessellator::VertexWriter::EndContour
virtual void EndContour()=0
impeller::PathTessellator::VertexWriter::Write
virtual void Write(Point point)=0
impeller::PathTessellator
Definition: path_tessellator.h:17
impeller::PathTessellator::PathToFilledSegments
static void PathToFilledSegments(const PathSource &source, SegmentReceiver &receiver)
Definition: path_tessellator.cc:284
impeller::PathTessellator::PathToTransformedFilledVertices
static void PathToTransformedFilledVertices(const PathSource &source, VertexWriter &writer, const Matrix &matrix)
Definition: path_tessellator.cc:317
impeller::PathTessellator::PathToStrokedSegments
static void PathToStrokedSegments(const PathSource &source, SegmentReceiver &receiver)
Definition: path_tessellator.cc:291
impeller::PathTessellator::PathToFilledVertices
static void PathToFilledVertices(const PathSource &source, VertexWriter &writer, Scalar scale)
Definition: path_tessellator.cc:308
impeller::PathTessellator::CountFillStorage
static std::pair< size_t, size_t > CountFillStorage(const PathSource &source, Scalar scale)
Definition: path_tessellator.cc:298
impeller
Definition: allocation.cc:12
impeller::Scalar
float Scalar
Definition: scalar.h:19
impeller::ComputeConicSubdivisions
Scalar ComputeConicSubdivisions(Scalar scale_factor, Point p0, Point p1, Point p2, Scalar w)
Definition: wangs_formula.cc:45
impeller::ComputeQuadradicSubdivisions
Scalar ComputeQuadradicSubdivisions(Scalar scale_factor, Point p0, Point p1, Point p2)
Definition: wangs_formula.cc:31
impeller::ComputeCubicSubdivisions
Scalar ComputeCubicSubdivisions(Scalar scale_factor, Point p0, Point p1, Point p2, Point p3)
Definition: wangs_formula.cc:18
path_source.h
scalar.h
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::PathTessellator::Conic
Definition: path_tessellator.h:98
impeller::PathTessellator::Conic::GetStartDirection
std::optional< Vector2 > GetStartDirection() const
Definition: path_tessellator.h:120
impeller::PathTessellator::Conic::Last
Point Last() const
Definition: path_tessellator.h:104
impeller::PathTessellator::Conic::GetEndDirection
std::optional< Vector2 > GetEndDirection() const
Definition: path_tessellator.h:130
impeller::PathTessellator::Conic::weight
const Scalar weight
Definition: path_tessellator.h:102
impeller::PathTessellator::Conic::Solve
Point Solve(Scalar t) const
Definition: path_tessellator.h:106
impeller::PathTessellator::Conic::cp
const Point cp
Definition: path_tessellator.h:100
impeller::PathTessellator::Conic::p2
const Point p2
Definition: path_tessellator.h:101
impeller::PathTessellator::Conic::SubdivisionCount
Scalar SubdivisionCount(Scalar scale) const
Definition: path_tessellator.h:116
impeller::PathTessellator::Conic::p1
const Point p1
Definition: path_tessellator.h:99
impeller::PathTessellator::Cubic
Definition: path_tessellator.h:141
impeller::PathTessellator::Cubic::Solve
Point Solve(Scalar t) const
Definition: path_tessellator.h:149
impeller::PathTessellator::Cubic::cp2
const Point cp2
Definition: path_tessellator.h:144
impeller::PathTessellator::Cubic::p2
const Point p2
Definition: path_tessellator.h:145
impeller::PathTessellator::Cubic::GetStartDirection
std::optional< Vector2 > GetStartDirection() const
Definition: path_tessellator.h:161
impeller::PathTessellator::Cubic::SubdivisionCount
Scalar SubdivisionCount(Scalar scale) const
Definition: path_tessellator.h:157
impeller::PathTessellator::Cubic::cp1
const Point cp1
Definition: path_tessellator.h:143
impeller::PathTessellator::Cubic::p1
const Point p1
Definition: path_tessellator.h:142
impeller::PathTessellator::Cubic::Last
Point Last() const
Definition: path_tessellator.h:147
impeller::PathTessellator::Cubic::GetEndDirection
std::optional< Vector2 > GetEndDirection() const
Definition: path_tessellator.h:174
impeller::PathTessellator::Quad
Definition: path_tessellator.h:61
impeller::PathTessellator::Quad::Last
Point Last() const
Definition: path_tessellator.h:66
impeller::PathTessellator::Quad::SubdivisionCount
Scalar SubdivisionCount(Scalar scale) const
Definition: path_tessellator.h:73
impeller::PathTessellator::Quad::p1
const Point p1
Definition: path_tessellator.h:62
impeller::PathTessellator::Quad::cp
const Point cp
Definition: path_tessellator.h:63
impeller::PathTessellator::Quad::Solve
Point Solve(Scalar t) const
Definition: path_tessellator.h:68
impeller::PathTessellator::Quad::GetStartDirection
std::optional< Vector2 > GetStartDirection() const
Definition: path_tessellator.h:77
impeller::PathTessellator::Quad::p2
const Point p2
Definition: path_tessellator.h:64
impeller::PathTessellator::Quad::GetEndDirection
std::optional< Vector2 > GetEndDirection() const
Definition: path_tessellator.h:87
impeller::TPoint< Scalar >
wangs_formula.h