Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2014 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "PathOpsExtendedTest.h"
      9 #include "PathOpsTestCommon.h"
     10 #include "SkBitmap.h"
     11 #include "Test.h"
     12 
     13 DEF_TEST(PathOpsBuilder, reporter) {
     14     SkOpBuilder builder;
     15     SkPath result;
     16     REPORTER_ASSERT(reporter, builder.resolve(&result));
     17     REPORTER_ASSERT(reporter, result.isEmpty());
     18 
     19     builder.add(result, kDifference_SkPathOp);
     20     REPORTER_ASSERT(reporter, builder.resolve(&result));
     21     REPORTER_ASSERT(reporter, result.isEmpty());
     22 
     23     builder.add(result, kUnion_SkPathOp);
     24     REPORTER_ASSERT(reporter, builder.resolve(&result));
     25     REPORTER_ASSERT(reporter, result.isEmpty());
     26 
     27     SkPath rectPath;
     28     rectPath.setFillType(SkPath::kEvenOdd_FillType);
     29     rectPath.addRect(0, 1, 2, 3, SkPath::kCW_Direction);
     30     builder.add(rectPath, kUnion_SkPathOp);
     31     REPORTER_ASSERT(reporter, builder.resolve(&result));
     32     bool closed;
     33     SkPath::Direction dir;
     34     REPORTER_ASSERT(reporter, result.isRect(nullptr, &closed, &dir));
     35     REPORTER_ASSERT(reporter, closed);
     36     REPORTER_ASSERT(reporter, dir == SkPath::kCCW_Direction);
     37     int pixelDiff = comparePaths(reporter, __FUNCTION__, rectPath, result);
     38     REPORTER_ASSERT(reporter, pixelDiff == 0);
     39 
     40     rectPath.reset();
     41     rectPath.setFillType(SkPath::kEvenOdd_FillType);
     42     rectPath.addRect(0, 1, 2, 3, SkPath::kCCW_Direction);
     43     builder.add(rectPath, kUnion_SkPathOp);
     44     REPORTER_ASSERT(reporter, builder.resolve(&result));
     45     REPORTER_ASSERT(reporter, result.isRect(nullptr, &closed, &dir));
     46     REPORTER_ASSERT(reporter, closed);
     47     REPORTER_ASSERT(reporter, dir == SkPath::kCCW_Direction);
     48     REPORTER_ASSERT(reporter, rectPath == result);
     49 
     50     builder.add(rectPath, kDifference_SkPathOp);
     51     REPORTER_ASSERT(reporter, builder.resolve(&result));
     52     REPORTER_ASSERT(reporter, result.isEmpty());
     53 
     54     SkPath rect2, rect3;
     55     rect2.addRect(2, 1, 4, 3, SkPath::kCW_Direction);
     56     rect3.addRect(4, 1, 5, 3, SkPath::kCCW_Direction);
     57     builder.add(rectPath, kUnion_SkPathOp);
     58     builder.add(rect2, kUnion_SkPathOp);
     59     builder.add(rect3, kUnion_SkPathOp);
     60     REPORTER_ASSERT(reporter, builder.resolve(&result));
     61     REPORTER_ASSERT(reporter, result.isRect(nullptr, &closed, &dir));
     62     REPORTER_ASSERT(reporter, closed);
     63     SkRect expected;
     64     expected.set(0, 1, 5, 3);
     65     REPORTER_ASSERT(reporter, result.getBounds() == expected);
     66 
     67     SkPath circle1, circle2, circle3;
     68     circle1.addCircle(5, 6, 4, SkPath::kCW_Direction);
     69     circle2.addCircle(7, 4, 8, SkPath::kCCW_Direction);
     70     circle3.addCircle(6, 5, 6, SkPath::kCW_Direction);
     71     SkPath opCompare;
     72     Op(circle1, circle2, kUnion_SkPathOp, &opCompare);
     73     Op(opCompare, circle3, kDifference_SkPathOp, &opCompare);
     74     builder.add(circle1, kUnion_SkPathOp);
     75     builder.add(circle2, kUnion_SkPathOp);
     76     builder.add(circle3, kDifference_SkPathOp);
     77     REPORTER_ASSERT(reporter, builder.resolve(&result));
     78     pixelDiff = comparePaths(reporter, __FUNCTION__, opCompare, result);
     79     REPORTER_ASSERT(reporter, pixelDiff == 0);
     80 }
     81 
     82 DEF_TEST(BuilderIssue3838, reporter) {
     83     SkPath path;
     84     path.moveTo(200, 170);
     85     path.lineTo(220, 170);
     86     path.lineTo(220, 230);
     87     path.lineTo(240, 230);
     88     path.lineTo(240, 210);
     89     path.lineTo(180, 210);
     90     path.lineTo(180, 190);
     91     path.lineTo(260, 190);
     92     path.lineTo(260, 250);
     93     path.lineTo(200, 250);
     94     path.lineTo(200, 170);
     95     path.close();
     96     SkPath path2;
     97     SkOpBuilder builder;
     98     builder.add(path, kUnion_SkPathOp);
     99     builder.resolve(&path2);
    100     int pixelDiff = comparePaths(reporter, __FUNCTION__, path, path2);
    101     REPORTER_ASSERT(reporter, pixelDiff == 0);
    102 }
    103 
    104 DEF_TEST(BuilderIssue3838_2, reporter) {
    105     SkPath path;
    106     path.addCircle(100, 100, 50);
    107 
    108     SkOpBuilder builder;
    109     builder.add(path, kUnion_SkPathOp);
    110     builder.add(path, kUnion_SkPathOp);
    111 
    112     SkPath result;
    113     builder.resolve(&result);
    114     int pixelDiff = comparePaths(reporter, __FUNCTION__, path, result);
    115     REPORTER_ASSERT(reporter, pixelDiff == 0);
    116 }
    117 
    118 DEF_TEST(BuilderIssue3838_3, reporter) {
    119     SkPath path;
    120     path.moveTo(40, 10);
    121     path.lineTo(60, 10);
    122     path.lineTo(60, 30);
    123     path.lineTo(40, 30);
    124     path.lineTo(40, 10);
    125     path.moveTo(41, 11);
    126     path.lineTo(41, 29);
    127     path.lineTo(59, 29);
    128     path.lineTo(59, 11);
    129     path.lineTo(41, 11);
    130 
    131     SkOpBuilder builder;
    132     builder.add(path, kUnion_SkPathOp);
    133     SkPath result;
    134     builder.resolve(&result);
    135     int pixelDiff = comparePaths(reporter, __FUNCTION__, path, result);
    136     REPORTER_ASSERT(reporter, pixelDiff == 0);
    137 }
    138 
    139 DEF_TEST(BuilderIssue502792_2, reporter) {
    140     SkPath path, pathB;
    141     path.setFillType(SkPath::kWinding_FillType);
    142     path.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
    143     path.addRect(2, 2, 3, 3, SkPath::kCW_Direction);
    144     pathB.setFillType(SkPath::kEvenOdd_FillType);
    145     pathB.addRect(3, 3, 4, 4, SkPath::kCW_Direction);
    146     pathB.addRect(3, 3, 4, 4, SkPath::kCW_Direction);
    147     SkOpBuilder builder;
    148     builder.add(path, kUnion_SkPathOp);
    149     builder.add(pathB, kDifference_SkPathOp);
    150     SkPath result;
    151     builder.resolve(&result);
    152 }
    153 
    154 DEF_TEST(Fuzz846, reporter) {
    155 /*
    156 <clipPath id="clip-circle">
    157     <circle id="circle" cx="60" cy="60" r="50" />
    158 </clipPath>
    159 <clipPath id="clip-rect">
    160     <clipPath id="clip-rect">
    161         <clipPath id="clip-rect">
    162             <clipPath id="clip-rect">
    163                 <rect x="10" y="30" width="0" height="60" />
    164                 <rect x="10" y="30" width="0" height="60" />
    165                 <rect x="10" y="30" width="100" height="60" />
    166                 <rect x="10" y="30" width="32668" />
    167                 <rect x="10" y="30" width="100" height="18446744073709551615" />
    168                 <rect x="10" y="255" width="100" height="60" />
    169                 <rect width="100" height="60" />
    170                 <rect x="10" y="30" width="100" height="60" />
    171                 <rect x="10" y="30" width="100" height="4294967236" />
    172                 <rect x="10" y="30" width="100" height="60" />
    173             </clipPath>
    174             <rect x="10" y="30" width="0" height="60" />
    175             <rect x="10" y="30" width="0" height="0.18093252719929986369568203" />
    176             <rect x="10" y="30" width="100" height="60" />
    177             <rect x="10" y="30" width="32668" height="60" />
    178             <rect x="10" y="30" width="100" height="18446744073709551615" />
    179             <rect x="10" y="255" width="100" height="60" />
    180             <rect x="2147483649" y="30" width="100" height="60" />
    181             <rect x="10" y="30" width="100" height="60" />
    182             <rect x="10" y="30" width="100" height="60" />
    183             <rect x="10" y="30" width="100" height="60" />
    184         </clipPath>
    185         <rect x="10" y="30" width="0" height="60" />
    186         <rect x="10" y="30" width="0" height="60" />
    187         <rect x="10" y="30" width="100" height="60" />
    188         <rect x="10" y="30" width="32668" height="60" />
    189         <rect x="10" y="30" width="100" height="18446744073709551615" />
    190         <rect x="10" y="255" width="100" height="60" />
    191         <rect x="2147483649" y="30" width="100" height="60" />
    192         <rect x="10" y="30" width="100" height="60" />
    193         <rect x="10" y="2879753595" width="100" height="60" />
    194         <rect x="10" y="30" width="100" height="60" />
    195     </clipPath>
    196     <rect x="10" y="30" width="100" height="60" />
    197     <rect x="10" y="30" width="0" height="60" />
    198     <rect x="10" y="30" width="100" height="60" />
    199     <rect x="10" y="30" width="32668" height="60" />
    200     <rect x="10" y="30" width="100" height="18446744073709551615" />
    201     <rect x="10" y="255" width="100" height="60" />
    202     <rect x="2147483649" y="30" width="100" height="60" />
    203     <rect x="10" y="30" width="100" height="60" />
    204     <rect x="10" y="30" width="100" height="4294967236" />
    205     <rect x="10" y="30" width="100" height="4294967236" />
    206     <rect x="10" y="30" width="100" height="4294967236" />
    207     <rect x="10" y="30" width="100" height="4294967236" />
    208     <rect x="10" y="30" width="100" height="60" />
    209     <rect x="757798030" y="30" width="100" height="60" />
    210 */
    211     SkPath clipCircle, clipRect;
    212     SkPath inner;
    213     clipCircle.addCircle(60, 60, 50);             // <circle id="circle" cx="60" cy="60" r="50" />
    214 
    215     inner.addRect(10, 30, 10+0, 30+60);           // <rect x="10" y="30" width="0" height="60" />
    216     inner.addRect(10, 30, 10+0, 30+60);           // <rect x="10" y="30" width="0" height="60" />
    217     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    218     inner.addRect(10, 30, 10+32668, 30+0);        // <rect x="10" y="30" width="32668" />
    219     inner.addRect(10, 30, 10+100, 30+18446744073709551615.f); // <rect x="10" y="30" width="100" height="18446744073709551615" />
    220     inner.addRect(10, 255, 10+100, 255+60);       // <rect x="10" y="255" width="100" height="60" />
    221     inner.addRect(0, 0, 0+100, 0+60);             //  <rect width="100" height="60" />
    222     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    223     inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" />
    224     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    225     clipRect.addPath(inner);
    226     inner.reset();
    227     inner.addRect(10, 30, 10+0, 30+60);           // <rect x="10" y="30" width="0" height="60" />
    228     inner.addRect(10, 30, 10+0, 30+0.18093252719929986369568203f); // <rect x="10" y="30" width="0" height="0.18093252719929986369568203" />
    229     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    230     inner.addRect(10, 30, 10+32668, 30+60);       // <rect x="10" y="30" width="32668" height="60" />
    231     inner.addRect(10, 30, 10+100, 30+18446744073709551615.f); // <rect x="10" y="30" width="100" height="18446744073709551615" />
    232     inner.addRect(10, 255, 10+100, 255+60);       // <rect x="10" y="255" width="100" height="60" />
    233     inner.addRect(2147483649.f, 30, 2147483649.f+100, 30+60); // <rect x="2147483649" y="30" width="100" height="60" />
    234     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    235     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    236     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    237     clipRect.addPath(inner);
    238     inner.reset();
    239     inner.addRect(10, 30, 10+0, 30+60);           // <rect x="10" y="30" width="0" height="60" />
    240     inner.addRect(10, 30, 10+0, 30+60);           // <rect x="10" y="30" width="0" height="60" />
    241     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    242     inner.addRect(10, 30, 10+32668, 30+60);       // <rect x="10" y="30" width="32668" height="60" />
    243     inner.addRect(10, 30, 10+100, 30+18446744073709551615.f); // <rect x="10" y="30" width="100" height="18446744073709551615" />
    244     inner.addRect(10, 255, 10+100, 255+60);       // <rect x="10" y="255" width="100" height="60" />
    245     inner.addRect(2147483649.f, 30, 2147483649.f+100, 30+60); // <rect x="2147483649" y="30" width="100" height="60" />
    246     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    247     inner.addRect(10, 2879753595.f, 10+100, 30+2879753595.f); // <rect x="10" y="2879753595" width="100" height="60" />
    248     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    249     clipRect.addPath(inner);
    250     inner.reset();
    251     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    252     inner.addRect(10, 30, 10+0, 30+60);           // <rect x="10" y="30" width="0" height="60" />
    253     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    254     inner.addRect(10, 30, 10+32668, 30+60);       // <rect x="10" y="30" width="32668" height="60" />
    255     inner.addRect(10, 30, 10+100, 30+18446744073709551615.f); // <rect x="10" y="30" width="100" height="18446744073709551615" />
    256     inner.addRect(10, 255, 10+100, 255+60);       // <rect x="10" y="255" width="100" height="60" />
    257     inner.addRect(2147483649.f, 30, 2147483649.f+100, 30+60); // <rect x="2147483649" y="30" width="100" height="60" />
    258     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    259     inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" />
    260     inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" />
    261     inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" />
    262     inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" />
    263     inner.addRect(10, 30, 10+100, 30+60);         // <rect x="10" y="30" width="100" height="60" />
    264     inner.addRect(757798030.f, 30, 757798030.f+100, 30+60); // <rect x="757798030" y="30" width="100" height="60" />
    265     clipRect.addPath(inner);
    266 
    267     SkOpBuilder builder;
    268     builder.add(clipCircle, kUnion_SkPathOp);
    269     builder.add(clipRect, kDifference_SkPathOp);
    270     SkPath result;
    271     builder.resolve(&result);
    272 }
    273 
    274 DEF_TEST(Issue569540, reporter) {
    275     SkPath path1;
    276     path1.moveTo(5, -225);
    277     path1.lineTo(-225, 7425);
    278     path1.lineTo(7425, 7425);
    279     path1.lineTo(7425, -225);
    280     path1.lineTo(-225, -225);
    281     path1.lineTo(5, -225);
    282     path1.close();
    283 
    284     SkPath path2;
    285     path2.moveTo(5940, 2790);
    286     path2.lineTo(5940, 2160);
    287     path2.lineTo(5970, 1980);
    288     path2.lineTo(5688, 773669888);
    289     path2.lineTo(5688, 2160);
    290     path2.lineTo(5688, 2430);
    291     path2.lineTo(5400, 4590);
    292     path2.lineTo(5220, 4590);
    293     path2.lineTo(5220, 4920);
    294     path2.cubicTo(5182.22900390625f, 4948.328125f, 5160, 4992.78662109375f, 5160, 5040.00048828125f);
    295     path2.lineTo(5940, 2790);
    296     path2.close();
    297 
    298     SkOpBuilder builder;
    299     builder.add(path1, kUnion_SkPathOp);
    300     builder.add(path2, kUnion_SkPathOp);
    301     SkPath result;
    302     builder.resolve(&result);
    303 }
    304 
    305 DEF_TEST(SkOpBuilderFuzz665, reporter) {
    306     SkPath path;
    307     path.setFillType(SkPath::kEvenOdd_FillType);
    308 path.moveTo(SkBits2Float(0xcc4264a7), SkBits2Float(0x4bb12e50));  // -5.0959e+07f, 2.32235e+07f
    309 path.lineTo(SkBits2Float(0xcc4264b0), SkBits2Float(0x4bb12e48));  // -5.0959e+07f, 2.32234e+07f
    310 path.lineTo(SkBits2Float(0xcc4264a7), SkBits2Float(0x4bb12e50));  // -5.0959e+07f, 2.32235e+07f
    311 path.close();
    312     SkPath path1(path);
    313     path.reset();
    314     path.setFillType(SkPath::kWinding_FillType);
    315 path.moveTo(SkBits2Float(0x43213333), SkBits2Float(0x43080000));  // 161.2f, 136
    316 path.lineTo(SkBits2Float(0x43038000), SkBits2Float(0x43080000));  // 131.5f, 136
    317 path.cubicTo(SkBits2Float(0x43038000), SkBits2Float(0x42f00000), SkBits2Float(0x42f16666), SkBits2Float(0x42d53333), SkBits2Float(0x42d3cccd), SkBits2Float(0x42cd6666));  // 131.5f, 120, 120.7f, 106.6f, 105.9f, 102.7f
    318 path.lineTo(SkBits2Float(0x42e33333), SkBits2Float(0x42940000));  // 113.6f, 74
    319     SkPath path2(path);
    320     SkOpBuilder builder;
    321     builder.add(path1, kUnion_SkPathOp);
    322     builder.add(path2, kUnion_SkPathOp);
    323     SkPath result;
    324     builder.resolve(&result);
    325 }
    326 
    327 DEF_TEST(SkOpBuilder618991, reporter) {
    328     SkPath path0;
    329     path0.moveTo(140, 40);
    330     path0.lineTo(200, 210);
    331     path0.lineTo(40, 100);
    332     path0.lineTo(2.22223e+07f, 2.22222e+14f);
    333     path0.lineTo(2.22223e+07f, 2.22222e+14f);
    334 
    335     SkPath path1;
    336     path1.moveTo(160, 60);
    337     path1.lineTo(220, 230);
    338     path1.lineTo(60, 120);
    339     path1.lineTo(2.22223e+07f, 2.22222e+14f);
    340     path1.lineTo(2.22223e+07f, 2.22222e+14f);
    341 
    342     SkOpBuilder builder;
    343     builder.add(path0, SkPathOp::kUnion_SkPathOp);
    344     builder.add(path1, SkPathOp::kUnion_SkPathOp);
    345     builder.resolve(&path0);
    346 }
    347 
    348 DEF_TEST(SkOpBuilderKFuzz1, reporter) {
    349     SkPath path;
    350 path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000));  // 0, 0
    351 path.lineTo(SkBits2Float(0x39008001), SkBits2Float(0xd31fbc1d));  // 0.000122547f, -6.86056e+11f
    352 path.conicTo(SkBits2Float(0x246a205a), SkBits2Float(0x0080d3fb), SkBits2Float(0xce000001), SkBits2Float(0x04d31fbc), SkBits2Float(0x57a82c00));  // 5.07681e-17f, 1.1831e-38f, -5.36871e+08f, 4.9635e-36f, 3.69814e+14f
    353     SkPath path0(path);
    354     path.reset();
    355 path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000));  // 0, 0
    356 path.cubicTo(SkBits2Float(0x80d3f924), SkBits2Float(0xcecece4f), SkBits2Float(0xcececece), SkBits2Float(0xcececece), SkBits2Float(0x9a9a9ace), SkBits2Float(0x9a9a9a9a));  // -1.94667e-38f, -1.73481e+09f, -1.73483e+09f, -1.73483e+09f, -6.3943e-23f, -6.39427e-23f
    357 path.moveTo(SkBits2Float(0x9a9a019a), SkBits2Float(0xa59a9a9a));  // -6.36955e-23f, -2.68195e-16f
    358     SkPath path1(path);
    359 SkOpBuilder builder;
    360     builder.add(path0, SkPathOp::kUnion_SkPathOp);
    361     builder.add(path1, SkPathOp::kUnion_SkPathOp);
    362     builder.resolve(&path);
    363 }
    364