@@ -397,18 +397,93 @@ TEST(TessellatorTest, FilledEllipseTessellationVertices) {
397
397
398
398
// Square bounds should actually use the circle generator, but its
399
399
// results should match the same math as the ellipse generator.
400
- test ({}, Rect::MakeLTRB (0 , 0 , 2 , 2 ));
401
-
402
- test ({}, Rect::MakeLTRB (0 , 0 , 2 , 3 ));
403
- test ({}, Rect::MakeLTRB (0 , 0 , 3 , 2 ));
404
- test ({}, Rect::MakeLTRB (5 , 10 , 2 , 3 ));
405
- test ({}, Rect::MakeLTRB (16 , 7 , 3 , 2 ));
406
- test (Matrix::MakeScale ({500.0 , 500.0 , 0.0 }), Rect::MakeLTRB (5 , 10 , 3 , 2 ));
407
- test (Matrix::MakeScale ({500.0 , 500.0 , 0.0 }), Rect::MakeLTRB (5 , 10 , 2 , 3 ));
400
+ test ({}, Rect::MakeXYWH (0 , 0 , 2 , 2 ));
401
+
402
+ test ({}, Rect::MakeXYWH (0 , 0 , 2 , 3 ));
403
+ test ({}, Rect::MakeXYWH (0 , 0 , 3 , 2 ));
404
+ test ({}, Rect::MakeXYWH (5 , 10 , 2 , 3 ));
405
+ test ({}, Rect::MakeXYWH (16 , 7 , 3 , 2 ));
406
+ test (Matrix::MakeScale ({500.0 , 500.0 , 0.0 }), Rect::MakeXYWH (5 , 10 , 3 , 2 ));
407
+ test (Matrix::MakeScale ({500.0 , 500.0 , 0.0 }), Rect::MakeXYWH (5 , 10 , 2 , 3 ));
408
408
test (Matrix::MakeScale ({0.002 , 0.002 , 0.0 }),
409
- Rect::MakeLTRB (5000 , 10000 , 3000 , 2000 ));
409
+ Rect::MakeXYWH (5000 , 10000 , 3000 , 2000 ));
410
410
test (Matrix::MakeScale ({0.002 , 0.002 , 0.0 }),
411
- Rect::MakeLTRB (5000 , 10000 , 2000 , 3000 ));
411
+ Rect::MakeXYWH (5000 , 10000 , 2000 , 3000 ));
412
+ }
413
+
414
+ TEST (TessellatorTest, FilledRoundRectTessellationVertices) {
415
+ auto tessellator = std::make_shared<Tessellator>();
416
+
417
+ auto test = [&tessellator](const Matrix& transform, const Rect & bounds,
418
+ const Size & radii) {
419
+ FML_DCHECK (radii.width * 2 <= bounds.GetSize ().width ) << radii << bounds;
420
+ FML_DCHECK (radii.height * 2 <= bounds.GetSize ().height ) << radii << bounds;
421
+
422
+ Scalar middle_left = bounds.GetOrigin ().x + radii.width ;
423
+ Scalar middle_top = bounds.GetOrigin ().y + radii.height ;
424
+ Scalar middle_right =
425
+ bounds.GetOrigin ().x + bounds.GetSize ().width - radii.width ;
426
+ Scalar middle_bottom =
427
+ bounds.GetOrigin ().y + bounds.GetSize ().height - radii.height ;
428
+
429
+ auto generator = tessellator->FilledRoundRect (transform, bounds, radii);
430
+ EXPECT_EQ (generator.GetTriangleType (), PrimitiveType::kTriangleStrip );
431
+
432
+ auto vertex_count = generator.GetVertexCount ();
433
+ auto vertices = std::vector<Point >();
434
+ generator.GenerateVertices ([&vertices](const Point & p) { //
435
+ vertices.push_back (p);
436
+ });
437
+ EXPECT_EQ (vertices.size (), vertex_count);
438
+ ASSERT_EQ (vertex_count % 4 , 0u );
439
+
440
+ auto quadrant_count = vertex_count / 4 ;
441
+ for (size_t i = 0 ; i < quadrant_count; i++) {
442
+ double angle = kPiOver2 * i / (quadrant_count - 1 );
443
+ double degrees = angle * 180.0 / kPi ;
444
+ double rcos = cos (angle) * radii.width ;
445
+ double rsin = sin (angle) * radii.height ;
446
+ EXPECT_POINT_NEAR (vertices[i * 2 ],
447
+ Point (middle_left - rcos, middle_bottom + rsin))
448
+ << " vertex " << i << " , angle = " << degrees << " , " //
449
+ << " bounds = " << bounds << std::endl;
450
+ EXPECT_POINT_NEAR (vertices[i * 2 + 1 ],
451
+ Point (middle_left - rcos, middle_top - rsin))
452
+ << " vertex " << i << " , angle = " << degrees << " , " //
453
+ << " bounds = " << bounds << std::endl;
454
+ EXPECT_POINT_NEAR (vertices[vertex_count - i * 2 - 1 ],
455
+ Point (middle_right + rcos, middle_top - rsin))
456
+ << " vertex " << i << " , angle = " << degrees << " , " //
457
+ << " bounds = " << bounds << std::endl;
458
+ EXPECT_POINT_NEAR (vertices[vertex_count - i * 2 - 2 ],
459
+ Point (middle_right + rcos, middle_bottom + rsin))
460
+ << " vertex " << i << " , angle = " << degrees << " , " //
461
+ << " bounds = " << bounds << std::endl;
462
+ }
463
+ };
464
+
465
+ // Both radii spanning the bounds should actually use the circle/ellipse
466
+ // generator, but their results should match the same math as the round
467
+ // rect generator.
468
+ test ({}, Rect::MakeXYWH (0 , 0 , 20 , 20 ), {10 , 10 });
469
+
470
+ // One radius spanning the bounds, but not the other will not match the
471
+ // round rect math if the generator transfers to circle/ellipse
472
+ test ({}, Rect::MakeXYWH (0 , 0 , 20 , 20 ), {10 , 5 });
473
+ test ({}, Rect::MakeXYWH (0 , 0 , 20 , 20 ), {5 , 10 });
474
+
475
+ test ({}, Rect::MakeXYWH (0 , 0 , 20 , 30 ), {2 , 2 });
476
+ test ({}, Rect::MakeXYWH (0 , 0 , 30 , 20 ), {2 , 2 });
477
+ test ({}, Rect::MakeXYWH (5 , 10 , 20 , 30 ), {2 , 3 });
478
+ test ({}, Rect::MakeXYWH (16 , 7 , 30 , 20 ), {2 , 3 });
479
+ test (Matrix::MakeScale ({500.0 , 500.0 , 0.0 }), Rect::MakeXYWH (5 , 10 , 30 , 20 ),
480
+ {2 , 3 });
481
+ test (Matrix::MakeScale ({500.0 , 500.0 , 0.0 }), Rect::MakeXYWH (5 , 10 , 20 , 30 ),
482
+ {2 , 3 });
483
+ test (Matrix::MakeScale ({0.002 , 0.002 , 0.0 }),
484
+ Rect::MakeXYWH (5000 , 10000 , 3000 , 2000 ), {50 , 70 });
485
+ test (Matrix::MakeScale ({0.002 , 0.002 , 0.0 }),
486
+ Rect::MakeXYWH (5000 , 10000 , 2000 , 3000 ), {50 , 70 });
412
487
}
413
488
414
489
} // namespace testing
0 commit comments