Callers must provide the scale factor for how this path will be transformed.
It is suitable to use the max basis length of the matrix used to transform the path. If the provided scale is 0, curves will revert to straight lines.
201 {
202 Polyline
polyline(std::move(point_buffer), std::move(reclaim));
203
204 auto& path_components = data_->components;
205 auto& path_points = data_->points;
206
207 auto get_path_component = [&path_components, &path_points](
209 if (component_i >= path_components.size()) {
210 return std::monostate{};
211 }
212 const auto& component = path_components[component_i];
213 switch (component.type) {
215 return reinterpret_cast<const LinearPathComponent*>(
216 &path_points[component.index]);
218 return reinterpret_cast<const QuadraticPathComponent*>(
219 &path_points[component.index]);
221 return reinterpret_cast<const CubicPathComponent*>(
222 &path_points[component.index]);
224 return std::monostate{};
225 }
226 };
227
228 auto compute_contour_start_direction =
229 [&get_path_component](size_t current_path_component_index) {
230 size_t next_component_index = current_path_component_index + 1;
231 while (!std::holds_alternative<std::monostate>(
232 get_path_component(next_component_index))) {
233 auto next_component = get_path_component(next_component_index);
234 auto maybe_vector =
235 std::visit(PathComponentStartDirectionVisitor(), next_component);
236 if (maybe_vector.has_value()) {
237 return maybe_vector.value();
238 } else {
239 next_component_index++;
240 }
241 }
243 };
244
245 std::vector<PolylineContour::Component> poly_components;
246 std::optional<size_t> previous_path_component_index;
247 auto end_contour = [&
polyline, &previous_path_component_index,
248 &get_path_component, &poly_components]() {
249
250
252 return;
253 }
254
255 if (!previous_path_component_index.has_value()) {
256 return;
257 }
258
261 contour.components = poly_components;
262 poly_components.clear();
263
264 size_t previous_index = previous_path_component_index.value();
265 while (!std::holds_alternative<std::monostate>(
266 get_path_component(previous_index))) {
267 auto previous_component = get_path_component(previous_index);
268 auto maybe_vector =
269 std::visit(PathComponentEndDirectionVisitor(), previous_component);
270 if (maybe_vector.has_value()) {
271 contour.end_direction = maybe_vector.value();
272 break;
273 } else {
274 if (previous_index == 0) {
275 break;
276 }
277 previous_index--;
278 }
279 }
280 };
281
282 for (size_t component_i = 0; component_i < path_components.size();
283 component_i++) {
284 const auto& path_component = path_components[component_i];
285 switch (path_component.type) {
287 poly_components.push_back({
288 .component_start_index =
polyline.points->size() - 1,
289 .is_curve = false,
290 });
291 reinterpret_cast<const LinearPathComponent*>(
292 &path_points[path_component.index])
293 ->AppendPolylinePoints(*
polyline.points);
294 previous_path_component_index = component_i;
295 break;
297 poly_components.push_back({
298 .component_start_index =
polyline.points->size() - 1,
299 .is_curve = true,
300 });
301 reinterpret_cast<const QuadraticPathComponent*>(
302 &path_points[path_component.index])
304 previous_path_component_index = component_i;
305 break;
307 poly_components.push_back({
308 .component_start_index =
polyline.points->size() - 1,
309 .is_curve = true,
310 });
311 reinterpret_cast<const CubicPathComponent*>(
312 &path_points[path_component.index])
314 previous_path_component_index = component_i;
315 break;
317 if (component_i == path_components.size() - 1) {
318
319
320 continue;
321 }
322 end_contour();
323
324 Vector2 start_direction = compute_contour_start_direction(component_i);
325 const auto&
contour = data_->contours[path_component.index];
327 .is_closed =
contour.is_closed,
328 .start_direction = start_direction,
329 .components = poly_components});
330
332 break;
333 }
334 }
335 end_contour();
337}
std::variant< std::monostate, const LinearPathComponent *, const QuadraticPathComponent *, const CubicPathComponent * > PathComponentVariant
const Path::Polyline & polyline