• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 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 #include "SkPathOps.h"
8 #include "SkPath.h"
9 #include "SkPoint.h"
10 #include "Test.h"
11 
12 static const SkPoint nonFinitePts[] = {
13     { SK_ScalarInfinity, 0 },
14     { 0, SK_ScalarInfinity },
15     { SK_ScalarInfinity, SK_ScalarInfinity },
16     { SK_ScalarNegativeInfinity, 0},
17     { 0, SK_ScalarNegativeInfinity },
18     { SK_ScalarNegativeInfinity, SK_ScalarNegativeInfinity },
19     { SK_ScalarNegativeInfinity, SK_ScalarInfinity },
20     { SK_ScalarInfinity, SK_ScalarNegativeInfinity },
21     { SK_ScalarNaN, 0 },
22     { 0, SK_ScalarNaN },
23     { SK_ScalarNaN, SK_ScalarNaN },
24 };
25 
26 const size_t nonFinitePtsCount = sizeof(nonFinitePts) / sizeof(nonFinitePts[0]);
27 
28 static const SkPoint finitePts[] = {
29     { 0, 0 },
30     { SK_ScalarMax, 0 },
31     { 0, SK_ScalarMax },
32     { SK_ScalarMax, SK_ScalarMax },
33     { SK_ScalarMin, 0 },
34     { 0, SK_ScalarMin },
35     { SK_ScalarMin, SK_ScalarMin },
36 };
37 
38 const size_t finitePtsCount = sizeof(finitePts) / sizeof(finitePts[0]);
39 
failOne(skiatest::Reporter * reporter,int index)40 static void failOne(skiatest::Reporter* reporter, int index) {
41     SkPath path;
42     int i = (int) (index % nonFinitePtsCount);
43     int f = (int) (index % finitePtsCount);
44     int g = (int) ((f + 1) % finitePtsCount);
45     switch (index % 13) {
46         case 0: path.lineTo(nonFinitePts[i]); break;
47         case 1: path.quadTo(nonFinitePts[i], nonFinitePts[i]); break;
48         case 2: path.quadTo(nonFinitePts[i], finitePts[f]); break;
49         case 3: path.quadTo(finitePts[f], nonFinitePts[i]); break;
50         case 4: path.cubicTo(nonFinitePts[i], finitePts[f], finitePts[f]); break;
51         case 5: path.cubicTo(finitePts[f], nonFinitePts[i], finitePts[f]); break;
52         case 6: path.cubicTo(finitePts[f], finitePts[f], nonFinitePts[i]); break;
53         case 7: path.cubicTo(nonFinitePts[i], nonFinitePts[i], finitePts[f]); break;
54         case 8: path.cubicTo(nonFinitePts[i], finitePts[f], nonFinitePts[i]); break;
55         case 9: path.cubicTo(finitePts[f], nonFinitePts[i], nonFinitePts[i]); break;
56         case 10: path.cubicTo(nonFinitePts[i], nonFinitePts[i], nonFinitePts[i]); break;
57         case 11: path.cubicTo(nonFinitePts[i], finitePts[f], finitePts[g]); break;
58         case 12: path.moveTo(nonFinitePts[i]); break;
59     }
60     SkPath result;
61     result.setFillType(SkPath::kWinding_FillType);
62     bool success = Simplify(path, &result);
63     REPORTER_ASSERT(reporter, !success);
64     REPORTER_ASSERT(reporter, result.isEmpty());
65     REPORTER_ASSERT(reporter, result.getFillType() == SkPath::kWinding_FillType);
66     reporter->bumpTestCount();
67 }
68 
dontFailOne(skiatest::Reporter * reporter,int index)69 static void dontFailOne(skiatest::Reporter* reporter, int index) {
70     SkPath path;
71     int f = (int) (index % finitePtsCount);
72     int g = (int) ((f + 1) % finitePtsCount);
73     switch (index % 11) {
74         case 0: path.lineTo(finitePts[f]); break;
75         case 1: path.quadTo(finitePts[f], finitePts[f]); break;
76         case 2: path.quadTo(finitePts[f], finitePts[g]); break;
77         case 3: path.quadTo(finitePts[g], finitePts[f]); break;
78         case 4: path.cubicTo(finitePts[f], finitePts[f], finitePts[f]); break;
79         case 5: path.cubicTo(finitePts[f], finitePts[f], finitePts[g]); break;
80         case 6: path.cubicTo(finitePts[f], finitePts[g], finitePts[f]); break;
81         case 7: path.cubicTo(finitePts[f], finitePts[g], finitePts[g]); break;
82         case 8: path.cubicTo(finitePts[g], finitePts[f], finitePts[f]); break;
83         case 9: path.cubicTo(finitePts[g], finitePts[f], finitePts[g]); break;
84         case 10: path.moveTo(finitePts[f]); break;
85     }
86     SkPath result;
87     result.setFillType(SkPath::kWinding_FillType);
88     bool success = Simplify(path, &result);
89     REPORTER_ASSERT(reporter, success);
90     REPORTER_ASSERT(reporter, result.getFillType() != SkPath::kWinding_FillType);
91     reporter->bumpTestCount();
92 }
93 
PathOpsSimplifyFailTest(skiatest::Reporter * reporter)94 static void PathOpsSimplifyFailTest(skiatest::Reporter* reporter) {
95     for (int index = 0; index < (int) (13 * nonFinitePtsCount * finitePtsCount); ++index) {
96         failOne(reporter, index);
97     }
98     for (int index = 0; index < (int) (11 * finitePtsCount); ++index) {
99         dontFailOne(reporter, index);
100     }
101 }
102 
PathOpsSimplifyFailOneTest(skiatest::Reporter * reporter)103 static void PathOpsSimplifyFailOneTest(skiatest::Reporter* reporter) {
104     int index = 0;
105     failOne(reporter, index);
106 }
107 
PathOpsSimplifyDontFailOneTest(skiatest::Reporter * reporter)108 static void PathOpsSimplifyDontFailOneTest(skiatest::Reporter* reporter) {
109     int index = 6;
110     dontFailOne(reporter, index);
111 }
112 
113 #include "TestClassDef.h"
114 DEFINE_TESTCLASS_SHORT(PathOpsSimplifyFailTest)
115 
116 DEFINE_TESTCLASS_SHORT(PathOpsSimplifyFailOneTest)
117 
118 DEFINE_TESTCLASS_SHORT(PathOpsSimplifyDontFailOneTest)
119