7 #include "third_party/libtess2/Include/tesselator.h"
11 static void*
HeapAlloc(
void* userData,
unsigned int size) {
15 static void*
HeapRealloc(
void* userData,
void* ptr,
unsigned int size) {
16 return realloc(ptr, size);
19 static void HeapFree(
void* userData,
void* ptr) {
40 c_tessellator_ = std::move(tessellator);
49 return TESS_WINDING_ODD;
51 return TESS_WINDING_NONZERO;
53 return TESS_WINDING_ODD;
64 std::unique_ptr<std::vector<Point>> point_buffer =
65 std::make_unique<std::vector<Point>>();
74 auto tessellator = c_tessellator_.get();
79 constexpr
int kVertexSize = 2;
80 constexpr
int kPolygonSize = 3;
85 static_assert(
sizeof(
Point) == 2 *
sizeof(
float));
86 for (
size_t contour_i = 0; contour_i <
polyline.contours.size();
88 size_t start_point_index, end_point_index;
89 std::tie(start_point_index, end_point_index) =
90 polyline.GetContourPointBounds(contour_i);
92 ::tessAddContour(tessellator,
94 polyline.points->data() + start_point_index,
96 end_point_index - start_point_index
103 auto result = ::tessTesselate(tessellator,
115 int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;
122 if (element_item_count < USHRT_MAX) {
123 int vertex_item_count = tessGetVertexCount(tessellator);
124 auto vertices = tessGetVertices(tessellator);
125 auto elements = tessGetElements(tessellator);
129 std::vector<uint16_t> indices(element_item_count);
130 for (
int i = 0; i < element_item_count; i++) {
131 indices[i] =
static_cast<uint16_t
>(elements[i]);
133 if (!callback(vertices, vertex_item_count, indices.data(),
134 element_item_count)) {
138 std::vector<Point> points;
139 std::vector<float>
data;
141 int vertex_item_count = tessGetVertexCount(tessellator) * kVertexSize;
142 auto vertices = tessGetVertices(tessellator);
143 points.reserve(vertex_item_count);
144 for (
int i = 0; i < vertex_item_count; i += 2) {
145 points.emplace_back(vertices[i], vertices[i + 1]);
148 int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;
149 auto elements = tessGetElements(tessellator);
150 data.reserve(element_item_count);
151 for (
int i = 0; i < element_item_count; i++) {
152 data.emplace_back(points[elements[i]].
x);
153 data.emplace_back(points[elements[i]].y);
155 if (!callback(
data.data(), element_item_count,
nullptr, 0u)) {
164 if (tessellator !=
nullptr) {
165 ::tessDeleteTess(tessellator);
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
FillType GetFillType() const
Polyline CreatePolyline(Scalar scale, Polyline::PointBufferPtr point_buffer=std::make_unique< std::vector< Point >>(), Polyline::ReclaimPointBufferCallback reclaim=nullptr) const
std::function< bool(const float *vertices, size_t vertices_count, const uint16_t *indices, size_t indices_count)> BuilderCallback
A callback that returns the results of the tessellation.
TessellatorLibtess::Result Tessellate(const Path &path, Scalar tolerance, const BuilderCallback &callback)
Generates filled triangles from the path. A callback is invoked once for the entire tessellation.
static void * HeapRealloc(void *userData, void *ptr, unsigned int size)
void DestroyTessellator(TESStesselator *tessellator)
static void * HeapAlloc(void *userData, unsigned int size)
std::unique_ptr< TESStesselator, decltype(&DestroyTessellator)> CTessellator
static int ToTessWindingRule(FillType fill_type)
static void HeapFree(void *userData, void *ptr)
static const TESSalloc kAlloc
const Path::Polyline & polyline
std::shared_ptr< const fml::Mapping > data