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 
DEF_TEST(PathOpsBuilder,reporter)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 
DEF_TEST(BuilderIssue3838,reporter)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 
DEF_TEST(BuilderIssue3838_2,reporter)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 
DEF_TEST(BuilderIssue3838_3,reporter)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 
DEF_TEST(BuilderIssue502792_2,reporter)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 
DEF_TEST(Fuzz846,reporter)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 
DEF_TEST(Issue569540,reporter)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