5 #include "flutter/testing/testing.h"
6 #include "gtest/gtest.h"
16 TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
23 [](
const float* vertices,
size_t vertices_count,
24 const uint16_t* indices,
size_t indices_count) {
return true; });
35 [](
const float* vertices,
size_t vertices_count,
36 const uint16_t* indices,
size_t indices_count) {
return true; });
47 [](
const float* vertices,
size_t vertices_count,
48 const uint16_t* indices,
size_t indices_count) {
return true; });
57 for (
int i = 0; i < 1000; i++) {
58 auto coord = i * 1.0f;
59 builder.
AddLine({coord, coord}, {coord + 1, coord + 1});
64 [](
const float* vertices,
size_t vertices_count,
65 const uint16_t* indices,
size_t indices_count) {
return true; });
76 [](
const float* vertices,
size_t vertices_count,
77 const uint16_t* indices,
size_t indices_count) {
return false; });
86 for (
auto i = 0; i < 1000; i++) {
90 bool no_indices =
false;
94 [&no_indices, &count](
const float* vertices,
size_t vertices_count,
95 const uint16_t* indices,
size_t indices_count) {
96 no_indices = indices ==
nullptr;
97 count = vertices_count;
101 ASSERT_TRUE(no_indices);
102 ASSERT_TRUE(count >= USHRT_MAX);
107 TEST(TessellatorTest, TessellateConvex) {
114 std::vector<Point> expected = {{0, 0}, {10, 0}, {0, 10}, {10, 10}};
115 EXPECT_EQ(pts, expected);
126 std::vector<Point> expected = {{0, 0}, {10, 0}, {0, 10}, {10, 10},
127 {10, 10}, {20, 20}, {20, 20}, {30, 20},
129 EXPECT_EQ(pts, expected);
133 TEST(TessellatorTest, CircleVertexCounts) {
134 auto tessellator = std::make_shared<Tessellator>();
136 auto test = [&tessellator](
const Matrix& transform,
Scalar radius) {
137 auto generator = tessellator->FilledCircle(transform, {}, radius);
138 size_t quadrant_divisions = generator.GetVertexCount() / 4;
143 double angle =
kPiOver2 / quadrant_divisions;
144 Point first = {radius, 0};
145 Point next = {
static_cast<Scalar>(cos(angle) * radius),
146 static_cast<Scalar>(sin(angle) * radius)};
147 Point midpoint = (first + next) * 0.5;
150 <<
", transform = " << transform <<
", radius = " << radius
151 <<
", divisions = " << quadrant_divisions;
164 for (
int i = 36; i < 10000; i += 4) {
169 TEST(TessellatorTest, FilledCircleTessellationVertices) {
170 auto tessellator = std::make_shared<Tessellator>();
172 auto test = [&tessellator](
const Matrix& transform,
const Point& center,
174 auto generator = tessellator->FilledCircle(transform, center, radius);
177 auto vertex_count = generator.GetVertexCount();
178 auto vertices = std::vector<Point>();
179 generator.GenerateVertices([&vertices](
const Point& p) {
180 vertices.push_back(p);
182 EXPECT_EQ(vertices.size(), vertex_count);
183 ASSERT_EQ(vertex_count % 4, 0u);
185 auto quadrant_count = vertex_count / 4;
186 for (
size_t i = 0; i < quadrant_count; i++) {
187 double angle =
kPiOver2 * i / (quadrant_count - 1);
188 double degrees = angle * 180.0 /
kPi;
189 double rsin = sin(angle) * radius;
190 double rcos = cos(angle) * radius;
192 Point(center.x - rcos, center.y + rsin))
193 <<
"vertex " << i <<
", angle = " << degrees << std::endl;
195 Point(center.x - rcos, center.y - rsin))
196 <<
"vertex " << i <<
", angle = " << degrees << std::endl;
198 Point(center.x + rcos, center.y - rsin))
199 <<
"vertex " << i <<
", angle = " << degrees << std::endl;
201 Point(center.x + rcos, center.y + rsin))
202 <<
"vertex " << i <<
", angle = " << degrees << std::endl;
207 test({}, {10, 10}, 2.0);
212 TEST(TessellatorTest, StrokedCircleTessellationVertices) {
213 auto tessellator = std::make_shared<Tessellator>();
215 auto test = [&tessellator](
const Matrix& transform,
const Point& center,
217 ASSERT_GT(radius, half_width);
219 tessellator->StrokedCircle(transform, center, radius, half_width);
222 auto vertex_count = generator.GetVertexCount();
223 auto vertices = std::vector<Point>();
224 generator.GenerateVertices([&vertices](
const Point& p) {
225 vertices.push_back(p);
227 EXPECT_EQ(vertices.size(), vertex_count);
228 ASSERT_EQ(vertex_count % 4, 0u);
230 auto quadrant_count = vertex_count / 8;
233 for (
size_t i = 0; i < quadrant_count; i++) {
234 double angle =
kPiOver2 * i / (quadrant_count - 1);
235 double degrees = angle * 180.0 /
kPi;
236 double rsin = sin(angle) * (radius + half_width);
237 double rcos = cos(angle) * (radius + half_width);
239 Point(center.x - rcos, center.y - rsin))
240 <<
"vertex " << i <<
", angle = " << degrees << std::endl;
242 Point(center.x + rsin, center.y - rcos))
243 <<
"vertex " << i <<
", angle = " << degrees << std::endl;
245 Point(center.x + rcos, center.y + rsin))
246 <<
"vertex " << i <<
", angle = " << degrees << std::endl;
248 Point(center.x - rsin, center.y + rcos))
249 <<
"vertex " << i <<
", angle = " << degrees << std::endl;
253 for (
size_t i = 0; i < quadrant_count; i++) {
254 double angle =
kPiOver2 * i / (quadrant_count - 1);
255 double degrees = angle * 180.0 /
kPi;
256 double rsin = sin(angle) * (radius - half_width);
257 double rcos = cos(angle) * (radius - half_width);
259 Point(center.x - rcos, center.y - rsin))
260 <<
"vertex " << i <<
", angle = " << degrees << std::endl;
262 Point(center.x + rsin, center.y - rcos))
263 <<
"vertex " << i <<
", angle = " << degrees << std::endl;
265 Point(center.x + rcos, center.y + rsin))
266 <<
"vertex " << i <<
", angle = " << degrees << std::endl;
268 Point(center.x - rsin, center.y + rcos))
269 <<
"vertex " << i <<
", angle = " << degrees << std::endl;
273 test({}, {}, 2.0, 1.0);
274 test({}, {}, 2.0, 0.5);
275 test({}, {10, 10}, 2.0, 1.0);
280 TEST(TessellatorTest, RoundCapLineTessellationVertices) {
281 auto tessellator = std::make_shared<Tessellator>();
283 auto test = [&tessellator](
const Matrix& transform,
const Point& p0,
285 auto generator = tessellator->RoundCapLine(transform, p0, p1, radius);
288 auto vertex_count = generator.GetVertexCount();
289 auto vertices = std::vector<Point>();
290 generator.GenerateVertices([&vertices](
const Point& p) {
291 vertices.push_back(p);
293 EXPECT_EQ(vertices.size(), vertex_count);
294 ASSERT_EQ(vertex_count % 4, 0u);
296 Point along = p1 - p0;
299 along *= radius / length;
303 Point across = {-along.
y, along.
x};
305 auto quadrant_count = vertex_count / 4;
306 for (
size_t i = 0; i < quadrant_count; i++) {
307 double angle =
kPiOver2 * i / (quadrant_count - 1);
308 double degrees = angle * 180.0 /
kPi;
309 Point relative_along = along * cos(angle);
310 Point relative_across = across * sin(angle);
312 p0 - relative_along + relative_across)
313 <<
"vertex " << i <<
", angle = " << degrees <<
", "
314 <<
"line = " << p0 <<
" => " << p1 <<
", "
315 <<
"radius = " << radius << std::endl;
317 p0 - relative_along - relative_across)
318 <<
"vertex " << i <<
", angle = " << degrees <<
", "
319 <<
"line = " << p0 <<
" => " << p1 <<
", "
320 <<
"radius = " << radius << std::endl;
322 p1 + relative_along - relative_across)
323 <<
"vertex " << i <<
", angle = " << degrees <<
", "
324 <<
"line = " << p0 <<
" => " << p1 <<
", "
325 <<
"radius = " << radius << std::endl;
327 p1 + relative_along + relative_across)
328 <<
"vertex " << i <<
", angle = " << degrees <<
", "
329 <<
"line = " << p0 <<
" => " << p1 <<
", "
330 <<
"radius = " << radius << std::endl;
336 test({}, {0, 0}, {0, 0}, 10);
338 test({}, {0, 0}, {10, 0}, 2);
339 test({}, {10, 0}, {0, 0}, 2);
340 test({}, {0, 0}, {10, 10}, 2);
351 TEST(TessellatorTest, FilledEllipseTessellationVertices) {
352 auto tessellator = std::make_shared<Tessellator>();
354 auto test = [&tessellator](
const Matrix& transform,
const Rect& bounds) {
355 auto center = bounds.GetCenter();
356 auto half_size = bounds.GetSize() * 0.5f;
358 auto generator = tessellator->FilledEllipse(transform, bounds);
361 auto vertex_count = generator.GetVertexCount();
362 auto vertices = std::vector<Point>();
363 generator.GenerateVertices([&vertices](
const Point& p) {
364 vertices.push_back(p);
366 EXPECT_EQ(vertices.size(), vertex_count);
367 ASSERT_EQ(vertex_count % 4, 0u);
369 auto quadrant_count = vertex_count / 4;
370 for (
size_t i = 0; i < quadrant_count; i++) {
371 double angle =
kPiOver2 * i / (quadrant_count - 1);
372 double degrees = angle * 180.0 /
kPi;
373 double rcos = cos(angle) * half_size.width;
374 double rsin = sin(angle) * half_size.height;
376 Point(center.x - rcos, center.y + rsin))
377 <<
"vertex " << i <<
", angle = " << degrees <<
", "
378 <<
"bounds = " << bounds << std::endl;
380 Point(center.x - rcos, center.y - rsin))
381 <<
"vertex " << i <<
", angle = " << degrees <<
", "
382 <<
"bounds = " << bounds << std::endl;
384 Point(center.x + rcos, center.y - rsin))
385 <<
"vertex " << i <<
", angle = " << degrees <<
", "
386 <<
"bounds = " << bounds << std::endl;
388 Point(center.x + rcos, center.y + rsin))
389 <<
"vertex " << i <<
", angle = " << degrees <<
", "
390 <<
"bounds = " << bounds << std::endl;
410 TEST(TessellatorTest, FilledRoundRectTessellationVertices) {
411 auto tessellator = std::make_shared<Tessellator>();
413 auto test = [&tessellator](
const Matrix& transform,
const Rect& bounds,
415 FML_DCHECK(radii.width * 2 <= bounds.GetWidth()) << radii << bounds;
416 FML_DCHECK(radii.height * 2 <= bounds.GetHeight()) << radii << bounds;
418 Scalar middle_left = bounds.GetX() + radii.width;
419 Scalar middle_top = bounds.GetY() + radii.height;
420 Scalar middle_right = bounds.GetX() + bounds.GetWidth() - radii.width;
421 Scalar middle_bottom = bounds.GetY() + bounds.GetHeight() - radii.height;
423 auto generator = tessellator->FilledRoundRect(transform, bounds, radii);
426 auto vertex_count = generator.GetVertexCount();
427 auto vertices = std::vector<Point>();
428 generator.GenerateVertices([&vertices](
const Point& p) {
429 vertices.push_back(p);
431 EXPECT_EQ(vertices.size(), vertex_count);
432 ASSERT_EQ(vertex_count % 4, 0u);
434 auto quadrant_count = vertex_count / 4;
435 for (
size_t i = 0; i < quadrant_count; i++) {
436 double angle =
kPiOver2 * i / (quadrant_count - 1);
437 double degrees = angle * 180.0 /
kPi;
438 double rcos = cos(angle) * radii.width;
439 double rsin = sin(angle) * radii.height;
441 Point(middle_left - rcos, middle_bottom + rsin))
442 <<
"vertex " << i <<
", angle = " << degrees <<
", "
443 <<
"bounds = " << bounds << std::endl;
445 Point(middle_left - rcos, middle_top - rsin))
446 <<
"vertex " << i <<
", angle = " << degrees <<
", "
447 <<
"bounds = " << bounds << std::endl;
449 Point(middle_right + rcos, middle_top - rsin))
450 <<
"vertex " << i <<
", angle = " << degrees <<
", "
451 <<
"bounds = " << bounds << std::endl;
453 Point(middle_right + rcos, middle_bottom + rsin))
454 <<
"vertex " << i <<
", angle = " << degrees <<
", "
455 <<
"bounds = " << bounds << std::endl;
483 TEST(TessellatorTest, EarlyReturnEmptyConvexShape) {
486 auto tessellator = std::make_shared<Tessellator>();
489 builder.
MoveTo({10, 10},
true);
491 auto points = tessellator->TessellateConvex(builder.
TakePath(), 3.0);
493 EXPECT_TRUE(points.empty());
497 TEST(TessellatorTest, ChecksConcurrentPolylineUsage) {
498 auto tessellator = std::make_shared<Tessellator>();
500 builder.
AddLine({0, 0}, {100, 100});
503 auto polyline = tessellator->CreateTempPolyline(path, 0.1);
504 EXPECT_DEBUG_DEATH(tessellator->CreateTempPolyline(path, 0.1),