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]);
107 auto& path_components = data_->components;
108 auto& path_points = data_->points;
109 bool started_contour =
false;
110 bool first_point =
true;
112 for (
size_t component_i = 0; component_i < path_components.size();
114 const auto& path_component = path_components[component_i];
115 switch (path_component.type) {
119 &path_points[path_component.index]);
130 &path_points[path_component.index]);
141 &path_points[path_component.index]);
150 if (component_i == path_components.size() - 1) {
160 if (started_contour) {
163 started_contour =
true;
167 if (started_contour) {
174 auto& components = data_->components;
176 if (index >= components.size()) {
184 auto&
points = data_->points;
185 auto point_index = components[index].index;
193 auto& components = data_->components;
195 if (index >= components.size()) {
203 auto&
points = data_->points;
204 auto point_index = components[index].index;
212 auto& components = data_->components;
214 if (index >= components.size()) {
222 auto&
points = data_->points;
223 auto point_index = components[index].index;
231 auto& components = data_->components;
233 if (index >= components.size()) {
241 move = data_->contours[components[index].index];
247 :
points(
std::move(point_buffer)), reclaim_points_(
std::move(reclaim)) {
252 points = std::move(other.points);
253 reclaim_points_ = std::move(other.reclaim_points_);
254 contours = std::move(other.contours);
258 if (reclaim_points_) {
260 reclaim_points_(std::move(
points));
270 auto& path_components = data_->components;
271 auto& path_points = data_->points;
273 auto get_path_component = [&path_components, &path_points](
275 if (component_i >= path_components.size()) {
276 return std::monostate{};
278 const auto& component = path_components[component_i];
279 switch (component.type) {
282 &path_points[component.index]);
285 &path_points[component.index]);
288 &path_points[component.index]);
290 return std::monostate{};
294 auto compute_contour_start_direction =
295 [&get_path_component](
size_t current_path_component_index) {
296 size_t next_component_index = current_path_component_index + 1;
297 while (!std::holds_alternative<std::monostate>(
298 get_path_component(next_component_index))) {
299 auto next_component = get_path_component(next_component_index);
302 if (maybe_vector.has_value()) {
303 return maybe_vector.value();
305 next_component_index++;
311 std::vector<PolylineContour::Component> poly_components;
312 std::optional<size_t> previous_path_component_index;
313 auto end_contour = [&
polyline, &previous_path_component_index,
314 &get_path_component, &poly_components]() {
321 if (!previous_path_component_index.has_value()) {
327 contour.components = poly_components;
328 poly_components.clear();
330 size_t previous_index = previous_path_component_index.value();
331 while (!std::holds_alternative<std::monostate>(
332 get_path_component(previous_index))) {
333 auto previous_component = get_path_component(previous_index);
336 if (maybe_vector.has_value()) {
337 contour.end_direction = maybe_vector.value();
340 if (previous_index == 0) {
348 for (
size_t component_i = 0; component_i < path_components.size();
350 const auto& path_component = path_components[component_i];
351 switch (path_component.type) {
353 poly_components.push_back({
354 .component_start_index =
polyline.points->size() - 1,
358 &path_points[path_component.index])
359 ->AppendPolylinePoints(*
polyline.points);
360 previous_path_component_index = component_i;
363 poly_components.push_back({
364 .component_start_index =
polyline.points->size() - 1,
368 &path_points[path_component.index])
370 previous_path_component_index = component_i;
373 poly_components.push_back({
374 .component_start_index =
polyline.points->size() - 1,
378 &path_points[path_component.index])
380 previous_path_component_index = component_i;
383 if (component_i == path_components.size() - 1) {
390 Vector2 start_direction = compute_contour_start_direction(component_i);
391 const auto&
contour = data_->contours[path_component.index];
393 .is_closed =
contour.is_closed,
394 .start_direction = start_direction,
395 .components = poly_components});
406 return data_->bounds;
412 if (!
bounds.has_value()) {
static const int points[]
FillType GetFillType() const
size_t GetComponentCount(std::optional< ComponentType > type={}) const
bool GetContourComponentAtIndex(size_t index, ContourComponent &contour) const
void EnumerateComponents(const Applier< LinearPathComponent > &linear_applier, const Applier< QuadraticPathComponent > &quad_applier, const Applier< CubicPathComponent > &cubic_applier, const Applier< ContourComponent > &contour_applier) const
std::optional< Rect > GetTransformedBoundingBox(const Matrix &transform) const
std::function< void(size_t index, const T &component)> Applier
bool GetLinearComponentAtIndex(size_t index, LinearPathComponent &linear) const
void WritePolyline(Scalar scale, VertexWriter &writer) const
bool GetQuadraticComponentAtIndex(size_t index, QuadraticPathComponent &quadratic) const
bool GetCubicComponentAtIndex(size_t index, CubicPathComponent &cubic) const
Polyline CreatePolyline(Scalar scale, Polyline::PointBufferPtr point_buffer=std::make_unique< std::vector< Point > >(), Polyline::ReclaimPointBufferCallback reclaim=nullptr) const
std::optional< Rect > GetBoundingBox() const
An interface for generating a multi contour polyline as a triangle strip.
#define FML_DCHECK(condition)
Optional< SkRect > bounds
struct PathData * Data(SkPath *path)
std::variant< std::monostate, const LinearPathComponent *, const QuadraticPathComponent *, const CubicPathComponent * > PathComponentVariant
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
const Path::Polyline & polyline
A 4x4 matrix using column-major storage.
Polyline(PointBufferPtr point_buffer, ReclaimPointBufferCallback reclaim)
std::vector< PolylineContour > contours
std::function< void(PointBufferPtr)> ReclaimPointBufferCallback
std::unique_ptr< std::vector< Point > > PointBufferPtr
std::tuple< size_t, size_t > GetContourPointBounds(size_t contour_index) const
void ToLinearPathComponents(Scalar scale_factor, const PointProc &proc) const
std::shared_ptr< const fml::Mapping > data
static sk_sp< SkShader > linear(sk_sp< SkShader > shader)