OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkMatrix.h" | 8 #include "SkMatrix.h" |
9 #include "SkPath.h" | 9 #include "SkPath.h" |
10 #include "SkPathRef.h" | 10 #include "SkPathRef.h" |
11 #include "SkPathOps.h" | |
12 #include "SkRRect.h" | 11 #include "SkRRect.h" |
13 #include "Test.h" | 12 #include "Test.h" |
14 | 13 |
15 static SkRRect path_contains_rrect(skiatest::Reporter* reporter, const SkPath& p
ath) { | 14 static SkRRect path_contains_rrect(skiatest::Reporter* reporter, const SkPath& p
ath, |
| 15 SkPath::Direction* dir, unsigned* start) { |
16 SkRRect out; | 16 SkRRect out; |
17 REPORTER_ASSERT(reporter, path.isRRect(&out)); | 17 REPORTER_ASSERT(reporter, path.isRRect(&out, dir, start)); |
18 SkPath path2, xorBoth; | 18 SkPath recreatedPath; |
19 path2.addRRect(out); | 19 recreatedPath.addRRect(out, *dir, *start); |
20 if (path == path2) { | 20 REPORTER_ASSERT(reporter, path == recreatedPath); |
21 return out; | 21 // Test that rotations/mirrors of the rrect path are still rrect paths and t
he returned |
| 22 // parameters for the transformed paths are correct. |
| 23 static const SkMatrix kMatrices[] = { |
| 24 SkMatrix::MakeScale(1, 1), |
| 25 SkMatrix::MakeScale(-1, 1), |
| 26 SkMatrix::MakeScale(1, -1), |
| 27 SkMatrix::MakeScale(-1, -1), |
| 28 }; |
| 29 for (auto& m : kMatrices) { |
| 30 SkPath xformed; |
| 31 path.transform(m, &xformed); |
| 32 SkRRect xrr; |
| 33 SkPath::Direction xd; |
| 34 unsigned xs; |
| 35 REPORTER_ASSERT(reporter, xformed.isRRect(&xrr, &xd, &xs)); |
| 36 recreatedPath.reset(); |
| 37 recreatedPath.addRRect(xrr, xd, xs); |
| 38 REPORTER_ASSERT(reporter, recreatedPath == xformed); |
22 } | 39 } |
23 Op(path, path2, SkPathOp::kXOR_SkPathOp, &xorBoth); | |
24 REPORTER_ASSERT(reporter, xorBoth.isEmpty()); | |
25 return out; | 40 return out; |
26 } | 41 } |
27 | 42 |
28 static SkRRect inner_path_contains_rrect(skiatest::Reporter* reporter, const SkR
Rect& in) { | 43 static SkRRect inner_path_contains_rrect(skiatest::Reporter* reporter, const SkR
Rect& in, |
| 44 SkPath::Direction dir, unsigned start)
{ |
29 switch (in.getType()) { | 45 switch (in.getType()) { |
30 case SkRRect::kEmpty_Type: | 46 case SkRRect::kEmpty_Type: |
31 case SkRRect::kRect_Type: | 47 case SkRRect::kRect_Type: |
32 case SkRRect::kOval_Type: | 48 case SkRRect::kOval_Type: |
33 return in; | 49 return in; |
34 default: | 50 default: |
35 break; | 51 break; |
36 } | 52 } |
37 SkPath path; | 53 SkPath path; |
38 path.addRRect(in); | 54 path.addRRect(in, dir, start); |
39 return path_contains_rrect(reporter, path); | 55 SkPath::Direction outDir; |
| 56 unsigned outStart; |
| 57 SkRRect rrect = path_contains_rrect(reporter, path, &outDir, &outStart); |
| 58 REPORTER_ASSERT(reporter, outDir == dir && outStart == start); |
| 59 return rrect; |
40 } | 60 } |
41 | 61 |
42 static void path_contains_rrect_check(skiatest::Reporter* reporter, const SkRRec
t& in) { | 62 static void path_contains_rrect_check(skiatest::Reporter* reporter, const SkRRec
t& in, |
43 SkRRect out = inner_path_contains_rrect(reporter, in); | 63 SkPath::Direction dir, unsigned start) { |
| 64 SkRRect out = inner_path_contains_rrect(reporter, in, dir, start); |
44 if (in != out) { | 65 if (in != out) { |
45 SkDebugf(""); | 66 SkDebugf(""); |
46 } | 67 } |
47 REPORTER_ASSERT(reporter, in == out); | 68 REPORTER_ASSERT(reporter, in == out); |
48 } | 69 } |
49 | 70 |
50 static void path_contains_rrect_nocheck(skiatest::Reporter* reporter, const SkRR
ect& in) { | 71 static void path_contains_rrect_nocheck(skiatest::Reporter* reporter, const SkRR
ect& in, |
51 SkRRect out = inner_path_contains_rrect(reporter, in); | 72 SkPath::Direction dir, unsigned start) { |
| 73 SkRRect out = inner_path_contains_rrect(reporter, in, dir, start); |
52 if (in == out) { | 74 if (in == out) { |
53 SkDebugf(""); | 75 SkDebugf(""); |
54 } | 76 } |
55 } | 77 } |
56 | 78 |
57 static void path_contains_rrect_check(skiatest::Reporter* reporter, const SkRect
& r, | 79 static void path_contains_rrect_check(skiatest::Reporter* reporter, const SkRect
& r, |
58 SkVector v[4]) { | 80 SkVector v[4], SkPath::Direction dir, unsigned start) { |
59 SkRRect rrect; | 81 SkRRect rrect; |
60 rrect.setRectRadii(r, v); | 82 rrect.setRectRadii(r, v); |
61 path_contains_rrect_check(reporter, rrect); | 83 path_contains_rrect_check(reporter, rrect, dir, start); |
62 } | 84 } |
63 | 85 |
64 class ForceIsRRect_Private { | 86 class ForceIsRRect_Private { |
65 public: | 87 public: |
66 ForceIsRRect_Private(SkPath* path) { | 88 ForceIsRRect_Private(SkPath* path, SkPath::Direction dir, unsigned start) { |
67 path->fPathRef->setIsRRect(true); | 89 path->fPathRef->setIsRRect(true, dir == SkPath::kCCW_Direction, start); |
68 } | 90 } |
69 }; | 91 }; |
70 | 92 |
71 static void force_path_contains_rrect(skiatest::Reporter* reporter, SkPath& path
) { | 93 static void force_path_contains_rrect(skiatest::Reporter* reporter, SkPath& path
, |
72 ForceIsRRect_Private force_rrect(&path); | 94 SkPath::Direction dir, unsigned start) { |
73 path_contains_rrect(reporter, path); | 95 ForceIsRRect_Private force_rrect(&path, dir, start); |
| 96 SkPath::Direction outDir; |
| 97 unsigned outStart; |
| 98 path_contains_rrect(reporter, path, &outDir, &outStart); |
| 99 REPORTER_ASSERT(reporter, outDir == dir && outStart == start); |
74 } | 100 } |
75 | 101 |
76 static void test_undetected_paths(skiatest::Reporter* reporter) { | 102 static void test_undetected_paths(skiatest::Reporter* reporter) { |
| 103 // We use a dummy path to get the exact conic weight used by SkPath for a ci
rcular arc. This |
| 104 // allows our local, hand-crafted, artisanal round rect paths below to exact
ly match the |
| 105 // factory made corporate paths produced by SkPath. |
| 106 SkPath dummyPath; |
| 107 dummyPath.addCircle(0, 0, 10); |
| 108 SkPath::RawIter iter(dummyPath); |
| 109 SkPoint dummyPts[4]; |
| 110 SkPath::Verb v = iter.next(dummyPts); |
| 111 SkASSERT(SkPath::kMove_Verb == v); |
| 112 v = iter.next(dummyPts); |
| 113 SkASSERT(SkPath::kConic_Verb == v); |
| 114 const SkScalar weight = iter.conicWeight(); |
| 115 |
77 SkPath path; | 116 SkPath path; |
78 path.moveTo(0, 62.5f); | 117 path.moveTo(0, 62.5f); |
79 path.lineTo(0, 3.5f); | 118 path.lineTo(0, 3.5f); |
80 path.conicTo(0, 0, 3.5f, 0, 0.70710677f); | 119 path.conicTo(0, 0, 3.5f, 0, weight); |
81 path.lineTo(196.5f, 0); | 120 path.lineTo(196.5f, 0); |
82 path.conicTo(200, 0, 200, 3.5f, 0.70710677f); | 121 path.conicTo(200, 0, 200, 3.5f, weight); |
83 path.lineTo(200, 62.5f); | 122 path.lineTo(200, 62.5f); |
84 path.conicTo(200, 66, 196.5f, 66, 0.70710677f); | 123 path.conicTo(200, 66, 196.5f, 66, weight); |
85 path.lineTo(3.5f, 66); | 124 path.lineTo(3.5f, 66); |
86 path.conicTo(0, 66, 0, 62.5, 0.70710677f); | 125 path.conicTo(0, 66, 0, 62.5, weight); |
87 path.close(); | 126 path.close(); |
88 force_path_contains_rrect(reporter, path); | 127 force_path_contains_rrect(reporter, path, SkPath::kCW_Direction, 6); |
89 | 128 |
90 path.reset(); | 129 path.reset(); |
91 path.moveTo(0, 81.5f); | 130 path.moveTo(0, 81.5f); |
92 path.lineTo(0, 3.5f); | 131 path.lineTo(0, 3.5f); |
93 path.conicTo(0, 0, 3.5f, 0, 0.70710677f); | 132 path.conicTo(0, 0, 3.5f, 0, weight); |
94 path.lineTo(149.5, 0); | 133 path.lineTo(149.5, 0); |
95 path.conicTo(153, 0, 153, 3.5f, 0.70710677f); | 134 path.conicTo(153, 0, 153, 3.5f, weight); |
96 path.lineTo(153, 81.5f); | 135 path.lineTo(153, 81.5f); |
97 path.conicTo(153, 85, 149.5f, 85, 0.70710677f); | 136 path.conicTo(153, 85, 149.5f, 85, weight); |
98 path.lineTo(3.5f, 85); | 137 path.lineTo(3.5f, 85); |
99 path.conicTo(0, 85, 0, 81.5f, 0.70710677f); | 138 path.conicTo(0, 85, 0, 81.5f, weight); |
100 path.close(); | 139 path.close(); |
101 force_path_contains_rrect(reporter, path); | 140 force_path_contains_rrect(reporter, path, SkPath::kCW_Direction, 6); |
102 | 141 |
103 path.reset(); | 142 path.reset(); |
104 path.moveTo(14, 1189); | 143 path.moveTo(14, 1189); |
105 path.lineTo(14, 21); | 144 path.lineTo(14, 21); |
106 path.conicTo(14, 14, 21, 14, 0.70710677f); | 145 path.conicTo(14, 14, 21, 14, weight); |
107 path.lineTo(1363, 14); | 146 path.lineTo(1363, 14); |
108 path.conicTo(1370, 14, 1370, 21, 0.70710677f); | 147 path.conicTo(1370, 14, 1370, 21, weight); |
109 path.lineTo(1370, 1189); | 148 path.lineTo(1370, 1189); |
110 path.conicTo(1370, 1196, 1363, 1196, 0.70710677f); | 149 path.conicTo(1370, 1196, 1363, 1196, weight); |
111 path.lineTo(21, 1196); | 150 path.lineTo(21, 1196); |
112 path.conicTo(14, 1196, 14, 1189, 0.70710677f); | 151 path.conicTo(14, 1196, 14, 1189, weight); |
113 path.close(); | 152 path.close(); |
114 force_path_contains_rrect(reporter, path); | 153 force_path_contains_rrect(reporter, path, SkPath::kCW_Direction, 6); |
115 | 154 |
116 path.reset(); | 155 path.reset(); |
117 path.moveTo(14, 1743); | 156 path.moveTo(14, 1743); |
118 path.lineTo(14, 21); | 157 path.lineTo(14, 21); |
119 path.conicTo(14, 14, 21, 14, 0.70710677f); | 158 path.conicTo(14, 14, 21, 14, weight); |
120 path.lineTo(1363, 14); | 159 path.lineTo(1363, 14); |
121 path.conicTo(1370, 14, 1370, 21, 0.70710677f); | 160 path.conicTo(1370, 14, 1370, 21, weight); |
122 path.lineTo(1370, 1743); | 161 path.lineTo(1370, 1743); |
123 path.conicTo(1370, 1750, 1363, 1750, 0.70710677f); | 162 path.conicTo(1370, 1750, 1363, 1750, weight); |
124 path.lineTo(21, 1750); | 163 path.lineTo(21, 1750); |
125 path.conicTo(14, 1750, 14, 1743, 0.70710677f); | 164 path.conicTo(14, 1750, 14, 1743, weight); |
126 path.close(); | 165 path.close(); |
127 force_path_contains_rrect(reporter, path); | 166 force_path_contains_rrect(reporter, path, SkPath::kCW_Direction, 6); |
128 } | 167 } |
129 | 168 |
130 static const SkScalar kWidth = 100.0f; | 169 static const SkScalar kWidth = 100.0f; |
131 static const SkScalar kHeight = 100.0f; | 170 static const SkScalar kHeight = 100.0f; |
132 | 171 |
133 static void test_tricky_radii(skiatest::Reporter* reporter) { | 172 static void test_tricky_radii(skiatest::Reporter* reporter) { |
134 { | 173 for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) { |
135 // crbug.com/458522 | 174 for (int start = 0; start < 8; ++start) { |
136 SkRRect rr; | 175 { |
137 const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 }; | 176 // crbug.com/458522 |
138 const SkScalar rad = 12814; | 177 SkRRect rr; |
139 const SkVector vec[] = { { rad, rad }, { 0, rad }, { rad, rad }, { 0, ra
d } }; | 178 const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 }; |
140 rr.setRectRadii(bounds, vec); | 179 const SkScalar rad = 12814; |
141 path_contains_rrect_check(reporter, rr); | 180 const SkVector vec[] = { { rad, rad }, { 0, rad }, { rad, rad },
{ 0, rad } }; |
142 } | 181 rr.setRectRadii(bounds, vec); |
| 182 path_contains_rrect_check(reporter, rr, dir, start); |
| 183 } |
143 | 184 |
144 { | 185 { |
145 // crbug.com//463920 | 186 // crbug.com//463920 |
146 SkRect r = SkRect::MakeLTRB(0, 0, 1009, 33554432.0); | 187 SkRect r = SkRect::MakeLTRB(0, 0, 1009, 33554432.0); |
147 SkVector radii[4] = { | 188 SkVector radii[4] = { |
148 { 13.0f, 8.0f }, { 170.0f, 2.0 }, { 256.0f, 33554432.0 }, { 110.0f,
5.0f } | 189 { 13.0f, 8.0f }, { 170.0f, 2.0 }, { 256.0f, 33554432.0 }, {
110.0f, 5.0f } |
149 }; | 190 }; |
150 SkRRect rr; | 191 SkRRect rr; |
151 rr.setRectRadii(r, radii); | 192 rr.setRectRadii(r, radii); |
152 path_contains_rrect_nocheck(reporter, rr); | 193 path_contains_rrect_nocheck(reporter, rr, dir, start); |
| 194 } |
| 195 } |
153 } | 196 } |
154 } | 197 } |
155 | 198 |
156 static void test_empty_crbug_458524(skiatest::Reporter* reporter) { | 199 static void test_empty_crbug_458524(skiatest::Reporter* reporter) { |
157 SkRRect rr; | 200 for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) { |
158 const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 }; | 201 for (int start = 0; start < 8; ++start) { |
159 const SkScalar rad = 40; | 202 SkRRect rr; |
160 rr.setRectXY(bounds, rad, rad); | 203 const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 }; |
161 path_contains_rrect_check(reporter, rr); | 204 const SkScalar rad = 40; |
| 205 rr.setRectXY(bounds, rad, rad); |
| 206 path_contains_rrect_check(reporter, rr, dir, start); |
162 | 207 |
163 SkRRect other; | 208 SkRRect other; |
164 SkMatrix matrix; | 209 SkMatrix matrix; |
165 matrix.setScale(0, 1); | 210 matrix.setScale(0, 1); |
166 rr.transform(matrix, &other); | 211 rr.transform(matrix, &other); |
167 path_contains_rrect_check(reporter, rr); | 212 path_contains_rrect_check(reporter, rr, dir, start); |
| 213 } |
| 214 } |
168 } | 215 } |
169 | 216 |
170 static void test_inset(skiatest::Reporter* reporter) { | 217 static void test_inset(skiatest::Reporter* reporter) { |
171 SkRRect rr, rr2; | 218 for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) { |
172 SkRect r = { 0, 0, 100, 100 }; | 219 for (int start = 0; start < 8; ++start) { |
| 220 SkRRect rr, rr2; |
| 221 SkRect r = { 0, 0, 100, 100 }; |
173 | 222 |
174 rr.setRect(r); | 223 rr.setRect(r); |
175 rr.inset(-20, -20, &rr2); | 224 rr.inset(-20, -20, &rr2); |
176 path_contains_rrect_check(reporter, rr); | 225 path_contains_rrect_check(reporter, rr, dir, start); |
177 | 226 |
178 rr.inset(20, 20, &rr2); | 227 rr.inset(20, 20, &rr2); |
179 path_contains_rrect_check(reporter, rr); | 228 path_contains_rrect_check(reporter, rr, dir, start); |
180 | 229 |
181 rr.inset(r.width()/2, r.height()/2, &rr2); | 230 rr.inset(r.width()/2, r.height()/2, &rr2); |
182 path_contains_rrect_check(reporter, rr); | 231 path_contains_rrect_check(reporter, rr, dir, start); |
183 | 232 |
184 rr.setRectXY(r, 20, 20); | 233 rr.setRectXY(r, 20, 20); |
185 rr.inset(19, 19, &rr2); | 234 rr.inset(19, 19, &rr2); |
186 path_contains_rrect_check(reporter, rr); | 235 path_contains_rrect_check(reporter, rr, dir, start); |
187 rr.inset(20, 20, &rr2); | 236 rr.inset(20, 20, &rr2); |
188 path_contains_rrect_check(reporter, rr); | 237 path_contains_rrect_check(reporter, rr, dir, start); |
| 238 } |
| 239 } |
189 } | 240 } |
190 | 241 |
191 | 242 |
192 static void test_9patch_rrect(skiatest::Reporter* reporter, | 243 static void test_9patch_rrect(skiatest::Reporter* reporter, |
193 const SkRect& rect, | 244 const SkRect& rect, |
194 SkScalar l, SkScalar t, SkScalar r, SkScalar b, | 245 SkScalar l, SkScalar t, SkScalar r, SkScalar b, |
195 bool checkRadii) { | 246 bool checkRadii) { |
196 SkRRect rr; | 247 for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) { |
197 rr.setNinePatch(rect, l, t, r, b); | 248 for (int start = 0; start < 8; ++start) { |
198 if (checkRadii) { | 249 SkRRect rr; |
199 path_contains_rrect_check(reporter, rr); | 250 rr.setNinePatch(rect, l, t, r, b); |
200 } else { | 251 if (checkRadii) { |
201 path_contains_rrect_nocheck(reporter, rr); | 252 path_contains_rrect_check(reporter, rr, dir, start); |
202 } | 253 } else { |
| 254 path_contains_rrect_nocheck(reporter, rr, dir, start); |
| 255 } |
203 | 256 |
204 SkRRect rr2; // construct the same RR using the most general set function | 257 SkRRect rr2; // construct the same RR using the most general set fun
ction |
205 SkVector radii[4] = { { l, t }, { r, t }, { r, b }, { l, b } }; | 258 SkVector radii[4] = { { l, t }, { r, t }, { r, b }, { l, b } }; |
206 rr2.setRectRadii(rect, radii); | 259 rr2.setRectRadii(rect, radii); |
207 if (checkRadii) { | 260 if (checkRadii) { |
208 path_contains_rrect_check(reporter, rr); | 261 path_contains_rrect_check(reporter, rr, dir, start); |
209 } else { | 262 } else { |
210 path_contains_rrect_nocheck(reporter, rr); | 263 path_contains_rrect_nocheck(reporter, rr, dir, start); |
| 264 } |
| 265 } |
211 } | 266 } |
212 } | 267 } |
213 | 268 |
214 // Test out the basic API entry points | 269 // Test out the basic API entry points |
215 static void test_round_rect_basic(skiatest::Reporter* reporter) { | 270 static void test_round_rect_basic(skiatest::Reporter* reporter) { |
| 271 for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) { |
| 272 for (int start = 0; start < 8; ++start) { |
| 273 //---- |
| 274 SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); |
216 | 275 |
217 //---- | 276 SkRRect rr1; |
218 SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); | 277 rr1.setRect(rect); |
| 278 path_contains_rrect_check(reporter, rr1, dir, start); |
219 | 279 |
220 SkRRect rr1; | 280 SkRRect rr1_2; // construct the same RR using the most general set f
unction |
221 rr1.setRect(rect); | 281 SkVector rr1_2_radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }
; |
222 path_contains_rrect_check(reporter, rr1); | 282 rr1_2.setRectRadii(rect, rr1_2_radii); |
| 283 path_contains_rrect_check(reporter, rr1_2, dir, start); |
| 284 SkRRect rr1_3; // construct the same RR using the nine patch set fu
nction |
| 285 rr1_3.setNinePatch(rect, 0, 0, 0, 0); |
| 286 path_contains_rrect_check(reporter, rr1_2, dir, start); |
223 | 287 |
224 SkRRect rr1_2; // construct the same RR using the most general set function | 288 //---- |
225 SkVector rr1_2_radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; | 289 SkPoint halfPoint = { SkScalarHalf(kWidth), SkScalarHalf(kHeight) }; |
226 rr1_2.setRectRadii(rect, rr1_2_radii); | 290 SkRRect rr2; |
227 path_contains_rrect_check(reporter, rr1_2); | 291 rr2.setOval(rect); |
228 SkRRect rr1_3; // construct the same RR using the nine patch set function | 292 path_contains_rrect_check(reporter, rr2, dir, start); |
229 rr1_3.setNinePatch(rect, 0, 0, 0, 0); | |
230 path_contains_rrect_check(reporter, rr1_2); | |
231 | 293 |
232 //---- | 294 SkRRect rr2_2; // construct the same RR using the most general set
function |
233 SkPoint halfPoint = { SkScalarHalf(kWidth), SkScalarHalf(kHeight) }; | 295 SkVector rr2_2_radii[4] = { { halfPoint.fX, halfPoint.fY }, |
234 SkRRect rr2; | 296 { halfPoint.fX, halfPoint.fY }, |
235 rr2.setOval(rect); | 297 { halfPoint.fX, halfPoint.fY }, |
236 path_contains_rrect_check(reporter, rr2); | 298 { halfPoint.fX, halfPoint.fY } }; |
| 299 rr2_2.setRectRadii(rect, rr2_2_radii); |
| 300 path_contains_rrect_check(reporter, rr2_2, dir, start); |
| 301 SkRRect rr2_3; // construct the same RR using the nine patch set fu
nction |
| 302 rr2_3.setNinePatch(rect, halfPoint.fX, halfPoint.fY, halfPoint.fX, h
alfPoint.fY); |
| 303 path_contains_rrect_check(reporter, rr2_3, dir, start); |
237 | 304 |
238 SkRRect rr2_2; // construct the same RR using the most general set function | 305 //---- |
239 SkVector rr2_2_radii[4] = { { halfPoint.fX, halfPoint.fY }, { halfPoint.fX,
halfPoint.fY }, | 306 SkPoint p = { 5, 5 }; |
240 { halfPoint.fX, halfPoint.fY }, { halfPoint.fX,
halfPoint.fY } }; | 307 SkRRect rr3; |
241 rr2_2.setRectRadii(rect, rr2_2_radii); | 308 rr3.setRectXY(rect, p.fX, p.fY); |
242 path_contains_rrect_check(reporter, rr2_2); | 309 path_contains_rrect_check(reporter, rr3, dir, start); |
243 SkRRect rr2_3; // construct the same RR using the nine patch set function | |
244 rr2_3.setNinePatch(rect, halfPoint.fX, halfPoint.fY, halfPoint.fX, halfPoint
.fY); | |
245 path_contains_rrect_check(reporter, rr2_3); | |
246 | 310 |
247 //---- | 311 SkRRect rr3_2; // construct the same RR using the most general set f
unction |
248 SkPoint p = { 5, 5 }; | 312 SkVector rr3_2_radii[4] = { { 5, 5 }, { 5, 5 }, { 5, 5 }, { 5, 5 } }
; |
249 SkRRect rr3; | 313 rr3_2.setRectRadii(rect, rr3_2_radii); |
250 rr3.setRectXY(rect, p.fX, p.fY); | 314 path_contains_rrect_check(reporter, rr3_2, dir, start); |
251 path_contains_rrect_check(reporter, rr3); | 315 SkRRect rr3_3; // construct the same RR using the nine patch set fu
nction |
| 316 rr3_3.setNinePatch(rect, 5, 5, 5, 5); |
| 317 path_contains_rrect_check(reporter, rr3_3, dir, start); |
252 | 318 |
253 SkRRect rr3_2; // construct the same RR using the most general set function | 319 //---- |
254 SkVector rr3_2_radii[4] = { { 5, 5 }, { 5, 5 }, { 5, 5 }, { 5, 5 } }; | 320 test_9patch_rrect(reporter, rect, 10, 9, 8, 7, true); |
255 rr3_2.setRectRadii(rect, rr3_2_radii); | |
256 path_contains_rrect_check(reporter, rr3_2); | |
257 SkRRect rr3_3; // construct the same RR using the nine patch set function | |
258 rr3_3.setNinePatch(rect, 5, 5, 5, 5); | |
259 path_contains_rrect_check(reporter, rr3_3); | |
260 | 321 |
261 //---- | 322 { |
262 test_9patch_rrect(reporter, rect, 10, 9, 8, 7, true); | 323 // Test out the rrect from skia:3466 |
| 324 SkRect rect2 = SkRect::MakeLTRB(0.358211994f, 0.755430222f, 0.87
2866154f, |
| 325 0.806214333f); |
263 | 326 |
264 { | 327 test_9patch_rrect(reporter, |
265 // Test out the rrect from skia:3466 | 328 rect2, |
266 SkRect rect2 = SkRect::MakeLTRB(0.358211994f, 0.755430222f, 0.872866154f
, 0.806214333f); | 329 0.926942348f, 0.642850280f, 0.529063463f, 0.58
7844372f, |
| 330 false); |
| 331 } |
267 | 332 |
268 test_9patch_rrect(reporter, | 333 //---- |
269 rect2, | 334 SkPoint radii2[4] = { { 0, 0 }, { 0, 0 }, { 50, 50 }, { 20, 50 } }; |
270 0.926942348f, 0.642850280f, 0.529063463f, 0.587844372f
, | 335 |
271 false); | 336 SkRRect rr5; |
| 337 rr5.setRectRadii(rect, radii2); |
| 338 path_contains_rrect_check(reporter, rr5, dir, start); |
| 339 } |
272 } | 340 } |
273 | |
274 //---- | |
275 SkPoint radii2[4] = { { 0, 0 }, { 0, 0 }, { 50, 50 }, { 20, 50 } }; | |
276 | |
277 SkRRect rr5; | |
278 rr5.setRectRadii(rect, radii2); | |
279 path_contains_rrect_check(reporter, rr5); | |
280 } | 341 } |
281 | 342 |
282 // Test out the cases when the RR degenerates to a rect | 343 // Test out the cases when the RR degenerates to a rect |
283 static void test_round_rect_rects(skiatest::Reporter* reporter) { | 344 static void test_round_rect_rects(skiatest::Reporter* reporter) { |
| 345 for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) { |
| 346 for (int start = 0; start < 8; ++start) { |
| 347 //---- |
| 348 SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); |
| 349 SkRRect rr1; |
| 350 rr1.setRectXY(rect, 0, 0); |
284 | 351 |
285 //---- | 352 path_contains_rrect_check(reporter, rr1, dir, start); |
286 SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); | |
287 SkRRect rr1; | |
288 rr1.setRectXY(rect, 0, 0); | |
289 | 353 |
290 path_contains_rrect_check(reporter, rr1); | 354 //---- |
| 355 SkPoint radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; |
291 | 356 |
292 //---- | 357 SkRRect rr2; |
293 SkPoint radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; | 358 rr2.setRectRadii(rect, radii); |
294 | 359 |
295 SkRRect rr2; | 360 path_contains_rrect_check(reporter, rr2, dir, start); |
296 rr2.setRectRadii(rect, radii); | |
297 | 361 |
298 path_contains_rrect_check(reporter, rr2); | 362 //---- |
| 363 SkPoint radii2[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } }
; |
299 | 364 |
300 //---- | 365 SkRRect rr3; |
301 SkPoint radii2[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } }; | 366 rr3.setRectRadii(rect, radii2); |
302 | 367 path_contains_rrect_check(reporter, rr3, dir, start); |
303 SkRRect rr3; | 368 } |
304 rr3.setRectRadii(rect, radii2); | 369 } |
305 path_contains_rrect_check(reporter, rr3); | |
306 } | 370 } |
307 | 371 |
308 // Test out the cases when the RR degenerates to an oval | 372 // Test out the cases when the RR degenerates to an oval |
309 static void test_round_rect_ovals(skiatest::Reporter* reporter) { | 373 static void test_round_rect_ovals(skiatest::Reporter* reporter) { |
310 //---- | 374 for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) { |
311 SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); | 375 for (int start = 0; start < 8; ++start) { |
312 SkRRect rr1; | 376 //---- |
313 rr1.setRectXY(rect, SkScalarHalf(kWidth), SkScalarHalf(kHeight)); | 377 SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); |
| 378 SkRRect rr1; |
| 379 rr1.setRectXY(rect, SkScalarHalf(kWidth), SkScalarHalf(kHeight)); |
314 | 380 |
315 path_contains_rrect_check(reporter, rr1); | 381 path_contains_rrect_check(reporter, rr1, dir, start); |
| 382 } |
| 383 } |
316 } | 384 } |
317 | 385 |
318 // Test out the non-degenerate RR cases | 386 // Test out the non-degenerate RR cases |
319 static void test_round_rect_general(skiatest::Reporter* reporter) { | 387 static void test_round_rect_general(skiatest::Reporter* reporter) { |
320 //---- | 388 for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) { |
321 SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); | 389 for (int start = 0; start < 8; ++start) { |
322 SkRRect rr1; | 390 //---- |
323 rr1.setRectXY(rect, 20, 20); | 391 SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); |
| 392 SkRRect rr1; |
| 393 rr1.setRectXY(rect, 20, 20); |
324 | 394 |
325 path_contains_rrect_check(reporter, rr1); | 395 path_contains_rrect_check(reporter, rr1, dir, start); |
326 | 396 |
327 //---- | 397 //---- |
328 SkPoint radii[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } }; | 398 SkPoint radii[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } }; |
329 | 399 |
330 SkRRect rr2; | 400 SkRRect rr2; |
331 rr2.setRectRadii(rect, radii); | 401 rr2.setRectRadii(rect, radii); |
332 | 402 |
333 path_contains_rrect_check(reporter, rr2); | 403 path_contains_rrect_check(reporter, rr2, dir, start); |
| 404 } |
| 405 } |
334 } | 406 } |
335 | 407 |
336 static void test_round_rect_iffy_parameters(skiatest::Reporter* reporter) { | 408 static void test_round_rect_iffy_parameters(skiatest::Reporter* reporter) { |
337 SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); | 409 for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) { |
338 SkPoint radii[4] = { { 50, 100 }, { 100, 50 }, { 50, 100 }, { 100, 50 } }; | 410 for (int start = 0; start < 8; ++start) { |
339 SkRRect rr1; | 411 SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); |
340 rr1.setRectRadii(rect, radii); | 412 SkPoint radii[4] = { { 50, 100 }, { 100, 50 }, { 50, 100 }, { 100, 5
0 } }; |
341 path_contains_rrect_nocheck(reporter, rr1); | 413 SkRRect rr1; |
| 414 rr1.setRectRadii(rect, radii); |
| 415 path_contains_rrect_nocheck(reporter, rr1, dir, start); |
| 416 } |
| 417 } |
342 } | 418 } |
343 | 419 |
344 static void set_radii(SkVector radii[4], int index, float rad) { | 420 static void set_radii(SkVector radii[4], int index, float rad) { |
345 sk_bzero(radii, sizeof(SkVector) * 4); | 421 sk_bzero(radii, sizeof(SkVector) * 4); |
346 radii[index].set(rad, rad); | 422 radii[index].set(rad, rad); |
347 } | 423 } |
348 | 424 |
349 static void test_skbug_3239(skiatest::Reporter* reporter) { | 425 static void test_skbug_3239(skiatest::Reporter* reporter) { |
350 const float min = SkBits2Float(0xcb7f16c8); /* -16717512.000000 */ | 426 const float min = SkBits2Float(0xcb7f16c8); /* -16717512.000000 */ |
351 const float max = SkBits2Float(0x4b7f1c1d); /* 16718877.000000 */ | 427 const float max = SkBits2Float(0x4b7f1c1d); /* 16718877.000000 */ |
352 const float big = SkBits2Float(0x4b7f1bd7); /* 16718807.000000 */ | 428 const float big = SkBits2Float(0x4b7f1bd7); /* 16718807.000000 */ |
353 | 429 |
354 const float rad = 33436320; | 430 const float rad = 33436320; |
355 | 431 |
356 const SkRect rectx = SkRect::MakeLTRB(min, min, max, big); | 432 const SkRect rectx = SkRect::MakeLTRB(min, min, max, big); |
357 const SkRect recty = SkRect::MakeLTRB(min, min, big, max); | 433 const SkRect recty = SkRect::MakeLTRB(min, min, big, max); |
358 | 434 |
359 SkVector radii[4]; | 435 for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) { |
360 for (int i = 0; i < 4; ++i) { | 436 for (int start = 0; start < 8; ++start) { |
361 set_radii(radii, i, rad); | 437 SkVector radii[4]; |
362 path_contains_rrect_check(reporter, rectx, radii); | 438 for (int i = 0; i < 4; ++i) { |
363 path_contains_rrect_check(reporter, recty, radii); | 439 set_radii(radii, i, rad); |
| 440 path_contains_rrect_check(reporter, rectx, radii, dir, start); |
| 441 path_contains_rrect_check(reporter, recty, radii, dir, start); |
| 442 } |
| 443 } |
364 } | 444 } |
365 } | 445 } |
366 | 446 |
367 static void test_mix(skiatest::Reporter* reporter) { | 447 static void test_mix(skiatest::Reporter* reporter) { |
368 // Test out mixed degenerate and non-degenerate geometry with Conics | 448 for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) { |
369 const SkVector radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 100, 100 } }; | 449 for (int start = 0; start < 8; ++start) { |
370 SkRect r = SkRect::MakeWH(100, 100); | 450 // Test out mixed degenerate and non-degenerate geometry with Conics |
371 SkRRect rr; | 451 const SkVector radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 100, 100
} }; |
372 rr.setRectRadii(r, radii); | 452 SkRect r = SkRect::MakeWH(100, 100); |
373 path_contains_rrect_check(reporter, rr); | 453 SkRRect rr; |
| 454 rr.setRectRadii(r, radii); |
| 455 path_contains_rrect_check(reporter, rr, dir, start); |
| 456 } |
| 457 } |
374 } | 458 } |
375 | 459 |
376 DEF_TEST(RoundRectInPath, reporter) { | 460 DEF_TEST(RoundRectInPath, reporter) { |
377 test_tricky_radii(reporter); | 461 test_tricky_radii(reporter); |
378 test_empty_crbug_458524(reporter); | 462 test_empty_crbug_458524(reporter); |
379 test_inset(reporter); | 463 test_inset(reporter); |
380 test_round_rect_basic(reporter); | 464 test_round_rect_basic(reporter); |
381 test_round_rect_rects(reporter); | 465 test_round_rect_rects(reporter); |
382 test_round_rect_ovals(reporter); | 466 test_round_rect_ovals(reporter); |
383 test_round_rect_general(reporter); | 467 test_round_rect_general(reporter); |
384 test_undetected_paths(reporter); | 468 test_undetected_paths(reporter); |
385 test_round_rect_iffy_parameters(reporter); | 469 test_round_rect_iffy_parameters(reporter); |
386 test_skbug_3239(reporter); | 470 test_skbug_3239(reporter); |
387 test_mix(reporter); | 471 test_mix(reporter); |
388 } | 472 } |
OLD | NEW |