@@ -89,142 +89,81 @@ Tessellator::Result Tessellator::Tessellate(const Path& path,
8989 constexpr int kVertexSize = 2 ;
9090 constexpr int kPolygonSize = 3 ;
9191
92- // If we have a larger polyline and the fill type is non-zero, we can split
93- // the tessellation up per contour. Since in general the complexity is at
94- // least nlog(n), this speeds up the processes substantially.
95- if (polyline.contours .size () > kMultiContourThreshold &&
96- fill_type == FillType::kNonZero ) {
97- std::vector<Point> points;
98- std::vector<float > data;
92+ // ----------------------------------------------------------------------------
93+ // / Feed contour information to the tessellator.
94+ // /
95+ static_assert (sizeof (Point) == 2 * sizeof (float ));
96+ for (size_t contour_i = 0 ; contour_i < polyline.contours .size ();
97+ contour_i++) {
98+ size_t start_point_index, end_point_index;
99+ std::tie (start_point_index, end_point_index) =
100+ polyline.GetContourPointBounds (contour_i);
101+
102+ ::tessAddContour (tessellator, // the C tessellator
103+ kVertexSize , //
104+ polyline.points->data () + start_point_index, //
105+ sizeof(Point), //
106+ end_point_index - start_point_index //
107+ );
108+ }
99109
100- // ----------------------------------------------------------------------------
101- // / Feed contour information to the tessellator.
102- // /
103- size_t total = 0u ;
104- static_assert (sizeof (Point) == 2 * sizeof (float ));
105- for (size_t contour_i = 0 ; contour_i < polyline.contours .size ();
106- contour_i++) {
107- size_t start_point_index, end_point_index;
108- std::tie (start_point_index, end_point_index) =
109- polyline.GetContourPointBounds (contour_i);
110-
111- ::tessAddContour (tessellator, // the C tessellator
112- kVertexSize , //
113- polyline.points->data () + start_point_index, //
114- sizeof(Point), //
115- end_point_index - start_point_index //
116- );
117-
118- // ----------------------------------------------------------------------------
119- // / Let's tessellate.
120- // /
121- auto result = ::tessTesselate(tessellator, // tessellator
122- ToTessWindingRule (fill_type), // winding
123- TESS_POLYGONS, // element type
124- kPolygonSize, // polygon size
125- kVertexSize, // vertex size
126- nullptr // normal (null is automatic)
127- );
128-
129- if (result != 1 ) {
130- return Result::kTessellationError ;
131- }
132-
133- int vertex_item_count = tessGetVertexCount (tessellator) * kVertexSize ;
134- auto vertices = tessGetVertices (tessellator);
135- for (int i = 0 ; i < vertex_item_count; i += 2 ) {
136- points.emplace_back (vertices[i], vertices[i + 1 ]);
137- }
138-
139- int element_item_count = tessGetElementCount (tessellator) * kPolygonSize ;
140- auto elements = tessGetElements (tessellator);
141- total += element_item_count;
142- for (int i = 0 ; i < element_item_count; i++) {
143- data.emplace_back (points[elements[i]].x );
144- data.emplace_back (points[elements[i]].y );
145- }
146- points.clear ();
110+ // ----------------------------------------------------------------------------
111+ // / Let's tessellate.
112+ // /
113+ auto result = ::tessTesselate(tessellator, // tessellator
114+ ToTessWindingRule (fill_type), // winding
115+ TESS_POLYGONS, // element type
116+ kPolygonSize, // polygon size
117+ kVertexSize, // vertex size
118+ nullptr // normal (null is automatic)
119+ );
120+
121+ if (result != 1 ) {
122+ return Result::kTessellationError ;
123+ }
124+
125+ int element_item_count = tessGetElementCount (tessellator) * kPolygonSize ;
126+
127+ // We default to using a 16bit index buffer, but in cases where we generate
128+ // more tessellated data than this can contain we need to fall back to
129+ // dropping the index buffer entirely. Instead code could instead switch to
130+ // a uint32 index buffer, but this is done for simplicity with the other
131+ // fast path above.
132+ if (element_item_count < USHRT_MAX) {
133+ int vertex_item_count = tessGetVertexCount (tessellator);
134+ auto vertices = tessGetVertices (tessellator);
135+ auto elements = tessGetElements (tessellator);
136+
137+ // libtess uses an int index internally due to usage of -1 as a sentinel
138+ // value.
139+ std::vector<uint16_t > indices (element_item_count);
140+ for (int i = 0 ; i < element_item_count; i++) {
141+ indices[i] = static_cast <uint16_t >(elements[i]);
147142 }
148- if (!callback (data.data (), total, nullptr , 0u )) {
143+ if (!callback (vertices, vertex_item_count, indices.data (),
144+ element_item_count)) {
149145 return Result::kInputError ;
150146 }
151147 } else {
152- // ----------------------------------------------------------------------------
153- // / Feed contour information to the tessellator.
154- // /
155- static_assert (sizeof (Point) == 2 * sizeof (float ));
156- for (size_t contour_i = 0 ; contour_i < polyline.contours .size ();
157- contour_i++) {
158- size_t start_point_index, end_point_index;
159- std::tie (start_point_index, end_point_index) =
160- polyline.GetContourPointBounds (contour_i);
161-
162- ::tessAddContour (tessellator, // the C tessellator
163- kVertexSize , //
164- polyline.points->data () + start_point_index, //
165- sizeof(Point), //
166- end_point_index - start_point_index //
167- );
168- }
169-
170- // ----------------------------------------------------------------------------
171- // / Let's tessellate.
172- // /
173- auto result = ::tessTesselate(tessellator, // tessellator
174- ToTessWindingRule (fill_type), // winding
175- TESS_POLYGONS, // element type
176- kPolygonSize, // polygon size
177- kVertexSize, // vertex size
178- nullptr // normal (null is automatic)
179- );
148+ std::vector<Point> points;
149+ std::vector<float > data;
180150
181- if (result != 1 ) {
182- return Result::kTessellationError ;
151+ int vertex_item_count = tessGetVertexCount (tessellator) * kVertexSize ;
152+ auto vertices = tessGetVertices (tessellator);
153+ points.reserve (vertex_item_count);
154+ for (int i = 0 ; i < vertex_item_count; i += 2 ) {
155+ points.emplace_back (vertices[i], vertices[i + 1 ]);
183156 }
184157
185158 int element_item_count = tessGetElementCount (tessellator) * kPolygonSize ;
186-
187- // We default to using a 16bit index buffer, but in cases where we generate
188- // more tessellated data than this can contain we need to fall back to
189- // dropping the index buffer entirely. Instead code could instead switch to
190- // a uint32 index buffer, but this is done for simplicity with the other
191- // fast path above.
192- if (element_item_count < USHRT_MAX) {
193- int vertex_item_count = tessGetVertexCount (tessellator);
194- auto vertices = tessGetVertices (tessellator);
195- auto elements = tessGetElements (tessellator);
196-
197- // libtess uses an int index internally due to usage of -1 as a sentinel
198- // value.
199- std::vector<uint16_t > indices (element_item_count);
200- for (int i = 0 ; i < element_item_count; i++) {
201- indices[i] = static_cast <uint16_t >(elements[i]);
202- }
203- if (!callback (vertices, vertex_item_count, indices.data (),
204- element_item_count)) {
205- return Result::kInputError ;
206- }
207- } else {
208- std::vector<Point> points;
209- std::vector<float > data;
210-
211- int vertex_item_count = tessGetVertexCount (tessellator) * kVertexSize ;
212- auto vertices = tessGetVertices (tessellator);
213- points.reserve (vertex_item_count);
214- for (int i = 0 ; i < vertex_item_count; i += 2 ) {
215- points.emplace_back (vertices[i], vertices[i + 1 ]);
216- }
217-
218- int element_item_count = tessGetElementCount (tessellator) * kPolygonSize ;
219- auto elements = tessGetElements (tessellator);
220- data.reserve (element_item_count);
221- for (int i = 0 ; i < element_item_count; i++) {
222- data.emplace_back (points[elements[i]].x );
223- data.emplace_back (points[elements[i]].y );
224- }
225- if (!callback (data.data (), element_item_count, nullptr , 0u )) {
226- return Result::kInputError ;
227- }
159+ auto elements = tessGetElements (tessellator);
160+ data.reserve (element_item_count);
161+ for (int i = 0 ; i < element_item_count; i++) {
162+ data.emplace_back (points[elements[i]].x );
163+ data.emplace_back (points[elements[i]].y );
164+ }
165+ if (!callback (data.data (), element_item_count, nullptr , 0u )) {
166+ return Result::kInputError ;
228167 }
229168 }
230169
0 commit comments