Flutter Impeller
tessellator_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/testing/testing.h"
6 #include "gtest/gtest.h"
7 
12 
13 namespace impeller {
14 namespace testing {
15 
16 TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
17  // Zero points.
18  {
19  Tessellator t;
20  auto path = PathBuilder{}.TakePath(FillType::kOdd);
22  path, 1.0f,
23  [](const float* vertices, size_t vertices_count,
24  const uint16_t* indices, size_t indices_count) { return true; });
25 
26  ASSERT_EQ(result, Tessellator::Result::kInputError);
27  }
28 
29  // One point.
30  {
31  Tessellator t;
32  auto path = PathBuilder{}.LineTo({0, 0}).TakePath(FillType::kOdd);
34  path, 1.0f,
35  [](const float* vertices, size_t vertices_count,
36  const uint16_t* indices, size_t indices_count) { return true; });
37 
38  ASSERT_EQ(result, Tessellator::Result::kSuccess);
39  }
40 
41  // Two points.
42  {
43  Tessellator t;
44  auto path = PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath(FillType::kOdd);
46  path, 1.0f,
47  [](const float* vertices, size_t vertices_count,
48  const uint16_t* indices, size_t indices_count) { return true; });
49 
50  ASSERT_EQ(result, Tessellator::Result::kSuccess);
51  }
52 
53  // Many points.
54  {
55  Tessellator t;
56  PathBuilder builder;
57  for (int i = 0; i < 1000; i++) {
58  auto coord = i * 1.0f;
59  builder.AddLine({coord, coord}, {coord + 1, coord + 1});
60  }
61  auto path = builder.TakePath(FillType::kOdd);
63  path, 1.0f,
64  [](const float* vertices, size_t vertices_count,
65  const uint16_t* indices, size_t indices_count) { return true; });
66 
67  ASSERT_EQ(result, Tessellator::Result::kSuccess);
68  }
69 
70  // Closure fails.
71  {
72  Tessellator t;
73  auto path = PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath(FillType::kOdd);
75  path, 1.0f,
76  [](const float* vertices, size_t vertices_count,
77  const uint16_t* indices, size_t indices_count) { return false; });
78 
79  ASSERT_EQ(result, Tessellator::Result::kInputError);
80  }
81 
82  // More than uint16 points, odd fill mode.
83  {
84  Tessellator t;
85  PathBuilder builder = {};
86  for (auto i = 0; i < 1000; i++) {
87  builder.AddCircle(Point(i, i), 4);
88  }
89  auto path = builder.TakePath(FillType::kOdd);
90  bool no_indices = false;
91  size_t count = 0u;
93  path, 1.0f,
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;
98  return true;
99  });
100 
101  ASSERT_TRUE(no_indices);
102  ASSERT_TRUE(count >= USHRT_MAX);
103  ASSERT_EQ(result, Tessellator::Result::kSuccess);
104  }
105 }
106 
107 TEST(TessellatorTest, TessellateConvex) {
108  {
109  Tessellator t;
110  // Sanity check simple rectangle.
111  auto pts = t.TessellateConvex(
112  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 10, 10)).TakePath(), 1.0);
113 
114  std::vector<Point> expected = {{0, 0}, {10, 0}, {0, 10}, {10, 10}};
115  EXPECT_EQ(pts, expected);
116  }
117 
118  {
119  Tessellator t;
120  auto pts = t.TessellateConvex(PathBuilder{}
121  .AddRect(Rect::MakeLTRB(0, 0, 10, 10))
122  .AddRect(Rect::MakeLTRB(20, 20, 30, 30))
123  .TakePath(),
124  1.0);
125 
126  std::vector<Point> expected = {{0, 0}, {10, 0}, {0, 10}, {10, 10},
127  {10, 10}, {20, 20}, {20, 20}, {30, 20},
128  {20, 30}, {30, 30}};
129  EXPECT_EQ(pts, expected);
130  }
131 
132  {
133  Tessellator t;
134  PathBuilder builder{};
135  auto path = builder.MoveTo({10, 10})
136  .Close()
137  .AddRect(Rect::MakeLTRB(0, 0, 100, 100))
138  .TakePath();
139  // Verify no crash.
140  t.TessellateConvex(path, 1.0);
141  }
142 }
143 
144 TEST(TessellatorTest, CircleVertexCounts) {
145  auto tessellator = std::make_shared<Tessellator>();
146 
147  auto test = [&tessellator](const Matrix& transform, Scalar radius) {
148  auto generator = tessellator->FilledCircle(transform, {}, radius);
149  size_t quadrant_divisions = generator.GetVertexCount() / 4;
150 
151  // Confirm the approximation error is within the currently accepted
152  // |kCircleTolerance| value advertised by |CircleTessellator|.
153  // (With an additional 1% tolerance for floating point rounding.)
154  double angle = kPiOver2 / quadrant_divisions;
155  Point first = {radius, 0};
156  Point next = {static_cast<Scalar>(cos(angle) * radius),
157  static_cast<Scalar>(sin(angle) * radius)};
158  Point midpoint = (first + next) * 0.5;
159  EXPECT_GE(midpoint.GetLength(),
160  radius - Tessellator::kCircleTolerance * 1.01)
161  << ", transform = " << transform << ", radius = " << radius
162  << ", divisions = " << quadrant_divisions;
163  };
164 
165  test({}, 0.0);
166  test({}, 0.9);
167  test({}, 1.0);
168  test({}, 1.9);
169  test(Matrix::MakeScale(Vector2(2.0, 2.0)), 0.95);
170  test({}, 2.0);
171  test(Matrix::MakeScale(Vector2(2.0, 2.0)), 1.0);
172  test({}, 11.9);
173  test({}, 12.0);
174  test({}, 35.9);
175  for (int i = 36; i < 10000; i += 4) {
176  test({}, i);
177  }
178 }
179 
180 TEST(TessellatorTest, FilledCircleTessellationVertices) {
181  auto tessellator = std::make_shared<Tessellator>();
182 
183  auto test = [&tessellator](const Matrix& transform, const Point& center,
184  Scalar radius) {
185  auto generator = tessellator->FilledCircle(transform, center, radius);
186  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
187 
188  auto vertex_count = generator.GetVertexCount();
189  auto vertices = std::vector<Point>();
190  generator.GenerateVertices([&vertices](const Point& p) { //
191  vertices.push_back(p);
192  });
193  EXPECT_EQ(vertices.size(), vertex_count);
194  ASSERT_EQ(vertex_count % 4, 0u);
195 
196  auto quadrant_count = vertex_count / 4;
197  for (size_t i = 0; i < quadrant_count; i++) {
198  double angle = kPiOver2 * i / (quadrant_count - 1);
199  double degrees = angle * 180.0 / kPi;
200  double rsin = sin(angle) * radius;
201  double rcos = cos(angle) * radius;
202  EXPECT_POINT_NEAR(vertices[i * 2],
203  Point(center.x - rcos, center.y + rsin))
204  << "vertex " << i << ", angle = " << degrees << std::endl;
205  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
206  Point(center.x - rcos, center.y - rsin))
207  << "vertex " << i << ", angle = " << degrees << std::endl;
208  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
209  Point(center.x + rcos, center.y - rsin))
210  << "vertex " << i << ", angle = " << degrees << std::endl;
211  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
212  Point(center.x + rcos, center.y + rsin))
213  << "vertex " << i << ", angle = " << degrees << std::endl;
214  }
215  };
216 
217  test({}, {}, 2.0);
218  test({}, {10, 10}, 2.0);
219  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {}, 2.0);
220  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {}, 1000.0);
221 }
222 
223 TEST(TessellatorTest, StrokedCircleTessellationVertices) {
224  auto tessellator = std::make_shared<Tessellator>();
225 
226  auto test = [&tessellator](const Matrix& transform, const Point& center,
227  Scalar radius, Scalar half_width) {
228  ASSERT_GT(radius, half_width);
229  auto generator =
230  tessellator->StrokedCircle(transform, center, radius, half_width);
231  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
232 
233  auto vertex_count = generator.GetVertexCount();
234  auto vertices = std::vector<Point>();
235  generator.GenerateVertices([&vertices](const Point& p) { //
236  vertices.push_back(p);
237  });
238  EXPECT_EQ(vertices.size(), vertex_count);
239  ASSERT_EQ(vertex_count % 4, 0u);
240 
241  auto quadrant_count = vertex_count / 8;
242 
243  // Test outer points first
244  for (size_t i = 0; i < quadrant_count; i++) {
245  double angle = kPiOver2 * i / (quadrant_count - 1);
246  double degrees = angle * 180.0 / kPi;
247  double rsin = sin(angle) * (radius + half_width);
248  double rcos = cos(angle) * (radius + half_width);
249  EXPECT_POINT_NEAR(vertices[i * 2],
250  Point(center.x - rcos, center.y - rsin))
251  << "vertex " << i << ", angle = " << degrees << std::endl;
252  EXPECT_POINT_NEAR(vertices[quadrant_count * 2 + i * 2],
253  Point(center.x + rsin, center.y - rcos))
254  << "vertex " << i << ", angle = " << degrees << std::endl;
255  EXPECT_POINT_NEAR(vertices[quadrant_count * 4 + i * 2],
256  Point(center.x + rcos, center.y + rsin))
257  << "vertex " << i << ", angle = " << degrees << std::endl;
258  EXPECT_POINT_NEAR(vertices[quadrant_count * 6 + i * 2],
259  Point(center.x - rsin, center.y + rcos))
260  << "vertex " << i << ", angle = " << degrees << std::endl;
261  }
262 
263  // Then test innerer points
264  for (size_t i = 0; i < quadrant_count; i++) {
265  double angle = kPiOver2 * i / (quadrant_count - 1);
266  double degrees = angle * 180.0 / kPi;
267  double rsin = sin(angle) * (radius - half_width);
268  double rcos = cos(angle) * (radius - half_width);
269  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
270  Point(center.x - rcos, center.y - rsin))
271  << "vertex " << i << ", angle = " << degrees << std::endl;
272  EXPECT_POINT_NEAR(vertices[quadrant_count * 2 + i * 2 + 1],
273  Point(center.x + rsin, center.y - rcos))
274  << "vertex " << i << ", angle = " << degrees << std::endl;
275  EXPECT_POINT_NEAR(vertices[quadrant_count * 4 + i * 2 + 1],
276  Point(center.x + rcos, center.y + rsin))
277  << "vertex " << i << ", angle = " << degrees << std::endl;
278  EXPECT_POINT_NEAR(vertices[quadrant_count * 6 + i * 2 + 1],
279  Point(center.x - rsin, center.y + rcos))
280  << "vertex " << i << ", angle = " << degrees << std::endl;
281  }
282  };
283 
284  test({}, {}, 2.0, 1.0);
285  test({}, {}, 2.0, 0.5);
286  test({}, {10, 10}, 2.0, 1.0);
287  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {}, 2.0, 1.0);
288  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {}, 1000.0, 10.0);
289 }
290 
291 TEST(TessellatorTest, RoundCapLineTessellationVertices) {
292  auto tessellator = std::make_shared<Tessellator>();
293 
294  auto test = [&tessellator](const Matrix& transform, const Point& p0,
295  const Point& p1, Scalar radius) {
296  auto generator = tessellator->RoundCapLine(transform, p0, p1, radius);
297  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
298 
299  auto vertex_count = generator.GetVertexCount();
300  auto vertices = std::vector<Point>();
301  generator.GenerateVertices([&vertices](const Point& p) { //
302  vertices.push_back(p);
303  });
304  EXPECT_EQ(vertices.size(), vertex_count);
305  ASSERT_EQ(vertex_count % 4, 0u);
306 
307  Point along = p1 - p0;
308  Scalar length = along.GetLength();
309  if (length > 0) {
310  along *= radius / length;
311  } else {
312  along = {radius, 0};
313  }
314  Point across = {-along.y, along.x};
315 
316  auto quadrant_count = vertex_count / 4;
317  for (size_t i = 0; i < quadrant_count; i++) {
318  double angle = kPiOver2 * i / (quadrant_count - 1);
319  double degrees = angle * 180.0 / kPi;
320  Point relative_along = along * cos(angle);
321  Point relative_across = across * sin(angle);
322  EXPECT_POINT_NEAR(vertices[i * 2], //
323  p0 - relative_along + relative_across)
324  << "vertex " << i << ", angle = " << degrees << ", " //
325  << "line = " << p0 << " => " << p1 << ", " //
326  << "radius = " << radius << std::endl;
327  EXPECT_POINT_NEAR(vertices[i * 2 + 1], //
328  p0 - relative_along - relative_across)
329  << "vertex " << i << ", angle = " << degrees << ", " //
330  << "line = " << p0 << " => " << p1 << ", " //
331  << "radius = " << radius << std::endl;
332  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1], //
333  p1 + relative_along - relative_across)
334  << "vertex " << i << ", angle = " << degrees << ", " //
335  << "line = " << p0 << " => " << p1 << ", " //
336  << "radius = " << radius << std::endl;
337  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2], //
338  p1 + relative_along + relative_across)
339  << "vertex " << i << ", angle = " << degrees << ", " //
340  << "line = " << p0 << " => " << p1 << ", " //
341  << "radius = " << radius << std::endl;
342  }
343  };
344 
345  // Empty line should actually use the circle generator, but its
346  // results should match the same math as the round cap generator.
347  test({}, {0, 0}, {0, 0}, 10);
348 
349  test({}, {0, 0}, {10, 0}, 2);
350  test({}, {10, 0}, {0, 0}, 2);
351  test({}, {0, 0}, {10, 10}, 2);
352 
353  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {0, 0}, {10, 0}, 2);
354  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {10, 0}, {0, 0}, 2);
355  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {0, 0}, {10, 10}, 2);
356 
357  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {0, 0}, {10, 0}, 2);
358  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {10, 0}, {0, 0}, 2);
359  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {0, 0}, {10, 10}, 2);
360 }
361 
362 TEST(TessellatorTest, FilledEllipseTessellationVertices) {
363  auto tessellator = std::make_shared<Tessellator>();
364 
365  auto test = [&tessellator](const Matrix& transform, const Rect& bounds) {
366  auto center = bounds.GetCenter();
367  auto half_size = bounds.GetSize() * 0.5f;
368 
369  auto generator = tessellator->FilledEllipse(transform, bounds);
370  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
371 
372  auto vertex_count = generator.GetVertexCount();
373  auto vertices = std::vector<Point>();
374  generator.GenerateVertices([&vertices](const Point& p) { //
375  vertices.push_back(p);
376  });
377  EXPECT_EQ(vertices.size(), vertex_count);
378  ASSERT_EQ(vertex_count % 4, 0u);
379 
380  auto quadrant_count = vertex_count / 4;
381  for (size_t i = 0; i < quadrant_count; i++) {
382  double angle = kPiOver2 * i / (quadrant_count - 1);
383  double degrees = angle * 180.0 / kPi;
384  double rcos = cos(angle) * half_size.width;
385  double rsin = sin(angle) * half_size.height;
386  EXPECT_POINT_NEAR(vertices[i * 2],
387  Point(center.x - rcos, center.y + rsin))
388  << "vertex " << i << ", angle = " << degrees << ", " //
389  << "bounds = " << bounds << std::endl;
390  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
391  Point(center.x - rcos, center.y - rsin))
392  << "vertex " << i << ", angle = " << degrees << ", " //
393  << "bounds = " << bounds << std::endl;
394  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
395  Point(center.x + rcos, center.y - rsin))
396  << "vertex " << i << ", angle = " << degrees << ", " //
397  << "bounds = " << bounds << std::endl;
398  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
399  Point(center.x + rcos, center.y + rsin))
400  << "vertex " << i << ", angle = " << degrees << ", " //
401  << "bounds = " << bounds << std::endl;
402  }
403  };
404 
405  // Square bounds should actually use the circle generator, but its
406  // results should match the same math as the ellipse generator.
407  test({}, Rect::MakeXYWH(0, 0, 2, 2));
408 
409  test({}, Rect::MakeXYWH(0, 0, 2, 3));
410  test({}, Rect::MakeXYWH(0, 0, 3, 2));
411  test({}, Rect::MakeXYWH(5, 10, 2, 3));
412  test({}, Rect::MakeXYWH(16, 7, 3, 2));
413  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 3, 2));
414  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 2, 3));
415  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
416  Rect::MakeXYWH(5000, 10000, 3000, 2000));
417  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
418  Rect::MakeXYWH(5000, 10000, 2000, 3000));
419 }
420 
421 TEST(TessellatorTest, FilledRoundRectTessellationVertices) {
422  auto tessellator = std::make_shared<Tessellator>();
423 
424  auto test = [&tessellator](const Matrix& transform, const Rect& bounds,
425  const Size& radii) {
426  FML_DCHECK(radii.width * 2 <= bounds.GetWidth()) << radii << bounds;
427  FML_DCHECK(radii.height * 2 <= bounds.GetHeight()) << radii << bounds;
428 
429  Scalar middle_left = bounds.GetX() + radii.width;
430  Scalar middle_top = bounds.GetY() + radii.height;
431  Scalar middle_right = bounds.GetX() + bounds.GetWidth() - radii.width;
432  Scalar middle_bottom = bounds.GetY() + bounds.GetHeight() - radii.height;
433 
434  auto generator = tessellator->FilledRoundRect(transform, bounds, radii);
435  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
436 
437  auto vertex_count = generator.GetVertexCount();
438  auto vertices = std::vector<Point>();
439  generator.GenerateVertices([&vertices](const Point& p) { //
440  vertices.push_back(p);
441  });
442  EXPECT_EQ(vertices.size(), vertex_count);
443  ASSERT_EQ(vertex_count % 4, 0u);
444 
445  auto quadrant_count = vertex_count / 4;
446  for (size_t i = 0; i < quadrant_count; i++) {
447  double angle = kPiOver2 * i / (quadrant_count - 1);
448  double degrees = angle * 180.0 / kPi;
449  double rcos = cos(angle) * radii.width;
450  double rsin = sin(angle) * radii.height;
451  EXPECT_POINT_NEAR(vertices[i * 2],
452  Point(middle_left - rcos, middle_bottom + rsin))
453  << "vertex " << i << ", angle = " << degrees << ", " //
454  << "bounds = " << bounds << std::endl;
455  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
456  Point(middle_left - rcos, middle_top - rsin))
457  << "vertex " << i << ", angle = " << degrees << ", " //
458  << "bounds = " << bounds << std::endl;
459  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
460  Point(middle_right + rcos, middle_top - rsin))
461  << "vertex " << i << ", angle = " << degrees << ", " //
462  << "bounds = " << bounds << std::endl;
463  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
464  Point(middle_right + rcos, middle_bottom + rsin))
465  << "vertex " << i << ", angle = " << degrees << ", " //
466  << "bounds = " << bounds << std::endl;
467  }
468  };
469 
470  // Both radii spanning the bounds should actually use the circle/ellipse
471  // generator, but their results should match the same math as the round
472  // rect generator.
473  test({}, Rect::MakeXYWH(0, 0, 20, 20), {10, 10});
474 
475  // One radius spanning the bounds, but not the other will not match the
476  // round rect math if the generator transfers to circle/ellipse
477  test({}, Rect::MakeXYWH(0, 0, 20, 20), {10, 5});
478  test({}, Rect::MakeXYWH(0, 0, 20, 20), {5, 10});
479 
480  test({}, Rect::MakeXYWH(0, 0, 20, 30), {2, 2});
481  test({}, Rect::MakeXYWH(0, 0, 30, 20), {2, 2});
482  test({}, Rect::MakeXYWH(5, 10, 20, 30), {2, 3});
483  test({}, Rect::MakeXYWH(16, 7, 30, 20), {2, 3});
484  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 30, 20),
485  {2, 3});
486  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 20, 30),
487  {2, 3});
488  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
489  Rect::MakeXYWH(5000, 10000, 3000, 2000), {50, 70});
490  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
491  Rect::MakeXYWH(5000, 10000, 2000, 3000), {50, 70});
492 }
493 
494 TEST(TessellatorTest, EarlyReturnEmptyConvexShape) {
495  // This path is not technically empty (it has a size in one dimension),
496  // but is otherwise completely flat.
497  auto tessellator = std::make_shared<Tessellator>();
498  PathBuilder builder;
499  builder.MoveTo({0, 0});
500  builder.MoveTo({10, 10}, /*relative=*/true);
501 
502  auto points = tessellator->TessellateConvex(builder.TakePath(), 3.0);
503 
504  EXPECT_TRUE(points.empty());
505 }
506 
507 #if !NDEBUG
508 TEST(TessellatorTest, ChecksConcurrentPolylineUsage) {
509  auto tessellator = std::make_shared<Tessellator>();
510  PathBuilder builder;
511  builder.AddLine({0, 0}, {100, 100});
512  auto path = builder.TakePath();
513 
514  auto polyline = tessellator->CreateTempPolyline(path, 0.1);
515  EXPECT_DEBUG_DEATH(tessellator->CreateTempPolyline(path, 0.1),
516  "point_buffer_");
517 }
518 #endif // NDEBUG
519 
520 } // namespace testing
521 } // namespace impeller
path.h
polyline
const Path::Polyline & polyline
Definition: stroke_path_geometry.cc:300
impeller::TPoint::y
Type y
Definition: point.h:31
impeller::Scalar
float Scalar
Definition: scalar.h:18
geometry_asserts.h
impeller::FillType::kOdd
@ kOdd
impeller::TRect< Scalar >::MakeXYWH
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition: rect.h:136
impeller::Tessellator
A utility that generates triangles of the specified fill type given a polyline. This happens on the C...
Definition: tessellator.h:33
impeller::Tessellator::Result::kInputError
@ kInputError
impeller::PathBuilder
Definition: path_builder.h:14
impeller::Vector2
Point Vector2
Definition: point.h:320
EXPECT_POINT_NEAR
#define EXPECT_POINT_NEAR(a, b)
Definition: geometry_asserts.h:172
impeller::kPi
constexpr float kPi
Definition: constants.h:26
impeller::PathBuilder::AddRect
PathBuilder & AddRect(Rect rect)
Definition: path_builder.cc:112
impeller::kPiOver2
constexpr float kPiOver2
Definition: constants.h:32
tessellator.h
path_builder.h
impeller::TSize< Scalar >
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::Point
TPoint< Scalar > Point
Definition: point.h:316
impeller::Tessellator::TessellateConvex
std::vector< Point > TessellateConvex(const Path &path, Scalar tolerance)
Given a convex path, create a triangle fan structure.
Definition: tessellator.cc:179
impeller::testing::TEST
TEST(CanvasRecorder, Save)
Definition: canvas_recorder_unittests.cc:65
impeller::PathBuilder::LineTo
PathBuilder & LineTo(Point point, bool relative=false)
Insert a line from the current position to point.
Definition: path_builder.cc:47
impeller::Tessellator::Result::kSuccess
@ kSuccess
impeller::PathBuilder::AddLine
PathBuilder & AddLine(const Point &p1, const Point &p2)
Move to point p1, then insert a line from p1 to p2.
Definition: path_builder.cc:419
impeller::PathBuilder::TakePath
Path TakePath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:22
impeller::TPoint::x
Type x
Definition: point.h:30
impeller::Close
void Close(PathBuilder *builder)
Definition: tessellator.cc:36
impeller::TPoint::GetLength
constexpr Type GetLength() const
Definition: point.h:206
impeller::TPoint< Scalar >
impeller::Tessellator::Tessellate
Tessellator::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.
Definition: tessellator.cc:58
impeller::PathBuilder::MoveTo
PathBuilder & MoveTo(Point point, bool relative=false)
Definition: path_builder.cc:33
impeller::Tessellator::kCircleTolerance
static constexpr Scalar kCircleTolerance
The pixel tolerance used by the algorighm to determine how many divisions to create for a circle.
Definition: tessellator.h:228
impeller::PathBuilder::AddCircle
PathBuilder & AddCircle(const Point &center, Scalar radius)
Definition: path_builder.cc:130
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
impeller::Tessellator::Result
Result
Definition: tessellator.h:72
impeller
Definition: aiks_blur_unittests.cc:20
impeller::Matrix::MakeScale
static constexpr Matrix MakeScale(const Vector3 &s)
Definition: matrix.h:104
impeller::TRect
Definition: rect.h:122
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37