10 #include "flutter/fml/logging.h"
23 size_t contour_index)
const {
24 if (contour_index >=
contours.size()) {
27 const size_t start_index =
contours.at(contour_index).start_index;
28 const size_t end_index = (contour_index >=
contours.size() - 1)
30 :
contours.at(contour_index + 1).start_index;
31 return std::make_tuple(start_index, end_index);
35 if (!type.has_value()) {
36 return data_->components.size();
38 auto type_value = type.value();
40 return data_->contours.size();
43 for (
const auto& component : data_->components) {
44 if (component.type == type_value) {
60 return data_->points.empty();
68 auto& points = data_->points;
69 size_t currentIndex = 0;
70 for (
const auto& component : data_->components) {
71 switch (component.type) {
74 linear_applier(currentIndex,
76 points[component.index + 1]));
81 quad_applier(currentIndex,
83 points[component.index + 1],
84 points[component.index + 2]));
89 cubic_applier(currentIndex,
91 points[component.index + 1],
92 points[component.index + 2],
93 points[component.index + 3]));
97 if (contour_applier) {
98 contour_applier(currentIndex, data_->contours[component.index]);
108 auto& components = data_->components;
110 if (index >= components.size()) {
118 auto& points = data_->points;
119 auto point_index = components[index].index;
127 auto& components = data_->components;
129 if (index >= components.size()) {
137 auto& points = data_->points;
138 auto point_index = components[index].index;
140 points[point_index], points[point_index + 1], points[point_index + 2]);
146 auto& components = data_->components;
148 if (index >= components.size()) {
156 auto& points = data_->points;
157 auto point_index = components[index].index;
159 points[point_index + 2], points[point_index + 3]);
165 auto& components = data_->components;
167 if (index >= components.size()) {
175 move = data_->contours[components[index].index];
181 : points(
std::move(point_buffer)), reclaim_points_(
std::move(reclaim)) {
186 points = std::move(other.points);
187 reclaim_points_ = std::move(other.reclaim_points_);
188 contours = std::move(other.contours);
192 if (reclaim_points_) {
194 reclaim_points_(std::move(points));
204 auto& path_components = data_->components;
205 auto& path_points = data_->points;
207 auto get_path_component = [&path_components, &path_points](
209 if (component_i >= path_components.size()) {
210 return std::monostate{};
212 const auto& component = path_components[component_i];
213 switch (component.type) {
216 &path_points[component.index]);
219 &path_points[component.index]);
222 &path_points[component.index]);
224 return std::monostate{};
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);
236 if (maybe_vector.has_value()) {
237 return maybe_vector.value();
239 next_component_index++;
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]() {
255 if (!previous_path_component_index.has_value()) {
259 auto& contour =
polyline.contours.back();
260 contour.end_direction =
Vector2(0, 1);
261 contour.components = poly_components;
262 poly_components.clear();
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);
270 if (maybe_vector.has_value()) {
271 contour.end_direction = maybe_vector.value();
274 if (previous_index == 0) {
282 for (
size_t component_i = 0; component_i < path_components.size();
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,
292 &path_points[path_component.index])
293 ->AppendPolylinePoints(*
polyline.points);
294 previous_path_component_index = component_i;
297 poly_components.push_back({
298 .component_start_index =
polyline.points->size() - 1,
302 &path_points[path_component.index])
304 previous_path_component_index = component_i;
307 poly_components.push_back({
308 .component_start_index =
polyline.points->size() - 1,
312 &path_points[path_component.index])
314 previous_path_component_index = component_i;
317 if (component_i == path_components.size() - 1) {
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});
331 polyline.points->push_back(contour.destination);
340 return data_->bounds;
344 const Matrix& transform)
const {
346 if (!bounds.has_value()) {
349 return bounds->TransformBounds(transform);