@@ -184,7 +184,8 @@ static constexpr SkIRect TestLatticeSrcRect = {1, 1, 39, 39};
184184
185185static sk_sp<SkPicture> MakeTestPicture (int w, int h, SkColor color) {
186186 SkPictureRecorder recorder;
187- SkCanvas* cv = recorder.beginRecording (TestBounds);
187+ SkRTreeFactory rtree_factory;
188+ SkCanvas* cv = recorder.beginRecording (TestBounds, &rtree_factory);
188189 SkPaint paint;
189190 paint.setColor (color);
190191 paint.setStyle (SkPaint::kFill_Style );
@@ -998,7 +999,8 @@ TEST(DisplayList, DisplayListSaveLayerBoundsWithAlphaFilter) {
998999 // that modifies alpha channels (save layer bounds are meaningless
9991000 // under those circumstances)
10001001 SkPictureRecorder recorder;
1001- SkCanvas* canvas = recorder.beginRecording (build_bounds);
1002+ SkRTreeFactory rtree_factory;
1003+ SkCanvas* canvas = recorder.beginRecording (build_bounds, &rtree_factory);
10021004 SkPaint p1;
10031005 p1.setColorFilter (alpha_color_filter);
10041006 canvas->saveLayer (save_bounds, &p1);
@@ -1586,5 +1588,128 @@ TEST(DisplayList, SaveLayerBoundsSnapshotsImageFilter) {
15861588 EXPECT_EQ (bounds, SkRect::MakeLTRB (50 , 50 , 100 , 100 ));
15871589}
15881590
1591+ TEST (DisplayList, FlutterSvgIssue661BoundsWereEmpty) {
1592+ // See https://github.com/dnfield/flutter_svg/issues/661
1593+
1594+ SkPath path1;
1595+ path1.setFillType (SkPathFillType::kWinding );
1596+ path1.moveTo (25 .54f , 37 .52f );
1597+ path1.cubicTo (20 .91f , 37 .52f , 16 .54f , 33 .39f , 13 .62f , 30 .58f );
1598+ path1.lineTo (13 , 30 );
1599+ path1.lineTo (12 .45f , 29 .42f );
1600+ path1.cubicTo (8 .39f , 25 .15f , 1 .61f , 18 , 8 .37f , 11 .27f );
1601+ path1.cubicTo (10 .18f , 9 .46f , 12 .37f , 9 .58f , 14 .49f , 11 .58f );
1602+ path1.cubicTo (15 .67f , 12 .71f , 17 .05f , 14 .69f , 17 .07f , 16 .58f );
1603+ path1.cubicTo (17 .0968f , 17 .458f , 16 .7603f , 18 .3081f , 16 .14f , 18 .93f );
1604+ path1.cubicTo (15 .8168f , 19 .239f , 15 .4653f , 19 .5169f , 15 .09f , 19 .76f );
1605+ path1.cubicTo (14 .27f , 20 .33f , 14 .21f , 20 .44f , 14 .27f , 20 .62f );
1606+ path1.cubicTo (15 .1672f , 22 .3493f , 16 .3239f , 23 .9309f , 17 .7f , 25 .31f );
1607+ path1.cubicTo (19 .0791f , 26 .6861f , 20 .6607f , 27 .8428f , 22 .39f , 28 .74f );
1608+ path1.cubicTo (22 .57f , 28 .8f , 22 .69f , 28 .74f , 23 .25f , 27 .92f );
1609+ path1.cubicTo (23 .5f , 27 .566f , 23 .778f , 27 .231f , 24 .08f , 26 .92f );
1610+ path1.cubicTo (24 .7045f , 26 .3048f , 25 .5538f , 25 .9723f , 26 .43f , 26 );
1611+ path1.cubicTo (28 .29f , 26 , 30 .27f , 27 .4f , 31 .43f , 28 .58f );
1612+ path1.cubicTo (33 .43f , 30 .67f , 33 .55f , 32 .9f , 31 .74f , 34 .7f );
1613+ path1.cubicTo (30 .1477f , 36 .4508f , 27 .906f , 37 .4704f , 25 .54f , 37 .52f );
1614+ path1.close ();
1615+ path1.moveTo (11 .17f , 12 .23f );
1616+ path1.cubicTo (10 .6946f , 12 .2571f , 10 .2522f , 12 .4819f , 9 .95f , 12 .85f );
1617+ path1.cubicTo (5 .12f , 17 .67f , 8 .95f , 22 .5f , 14 .05f , 27 .85f );
1618+ path1.lineTo (14 .62f , 28 .45f );
1619+ path1.lineTo (15 .16f , 28 .96f );
1620+ path1.cubicTo (20 .52f , 34 .06f , 25 .35f , 37 .89f , 30 .16f , 33 .06f );
1621+ path1.cubicTo (30 .83f , 32 .39f , 31 .25f , 31 .56f , 29 .81f , 30 .06f );
1622+ path1.cubicTo (28 .9247f , 29 .07f , 27 .7359f , 28 .4018f , 26 .43f , 28 .16f );
1623+ path1.cubicTo (26 .1476f , 28 .1284f , 25 .8676f , 28 .2367f , 25 .68f , 28 .45f );
1624+ path1.cubicTo (25 .4633f , 28 .6774f , 25 .269f , 28 .9252f , 25 .1f , 29 .19f );
1625+ path1.cubicTo (24 .53f , 30 .01f , 23 .47f , 31 .54f , 21 .54f , 30 .79f );
1626+ path1.lineTo (21 .41f , 30 .72f );
1627+ path1.cubicTo (19 .4601f , 29 .7156f , 17 .6787f , 28 .4133f , 16 .13f , 26 .86f );
1628+ path1.cubicTo (14 .5748f , 25 .3106f , 13 .2693f , 23 .5295f , 12 .26f , 21 .58f );
1629+ path1.lineTo (12 .2f , 21 .44f );
1630+ path1.cubicTo (11 .45f , 19 .51f , 12 .97f , 18 .44f , 13 .8f , 17 .88f );
1631+ path1.cubicTo (14 .061f , 17 .706f , 14 .308f , 17 .512f , 14 .54f , 17 .3f );
1632+ path1.cubicTo (14 .7379f , 17 .1067f , 14 .8404f , 16 .8359f , 14 .82f , 16 .56f );
1633+ path1.cubicTo (14 .5978f , 15 .268f , 13 .9585f , 14 .0843f , 13 , 13 .19f );
1634+ path1.cubicTo (12 .5398f , 12 .642f , 11 .8824f , 12 .2971f , 11 .17f , 12 .23f );
1635+ path1.lineTo (11 .17f , 12 .23f );
1636+ path1.close ();
1637+ path1.moveTo (27 , 19 .34f );
1638+ path1.lineTo (24 .74f , 19 .34f );
1639+ path1.cubicTo (24 .7319f , 18 .758f , 24 .262f , 18 .2881f , 23 .68f , 18 .28f );
1640+ path1.lineTo (23 .68f , 16 .05f );
1641+ path1.lineTo (23 .7f , 16 .05f );
1642+ path1.cubicTo (25 .5153f , 16 .0582f , 26 .9863f , 17 .5248f , 27 , 19 .34f );
1643+ path1.lineTo (27 , 19 .34f );
1644+ path1.close ();
1645+ path1.moveTo (32 .3f , 19 .34f );
1646+ path1.lineTo (30 .07f , 19 .34f );
1647+ path1.cubicTo (30 .037f , 15 .859f , 27 .171f , 13 .011f , 23 .69f , 13 );
1648+ path1.lineTo (23 .69f , 10 .72f );
1649+ path1.cubicTo (28 .415f , 10 .725f , 32 .3f , 14 .615f , 32 .3f , 19 .34f );
1650+ path1.close ();
1651+
1652+ SkPath path2;
1653+ path2.setFillType (SkPathFillType::kWinding );
1654+ path2.moveTo (37 .5f , 19 .33f );
1655+ path2.lineTo (35 .27f , 19 .33f );
1656+ path2.cubicTo (35 .265f , 12 .979f , 30 .041f , 7 .755f , 23 .69f , 7 .75f );
1657+ path2.lineTo (23 .69f , 5 .52f );
1658+ path2.cubicTo (31 .264f , 5 .525f , 37 .495f , 11 .756f , 37 .5f , 19 .33f );
1659+ path2.close ();
1660+
1661+ DisplayListBuilder builder;
1662+ {
1663+ builder.save ();
1664+ builder.clipRect ({0 , 0 , 100 , 100 }, SkClipOp::kIntersect , true );
1665+ {
1666+ builder.save ();
1667+ builder.transform2DAffine (2.17391 , 0 , -2547.83 , //
1668+ 0 , 2.04082 , -500 );
1669+ {
1670+ builder.save ();
1671+ builder.clipRect ({1172 , 245 , 1218 , 294 }, SkClipOp::kIntersect , true );
1672+ {
1673+ builder.saveLayer (nullptr , true );
1674+ {
1675+ builder.save ();
1676+ builder.transform2DAffine (1.4375 , 0 , 1164.09 , //
1677+ 0 , 1.53125 , 236.548 );
1678+ builder.setAntiAlias (1 );
1679+ builder.setColor (0xffffffff );
1680+ builder.drawPath (path1);
1681+ builder.restore ();
1682+ }
1683+ {
1684+ builder.save ();
1685+ builder.transform2DAffine (1.4375 , 0 , 1164.09 , //
1686+ 0 , 1.53125 , 236.548 );
1687+ builder.drawPath (path2);
1688+ builder.restore ();
1689+ }
1690+ builder.restore ();
1691+ }
1692+ builder.restore ();
1693+ }
1694+ builder.restore ();
1695+ }
1696+ builder.restore ();
1697+ }
1698+ sk_sp<DisplayList> display_list = builder.Build ();
1699+ // Prior to the fix, the bounds were empty.
1700+ EXPECT_FALSE (display_list->bounds ().isEmpty ());
1701+ // These are the expected bounds, but testing float values can be
1702+ // flaky wrt minor changes in the bounds calculations. If this
1703+ // line has to be revised too often as the DL implementation is
1704+ // improved and maintained, then we can eliminate this test and
1705+ // just rely on the "rounded out" bounds test that follows.
1706+ EXPECT_EQ (display_list->bounds (),
1707+ SkRect::MakeLTRB (0 , 0.00189208984375 , 99.9839630127 , 100 ));
1708+ // This is the more practical result. The bounds are "almost" 0,0,100x100
1709+ EXPECT_EQ (display_list->bounds ().roundOut (), SkIRect::MakeWH (100 , 100 ));
1710+ EXPECT_EQ (display_list->op_count (), 19 );
1711+ EXPECT_EQ (display_list->bytes (), sizeof (DisplayList) + 304u );
1712+ }
1713+
15891714} // namespace testing
15901715} // namespace flutter
0 commit comments