9 #include "flutter/fml/logging.h"
22 size_t contour_index)
const {
23 if (contour_index >=
contours.size()) {
26 const size_t start_index =
contours.at(contour_index).start_index;
27 const size_t end_index = (contour_index >=
contours.size() - 1)
29 :
contours.at(contour_index + 1).start_index;
30 return std::make_tuple(start_index, end_index);
34 if (!
type.has_value()) {
35 return data_->components.size();
37 auto type_value =
type.value();
39 for (
const auto& component : data_->components) {
40 if (component == type_value) {
56 return data_->points.empty() ||
57 (data_->components.size() == 1 &&
62 auto& path_components = data_->components;
63 auto& path_points = data_->points;
64 bool started_contour =
false;
65 bool first_point =
true;
67 size_t storage_offset = 0u;
68 for (
size_t component_i = 0; component_i < path_components.size();
70 const auto& path_component = path_components[component_i];
71 switch (path_component) {
75 &path_points[storage_offset]);
86 &path_points[storage_offset]);
97 &path_points[storage_offset]);
106 if (component_i == path_components.size() - 1) {
116 if (started_contour) {
119 started_contour =
true;
124 if (started_contour) {
131 auto& components = data_->components;
132 if (index >= components.size() ||
137 size_t storage_offset = 0u;
138 for (
auto i = 0u; i < index; i++) {
141 auto& points = data_->points;
150 auto& components = data_->components;
151 if (index >= components.size() ||
156 size_t storage_offset = 0u;
157 for (
auto i = 0u; i < index; i++) {
160 auto& points = data_->points;
164 points[storage_offset + 2]);
170 auto& components = data_->components;
171 if (index >= components.size() ||
176 size_t storage_offset = 0u;
177 for (
auto i = 0u; i < index; i++) {
180 auto& points = data_->points;
183 points[storage_offset + 2],
184 points[storage_offset + 3]);
190 auto& components = data_->components;
191 if (index >= components.size() ||
196 size_t storage_offset = 0u;
197 for (
auto i = 0u; i < index; i++) {
200 auto& points = data_->points;
202 move =
ContourComponent(points[storage_offset], points[storage_offset + 1]);
208 : points(
std::move(point_buffer)), reclaim_points_(
std::move(reclaim)) {
213 points = std::move(other.points);
214 reclaim_points_ = std::move(other.reclaim_points_);
215 contours = std::move(other.contours);
219 if (reclaim_points_) {
221 reclaim_points_(std::move(points));
226 size_t storage_offset,
228 size_t component_index,
229 std::vector<PolylineContour::Component>& poly_components)
const {
230 auto& path_components = data_->components;
231 auto& path_points = data_->points;
234 if (
polyline.contours.empty() || component_index == 0) {
238 auto& contour =
polyline.contours.back();
239 contour.end_direction =
Vector2(0, 1);
240 contour.components = poly_components;
241 poly_components.clear();
243 size_t previous_index = component_index - 1;
244 storage_offset -=
VerbToOffset(path_components[previous_index]);
246 while (previous_index >= 0 && storage_offset >= 0) {
247 const auto& path_component = path_components[previous_index];
248 switch (path_component) {
251 &path_points[storage_offset]);
253 if (maybe_end.has_value()) {
254 contour.end_direction = maybe_end.value();
261 &path_points[storage_offset]);
263 if (maybe_end.has_value()) {
264 contour.end_direction = maybe_end.value();
271 &path_points[storage_offset]);
273 if (maybe_end.has_value()) {
274 contour.end_direction = maybe_end.value();
295 auto& path_components = data_->components;
296 auto& path_points = data_->points;
297 std::optional<Vector2> start_direction;
298 std::vector<PolylineContour::Component> poly_components;
299 size_t storage_offset = 0u;
300 size_t component_i = 0;
302 for (; component_i < path_components.size(); component_i++) {
303 auto path_component = path_components[component_i];
304 switch (path_component) {
306 poly_components.push_back({
307 .component_start_index =
polyline.points->size() - 1,
311 &path_points[storage_offset]);
313 if (!start_direction.has_value()) {
314 start_direction = linear->GetStartDirection();
319 poly_components.push_back({
320 .component_start_index =
polyline.points->size() - 1,
324 &path_points[storage_offset]);
326 if (!start_direction.has_value()) {
327 start_direction = quad->GetStartDirection();
332 poly_components.push_back({
333 .component_start_index =
polyline.points->size() - 1,
337 &path_points[storage_offset]);
339 if (!start_direction.has_value()) {
340 start_direction = cubic->GetStartDirection();
345 if (component_i == path_components.size() - 1) {
351 polyline.contours.back().start_direction =
352 start_direction.value_or(
Vector2(0, -1));
353 start_direction = std::nullopt;
358 &path_points[storage_offset]);
361 .is_closed = contour->IsClosed(),
362 .start_direction =
Vector2(0, -1),
363 .components = poly_components
366 polyline.points->push_back(contour->destination);
380 polyline.contours.back().start_direction =
381 start_direction.value_or(
Vector2(0, -1));
388 return data_->bounds;
394 if (!bounds.has_value()) {
397 return bounds->TransformBounds(
transform);