@@ -397,18 +397,93 @@ TEST(TessellatorTest, FilledEllipseTessellationVertices) {
397397
398398 // Square bounds should actually use the circle generator, but its
399399 // 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 ));
408408 test (Matrix::MakeScale ({0.002 , 0.002 , 0.0 }),
409- Rect::MakeLTRB (5000 , 10000 , 3000 , 2000 ));
409+ Rect::MakeXYWH (5000 , 10000 , 3000 , 2000 ));
410410 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 });
412487}
413488
414489} // namespace testing
0 commit comments