Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 <initializer_list> | 8 #include <initializer_list> |
| 9 #include <functional> | 9 #include <functional> |
| 10 #include "Test.h" | 10 #include "Test.h" |
| 11 #if SK_SUPPORT_GPU | 11 #if SK_SUPPORT_GPU |
| 12 #include "GrShape.h" | 12 #include "GrShape.h" |
| 13 #include "SkCanvas.h" | 13 #include "SkCanvas.h" |
| 14 #include "SkDashPathEffect.h" | 14 #include "SkDashPathEffect.h" |
| 15 #include "SkPath.h" | 15 #include "SkPath.h" |
| 16 #include "SkPathOps.h" | |
| 16 #include "SkSurface.h" | 17 #include "SkSurface.h" |
| 17 | 18 |
| 18 using Key = SkTArray<uint32_t>; | 19 using Key = SkTArray<uint32_t>; |
| 19 | 20 |
| 20 static bool make_key(Key* key, const GrShape& shape) { | 21 static bool make_key(Key* key, const GrShape& shape) { |
| 21 int size = shape.unstyledKeySize(); | 22 int size = shape.unstyledKeySize(); |
| 22 if (size <= 0) { | 23 if (size <= 0) { |
| 23 key->reset(0); | 24 key->reset(0); |
| 24 return false; | 25 return false; |
| 25 } | 26 } |
| 26 SkASSERT(size); | 27 SkASSERT(size); |
| 27 key->reset(size); | 28 key->reset(size); |
| 28 shape.writeUnstyledKey(key->begin()); | 29 shape.writeUnstyledKey(key->begin()); |
| 29 return true; | 30 return true; |
| 30 } | 31 } |
| 31 | 32 |
| 33 static bool paths_fill_same(const SkPath& a, const SkPath& b) { | |
| 34 SkPath pathXor; | |
| 35 Op(a, b, SkPathOp::kXOR_SkPathOp, &pathXor); | |
| 36 return pathXor.isEmpty(); | |
| 37 } | |
| 38 | |
| 32 static bool test_bounds_by_rasterizing(const SkPath& path, const SkRect& bounds) { | 39 static bool test_bounds_by_rasterizing(const SkPath& path, const SkRect& bounds) { |
| 33 static constexpr int kRes = 2000; | 40 static constexpr int kRes = 2000; |
| 34 // This tolerance is in units of 1/kRes fractions of the bounds width/height . | 41 // This tolerance is in units of 1/kRes fractions of the bounds width/height . |
| 35 static constexpr int kTol = 0; | 42 static constexpr int kTol = 0; |
| 36 GR_STATIC_ASSERT(kRes % 4 == 0); | 43 GR_STATIC_ASSERT(kRes % 4 == 0); |
| 37 SkImageInfo info = SkImageInfo::MakeA8(kRes, kRes); | 44 SkImageInfo info = SkImageInfo::MakeA8(kRes, kRes); |
| 38 sk_sp<SkSurface> surface = SkSurface::MakeRaster(info); | 45 sk_sp<SkSurface> surface = SkSurface::MakeRaster(info); |
| 39 surface->getCanvas()->clear(0x0); | 46 surface->getCanvas()->clear(0x0); |
| 40 SkRect clip = SkRect::MakeXYWH(kRes/4, kRes/4, kRes/2, kRes/2); | 47 SkRect clip = SkRect::MakeXYWH(kRes/4, kRes/4, kRes/2, kRes/2); |
| 41 SkMatrix matrix; | 48 SkMatrix matrix; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 make_key(&fAppliedPEKey, fAppliedPE); | 134 make_key(&fAppliedPEKey, fAppliedPE); |
| 128 make_key(&fAppliedPEThenStrokeKey, fAppliedPEThenStroke); | 135 make_key(&fAppliedPEThenStrokeKey, fAppliedPEThenStroke); |
| 129 make_key(&fAppliedFullKey, fAppliedFull); | 136 make_key(&fAppliedFullKey, fAppliedFull); |
| 130 | 137 |
| 131 // Applying the path effect and then the stroke should always be the sam e as applying | 138 // Applying the path effect and then the stroke should always be the sam e as applying |
| 132 // both in one go. | 139 // both in one go. |
| 133 REPORTER_ASSERT(r, fAppliedPEThenStrokeKey == fAppliedFullKey); | 140 REPORTER_ASSERT(r, fAppliedPEThenStrokeKey == fAppliedFullKey); |
| 134 SkPath a, b; | 141 SkPath a, b; |
| 135 fAppliedPEThenStroke.asPath(&a); | 142 fAppliedPEThenStroke.asPath(&a); |
| 136 fAppliedFull.asPath(&b); | 143 fAppliedFull.asPath(&b); |
| 137 REPORTER_ASSERT(r, a == b); | 144 // If the output of the path effect is a rrect then it is possible for a and b to be |
| 145 // different paths that fill identically. The reason is that fAppliedFul l will do this: | |
| 146 // base -> apply path effect -> rrect_as_path -> stroke -> stroked_rrect _as_path | |
| 147 // fAppliedPEThenStroke will have converted the rrect_as_path back to a rrect. However, | |
| 148 // now that there is no longer a path effect, the direction and starting index get | |
| 149 // canonicalized before the stroke. | |
| 150 if (fAppliedPE.asRRect(nullptr, nullptr, nullptr)) { | |
| 151 REPORTER_ASSERT(r, paths_fill_same(a, b)); | |
| 152 } else { | |
| 153 REPORTER_ASSERT(r, a == b); | |
| 154 } | |
| 138 REPORTER_ASSERT(r, fAppliedFull.isEmpty() == fAppliedPEThenStroke.isEmpt y()); | 155 REPORTER_ASSERT(r, fAppliedFull.isEmpty() == fAppliedPEThenStroke.isEmpt y()); |
| 139 | 156 |
| 140 SkPath path; | 157 SkPath path; |
| 141 fBase.asPath(&path); | 158 fBase.asPath(&path); |
| 142 REPORTER_ASSERT(r, path.isEmpty() == fBase.isEmpty()); | 159 REPORTER_ASSERT(r, path.isEmpty() == fBase.isEmpty()); |
| 143 fAppliedPE.asPath(&path); | 160 fAppliedPE.asPath(&path); |
| 144 REPORTER_ASSERT(r, path.isEmpty() == fAppliedPE.isEmpty()); | 161 REPORTER_ASSERT(r, path.isEmpty() == fAppliedPE.isEmpty()); |
| 145 fAppliedFull.asPath(&path); | 162 fAppliedFull.asPath(&path); |
| 146 REPORTER_ASSERT(r, path.isEmpty() == fAppliedFull.isEmpty()); | 163 REPORTER_ASSERT(r, path.isEmpty() == fAppliedFull.isEmpty()); |
| 147 | 164 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 220 fAppliedPE.asPath(&b); | 237 fAppliedPE.asPath(&b); |
| 221 REPORTER_ASSERT(reporter, a == b); | 238 REPORTER_ASSERT(reporter, a == b); |
| 222 if (expectations.fStrokeApplies) { | 239 if (expectations.fStrokeApplies) { |
| 223 REPORTER_ASSERT(reporter, fBaseKey != fAppliedFullKey); | 240 REPORTER_ASSERT(reporter, fBaseKey != fAppliedFullKey); |
| 224 } else { | 241 } else { |
| 225 REPORTER_ASSERT(reporter, fBaseKey == fAppliedFullKey); | 242 REPORTER_ASSERT(reporter, fBaseKey == fAppliedFullKey); |
| 226 } | 243 } |
| 227 } | 244 } |
| 228 } | 245 } |
| 229 | 246 |
| 230 void TestCase::compare(skiatest::Reporter* reporter, const TestCase& that, | 247 void check_equivalence(skiatest::Reporter* r, const GrShape& a, const GrShape& b , |
| 248 const Key& keyA, const Key& keyB) { | |
| 249 // GrShape only respects that input winding direction and start point for rr ect shapes | |
| 250 // when there is a path effect. Thus, if there are two GrShapes representing the same rrect | |
| 251 // but one has a path effect in its style and the other doesn't then asPath( ) and the unstyled | |
| 252 // key will differ. GrShape will have canonicalized the direction and start point for the shape | |
| 253 // without the path effect. If *both* have path effects then they should hav e both preserve | |
| 254 // the direction and starting point. | |
| 255 SkRRect rrectA = SkRRect::MakeEmpty(), rrectB = SkRRect::MakeEmpty(); | |
| 256 SkPath::Direction dirA = SkPath::kCW_Direction, dirB = SkPath::kCW_Direction ; | |
| 257 unsigned startA = ~0U, startB = ~0U; | |
|
egdaniel
2016/06/06 18:34:36
comment that this initialization is for compiler
bsalomon
2016/06/06 19:41:29
Done.
| |
| 258 bool aIsRRect = a.asRRect(&rrectA, &dirA, &startA); | |
| 259 bool bIsRRect = b.asRRect(&rrectB, &dirB, &startB); | |
| 260 bool aHasPE = a.style().pathEffect(); | |
| 261 bool bHasPE = b.style().pathEffect(); | |
| 262 bool allowSameRRectButDiffStartAndDir = (aIsRRect && bIsRRect) && (aHasPE != bHasPE); | |
| 263 SkPath pathA, pathB; | |
| 264 a.asPath(&pathA); | |
| 265 b.asPath(&pathB); | |
| 266 if (allowSameRRectButDiffStartAndDir) { | |
| 267 REPORTER_ASSERT(r, aIsRRect && bIsRRect); | |
|
egdaniel
2016/06/06 18:34:36
is this check redundent with allowSameRRectBDSAD?
bsalomon
2016/06/06 19:41:29
Done.
| |
| 268 REPORTER_ASSERT(r, rrectA == rrectB); | |
| 269 REPORTER_ASSERT(r, paths_fill_same(pathA, pathB)); | |
| 270 } else { | |
| 271 REPORTER_ASSERT(r, pathA == pathB); | |
| 272 REPORTER_ASSERT(r, keyA == keyB); | |
| 273 REPORTER_ASSERT(r, aIsRRect == bIsRRect); | |
| 274 if (aIsRRect) { | |
| 275 REPORTER_ASSERT(r, rrectA == rrectB); | |
| 276 REPORTER_ASSERT(r, dirA == dirB); | |
| 277 REPORTER_ASSERT(r, startA == startB); | |
| 278 } | |
| 279 } | |
| 280 REPORTER_ASSERT(r, a.isEmpty() == b.isEmpty()); | |
| 281 REPORTER_ASSERT(r, a.knownToBeClosed() == b.knownToBeClosed()); | |
| 282 REPORTER_ASSERT(r, a.bounds() == b.bounds()); | |
| 283 } | |
| 284 | |
| 285 void TestCase::compare(skiatest::Reporter* r, const TestCase& that, | |
| 231 ComparisonExpecation expectation) const { | 286 ComparisonExpecation expectation) const { |
| 232 SkPath a, b; | 287 SkPath a, b; |
| 233 switch (expectation) { | 288 switch (expectation) { |
| 234 case kAllDifferent_ComparisonExpecation: | 289 case kAllDifferent_ComparisonExpecation: |
| 235 REPORTER_ASSERT(reporter, fBaseKey != that.fBaseKey); | 290 REPORTER_ASSERT(r, fBaseKey != that.fBaseKey); |
| 236 REPORTER_ASSERT(reporter, fAppliedPEKey != that.fAppliedPEKey); | 291 REPORTER_ASSERT(r, fAppliedPEKey != that.fAppliedPEKey); |
| 237 REPORTER_ASSERT(reporter, fAppliedFullKey != that.fAppliedFullKey); | 292 REPORTER_ASSERT(r, fAppliedFullKey != that.fAppliedFullKey); |
| 238 break; | 293 break; |
| 239 case kSameUpToPE_ComparisonExpecation: | 294 case kSameUpToPE_ComparisonExpecation: |
| 240 REPORTER_ASSERT(reporter, fBaseKey == that.fBaseKey); | 295 check_equivalence(r, fBase, that.fBase, fBaseKey, that.fBaseKey); |
| 241 fBase.asPath(&a); | 296 REPORTER_ASSERT(r, fAppliedPEKey != that.fAppliedPEKey); |
| 242 that.fBase.asPath(&b); | 297 REPORTER_ASSERT(r, fAppliedFullKey != that.fAppliedFullKey); |
| 243 REPORTER_ASSERT(reporter, a == b); | |
| 244 REPORTER_ASSERT(reporter, fBase.isEmpty() == that.fBase.isEmpty()); | |
| 245 REPORTER_ASSERT(reporter, fAppliedPEKey != that.fAppliedPEKey); | |
| 246 REPORTER_ASSERT(reporter, fAppliedFullKey != that.fAppliedFullKey); | |
| 247 break; | 298 break; |
| 248 case kSameUpToStroke_ComparisonExpecation: | 299 case kSameUpToStroke_ComparisonExpecation: |
| 249 REPORTER_ASSERT(reporter, fBaseKey == that.fBaseKey); | 300 check_equivalence(r, fBase, that.fBase, fBaseKey, that.fBaseKey); |
| 250 fBase.asPath(&a); | 301 check_equivalence(r, fAppliedPE, that.fAppliedPE, fAppliedPEKey, tha t.fAppliedPEKey); |
| 251 that.fBase.asPath(&b); | 302 REPORTER_ASSERT(r, fAppliedFullKey != that.fAppliedFullKey); |
| 252 REPORTER_ASSERT(reporter, a == b); | |
| 253 REPORTER_ASSERT(reporter, fBase.isEmpty() == that.fBase.isEmpty()); | |
| 254 REPORTER_ASSERT(reporter, fAppliedPEKey == that.fAppliedPEKey); | |
| 255 fAppliedPE.asPath(&a); | |
| 256 that.fAppliedPE.asPath(&b); | |
| 257 REPORTER_ASSERT(reporter, a == b); | |
| 258 REPORTER_ASSERT(reporter, fAppliedPE.isEmpty() == that.fAppliedPE.is Empty()); | |
| 259 REPORTER_ASSERT(reporter, fAppliedFullKey != that.fAppliedFullKey); | |
| 260 break; | 303 break; |
| 261 case kAllSame_ComparisonExpecation: | 304 case kAllSame_ComparisonExpecation: |
| 262 REPORTER_ASSERT(reporter, fBaseKey == that.fBaseKey); | 305 check_equivalence(r, fBase, that.fBase, fBaseKey, that.fBaseKey); |
| 263 fBase.asPath(&a); | 306 check_equivalence(r, fAppliedPE, that.fAppliedPE, fAppliedPEKey, tha t.fAppliedPEKey); |
| 264 that.fBase.asPath(&b); | 307 check_equivalence(r, fAppliedFull, that.fAppliedFull, fAppliedFullKe y, |
| 265 REPORTER_ASSERT(reporter, a == b); | 308 that.fAppliedFullKey); |
| 266 REPORTER_ASSERT(reporter, fBase.isEmpty() == that.fBase.isEmpty()); | |
| 267 REPORTER_ASSERT(reporter, fAppliedPEKey == that.fAppliedPEKey); | |
| 268 fAppliedPE.asPath(&a); | |
| 269 that.fAppliedPE.asPath(&b); | |
| 270 REPORTER_ASSERT(reporter, a == b); | |
| 271 REPORTER_ASSERT(reporter, fAppliedPE.isEmpty() == that.fAppliedPE.is Empty()); | |
| 272 REPORTER_ASSERT(reporter, fAppliedFullKey == that.fAppliedFullKey); | |
| 273 fAppliedFull.asPath(&a); | |
| 274 that.fAppliedFull.asPath(&b); | |
| 275 REPORTER_ASSERT(reporter, a == b); | |
| 276 REPORTER_ASSERT(reporter, fAppliedFull.isEmpty() == that.fAppliedFul l.isEmpty()); | |
| 277 break; | 309 break; |
| 278 } | 310 } |
| 279 } | 311 } |
| 280 } // namespace | 312 } // namespace |
| 281 | 313 |
| 282 static sk_sp<SkPathEffect> make_dash() { | 314 static sk_sp<SkPathEffect> make_dash() { |
| 283 static const SkScalar kIntervals[] = { 0.25, 3.f, 0.5, 2.f }; | 315 static const SkScalar kIntervals[] = { 0.25, 3.f, 0.5, 2.f }; |
| 284 static const SkScalar kPhase = 0.75; | 316 static const SkScalar kPhase = 0.75; |
| 285 return SkDashPathEffect::Make(kIntervals, SK_ARRAY_COUNT(kIntervals), kPhase ); | 317 return SkDashPathEffect::Make(kIntervals, SK_ARRAY_COUNT(kIntervals), kPhase ); |
| 286 } | 318 } |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 strokeDashCase1.compare(reporter, strokeDashCase2, TestCase::kSameUpToPE_Co mparisonExpecation); | 444 strokeDashCase1.compare(reporter, strokeDashCase2, TestCase::kSameUpToPE_Co mparisonExpecation); |
| 413 | 445 |
| 414 // Stroke and fill cases | 446 // Stroke and fill cases |
| 415 SkPaint strokeAndFill = stroke; | 447 SkPaint strokeAndFill = stroke; |
| 416 strokeAndFill.setStyle(SkPaint::kStrokeAndFill_Style); | 448 strokeAndFill.setStyle(SkPaint::kStrokeAndFill_Style); |
| 417 TestCase strokeAndFillCase1(geo, strokeAndFill, reporter, kS1); | 449 TestCase strokeAndFillCase1(geo, strokeAndFill, reporter, kS1); |
| 418 TestCase strokeAndFillCase2(geo, strokeAndFill, reporter, kS2); | 450 TestCase strokeAndFillCase2(geo, strokeAndFill, reporter, kS2); |
| 419 // Scale affects the stroke. Though, this can wind up creating a rect when t he input is a rect. | 451 // Scale affects the stroke. Though, this can wind up creating a rect when t he input is a rect. |
| 420 // In that case we wind up with a pure geometry key and the geometries are t he same. | 452 // In that case we wind up with a pure geometry key and the geometries are t he same. |
| 421 SkRRect rrect; | 453 SkRRect rrect; |
| 422 if (strokeAndFillCase1.appliedFullStyleShape().asRRect(&rrect)) { | 454 if (strokeAndFillCase1.appliedFullStyleShape().asRRect(&rrect, nullptr, null ptr)) { |
| 423 // We currently only expect to get here in the rect->rect case. | 455 // We currently only expect to get here in the rect->rect case. |
| 424 REPORTER_ASSERT(reporter, rrect.isRect()); | 456 REPORTER_ASSERT(reporter, rrect.isRect()); |
| 425 REPORTER_ASSERT(reporter, strokeAndFillCase1.baseShape().asRRect(&rrect) && rrect.isRect()); | 457 REPORTER_ASSERT(reporter, |
| 458 strokeAndFillCase1.baseShape().asRRect(&rrect, nullptr, nullptr) && | |
| 459 rrect.isRect()); | |
| 426 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, | 460 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, |
| 427 TestCase::kAllSame_ComparisonExpecation); | 461 TestCase::kAllSame_ComparisonExpecation); |
| 428 } else { | 462 } else { |
| 429 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, | 463 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, |
| 430 TestCase::kSameUpToStroke_ComparisonExpecatio n); | 464 TestCase::kSameUpToStroke_ComparisonExpecatio n); |
| 431 } | 465 } |
| 432 | 466 |
| 433 SkPaint strokeAndFillDash = strokeDash; | 467 SkPaint strokeAndFillDash = strokeDash; |
| 434 strokeAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style); | 468 strokeAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style); |
| 435 TestCase strokeAndFillDashCase1(geo, strokeAndFillDash, reporter, kS1); | 469 TestCase strokeAndFillDashCase1(geo, strokeAndFillDash, reporter, kS1); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 654 TestCase::kSameUpToStroke_ComparisonExpecation); | 688 TestCase::kSameUpToStroke_ComparisonExpecation); |
| 655 | 689 |
| 656 TestCase rrectFillCase(RRectPathEffect::RRect(), fill, reporter); | 690 TestCase rrectFillCase(RRectPathEffect::RRect(), fill, reporter); |
| 657 SkPaint stroke = peStroke; | 691 SkPaint stroke = peStroke; |
| 658 stroke.setPathEffect(nullptr); | 692 stroke.setPathEffect(nullptr); |
| 659 TestCase rrectStrokeCase(RRectPathEffect::RRect(), stroke, reporter); | 693 TestCase rrectStrokeCase(RRectPathEffect::RRect(), stroke, reporter); |
| 660 | 694 |
| 661 SkRRect rrect; | 695 SkRRect rrect; |
| 662 // Applying the path effect should make a SkRRect shape. There is no further stroking in the | 696 // Applying the path effect should make a SkRRect shape. There is no further stroking in the |
| 663 // geoPECase, so the full style should be the same as just the PE. | 697 // geoPECase, so the full style should be the same as just the PE. |
| 664 REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectShape().asRRect(&rrect) ); | 698 REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectShape().asRRect(&rrect, nullptr, nullptr)); |
| 665 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); | 699 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); |
| 666 REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectKey() == rrectFillCase. baseKey()); | 700 REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectKey() == rrectFillCase. baseKey()); |
| 667 | 701 |
| 668 REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleShape().asRRect(&rrect)) ; | 702 REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleShape().asRRect(&rrect, nullptr, nullptr)); |
| 669 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); | 703 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); |
| 670 REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleKey() == rrectFillCase.b aseKey()); | 704 REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleKey() == rrectFillCase.b aseKey()); |
| 671 | 705 |
| 672 // In the PE+stroke case applying the full style should be the same as just stroking the rrect. | 706 // In the PE+stroke case applying the full style should be the same as just stroking the rrect. |
| 673 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectShape().asRRect(& rrect)); | 707 REPORTER_ASSERT(reporter, |
| 708 geoPEStrokeCase.appliedPathEffectShape().asRRect(&rrect, nul lptr, nullptr)); | |
| 674 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); | 709 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); |
| 675 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectKey() == rrectFil lCase.baseKey()); | 710 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectKey() == rrectFil lCase.baseKey()); |
| 676 | 711 |
| 677 REPORTER_ASSERT(reporter, !geoPEStrokeCase.appliedFullStyleShape().asRRect(& rrect)); | 712 REPORTER_ASSERT(reporter, |
| 713 !geoPEStrokeCase.appliedFullStyleShape().asRRect(&rrect, nul lptr, nullptr)); | |
| 678 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleKey() == | 714 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleKey() == |
| 679 rrectStrokeCase.appliedFullStyleKey()); | 715 rrectStrokeCase.appliedFullStyleKey()); |
| 680 } | 716 } |
| 681 | 717 |
| 682 template <typename GEO> | 718 template <typename GEO> |
| 683 void test_unknown_path_effect(skiatest::Reporter* reporter, const GEO& geo) { | 719 void test_unknown_path_effect(skiatest::Reporter* reporter, const GEO& geo) { |
| 684 /** | 720 /** |
| 685 * This path effect just adds two lineTos to the input path. | 721 * This path effect just adds two lineTos to the input path. |
| 686 */ | 722 */ |
| 687 class AddLineTosPathEffect : SkPathEffect { | 723 class AddLineTosPathEffect : SkPathEffect { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 742 private: | 778 private: |
| 743 MakeHairlinePathEffect() {} | 779 MakeHairlinePathEffect() {} |
| 744 }; | 780 }; |
| 745 | 781 |
| 746 SkPaint fill; | 782 SkPaint fill; |
| 747 SkPaint pe; | 783 SkPaint pe; |
| 748 pe.setPathEffect(MakeHairlinePathEffect::Make()); | 784 pe.setPathEffect(MakeHairlinePathEffect::Make()); |
| 749 | 785 |
| 750 TestCase peCase(geo, pe, reporter); | 786 TestCase peCase(geo, pe, reporter); |
| 751 | 787 |
| 752 SkPath a, b; | 788 SkPath a, b, c; |
| 753 peCase.baseShape().asPath(&a); | 789 peCase.baseShape().asPath(&a); |
| 754 peCase.appliedPathEffectShape().asPath(&b); | 790 peCase.appliedPathEffectShape().asPath(&b); |
| 755 REPORTER_ASSERT(reporter, a == b); | 791 peCase.appliedFullStyleShape().asPath(&c); |
| 756 peCase.appliedFullStyleShape().asPath(&b); | |
| 757 REPORTER_ASSERT(reporter, a == b); | |
| 758 REPORTER_ASSERT(reporter, peCase.appliedPathEffectShape().style().isSimpleHa irline()); | |
| 759 REPORTER_ASSERT(reporter, peCase.appliedFullStyleShape().style().isSimpleHai rline()); | |
| 760 if (isNonPath) { | 792 if (isNonPath) { |
| 761 REPORTER_ASSERT(reporter, peCase.appliedPathEffectKey() == peCase.baseKe y()); | 793 // RRect types can have a change in start index or direction after the P E is applied. This |
| 762 REPORTER_ASSERT(reporter, peCase.appliedFullStyleKey() == peCase.baseKey ()); | 794 // is because once the PE is applied, GrShape may canonicalize the dir a nd index since it |
| 795 // is not germane to the styling any longer. | |
| 796 // Instead we just check that the paths would fill the same both before and after styling. | |
| 797 REPORTER_ASSERT(reporter, paths_fill_same(a, b)); | |
| 798 REPORTER_ASSERT(reporter, paths_fill_same(a, c)); | |
| 763 } else { | 799 } else { |
| 800 REPORTER_ASSERT(reporter, a == b); | |
| 801 REPORTER_ASSERT(reporter, a == c); | |
| 764 REPORTER_ASSERT(reporter, peCase.appliedPathEffectKey().empty()); | 802 REPORTER_ASSERT(reporter, peCase.appliedPathEffectKey().empty()); |
| 765 REPORTER_ASSERT(reporter, peCase.appliedFullStyleKey().empty()); | 803 REPORTER_ASSERT(reporter, peCase.appliedFullStyleKey().empty()); |
| 766 } | 804 } |
| 805 REPORTER_ASSERT(reporter, peCase.appliedPathEffectShape().style().isSimpleHa irline()); | |
| 806 REPORTER_ASSERT(reporter, peCase.appliedFullStyleShape().style().isSimpleHai rline()); | |
| 767 } | 807 } |
| 768 | 808 |
| 769 /** | 809 /** |
| 770 * isNonPath indicates whether the initial shape made from the path is expected to be recognized | 810 * isNonPath indicates whether the initial shape made from the path is expected to be recognized |
| 771 * as a simpler shape type (e.g. rrect) | 811 * as a simpler shape type (e.g. rrect) |
| 772 */ | 812 */ |
| 773 void test_volatile_path(skiatest::Reporter* reporter, const SkPath& path, | 813 void test_volatile_path(skiatest::Reporter* reporter, const SkPath& path, |
| 774 bool isNonPath) { | 814 bool isNonPath) { |
| 775 SkPath vPath(path); | 815 SkPath vPath(path); |
| 776 vPath.setIsVolatile(true); | 816 vPath.setIsVolatile(true); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 887 TestCase::kAllSame_ComparisonExpecation) ; | 927 TestCase::kAllSame_ComparisonExpecation) ; |
| 888 | 928 |
| 889 // Same for a rect. | 929 // Same for a rect. |
| 890 SkRect emptyRect = SkRect::MakeEmpty(); | 930 SkRect emptyRect = SkRect::MakeEmpty(); |
| 891 TestCase dashAndStrokeEmptyRectCase(emptyRect, dashAndStroke, reporter); | 931 TestCase dashAndStrokeEmptyRectCase(emptyRect, dashAndStroke, reporter); |
| 892 dashAndStrokeEmptyRectCase.compare(reporter, fillEmptyCase, | 932 dashAndStrokeEmptyRectCase.compare(reporter, fillEmptyCase, |
| 893 TestCase::kAllSame_ComparisonExpecation); | 933 TestCase::kAllSame_ComparisonExpecation); |
| 894 } | 934 } |
| 895 | 935 |
| 896 DEF_TEST(GrShape, reporter) { | 936 DEF_TEST(GrShape, reporter) { |
| 897 sk_sp<SkPathEffect> dashPE = make_dash(); | 937 for (auto r : { SkRect::MakeWH(10, 20), |
| 938 SkRect::MakeWH(-10, -20), | |
| 939 SkRect::MakeWH(-10, 20), | |
| 940 SkRect::MakeWH(10, -20)}) { | |
| 941 test_basic(reporter, r); | |
| 942 test_scale(reporter, r); | |
| 943 test_dash_fill(reporter, r); | |
| 944 test_null_dash(reporter, r); | |
| 945 // Test modifying various stroke params. | |
| 946 test_stroke_param<SkRect, SkScalar>( | |
| 947 reporter, r, | |
| 948 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, | |
| 949 SkIntToScalar(2), SkIntToScalar(4)); | |
| 950 test_stroke_param<SkRect, SkPaint::Join>( | |
| 951 reporter, r, | |
| 952 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);}, | |
| 953 SkPaint::kMiter_Join, SkPaint::kRound_Join); | |
| 954 test_stroke_cap(reporter, r); | |
| 955 test_miter_limit(reporter, r); | |
| 956 test_path_effect_makes_rrect(reporter, r); | |
| 957 test_unknown_path_effect(reporter, r); | |
| 958 test_path_effect_makes_empty_shape(reporter, r); | |
| 959 test_make_hairline_path_effect(reporter, r, true); | |
| 960 } | |
| 898 | 961 |
| 899 for (auto rr : { SkRRect::MakeRect(SkRect::MakeWH(10, 10)), | 962 for (auto rr : { SkRRect::MakeRect(SkRect::MakeWH(10, 10)), |
| 900 SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4)}) { | 963 SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4), |
| 964 SkRRect::MakeOval(SkRect::MakeWH(20, 20))}) { | |
| 901 test_basic(reporter, rr); | 965 test_basic(reporter, rr); |
| 902 test_scale(reporter, rr); | 966 test_scale(reporter, rr); |
| 903 test_dash_fill(reporter, rr); | 967 test_dash_fill(reporter, rr); |
| 904 test_null_dash(reporter, rr); | 968 test_null_dash(reporter, rr); |
| 905 // Test modifying various stroke params. | 969 // Test modifying various stroke params. |
| 906 test_stroke_param<SkRRect, SkScalar>( | 970 test_stroke_param<SkRRect, SkScalar>( |
| 907 reporter, rr, | 971 reporter, rr, |
| 908 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, | 972 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, |
| 909 SkIntToScalar(2), SkIntToScalar(4)); | 973 SkIntToScalar(2), SkIntToScalar(4)); |
| 910 test_stroke_param<SkRRect, SkPaint::Join>( | 974 test_stroke_param<SkRRect, SkPaint::Join>( |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 977 test_stroke_cap(reporter, path); | 1041 test_stroke_cap(reporter, path); |
| 978 test_miter_limit(reporter, path); | 1042 test_miter_limit(reporter, path); |
| 979 test_unknown_path_effect(reporter, path); | 1043 test_unknown_path_effect(reporter, path); |
| 980 test_path_effect_makes_empty_shape(reporter, path); | 1044 test_path_effect_makes_empty_shape(reporter, path); |
| 981 test_make_hairline_path_effect(reporter, path, testPath.fIsRRectForStrok e); | 1045 test_make_hairline_path_effect(reporter, path, testPath.fIsRRectForStrok e); |
| 982 | 1046 |
| 983 SkPaint fillPaint; | 1047 SkPaint fillPaint; |
| 984 TestCase fillPathCase(path, fillPaint, reporter); | 1048 TestCase fillPathCase(path, fillPaint, reporter); |
| 985 SkRRect rrect; | 1049 SkRRect rrect; |
| 986 REPORTER_ASSERT(reporter, testPath.fIsRRectForFill == | 1050 REPORTER_ASSERT(reporter, testPath.fIsRRectForFill == |
| 987 fillPathCase.baseShape().asRRect(&rrect)); | 1051 fillPathCase.baseShape().asRRect(&rrect, nullp tr, nullptr)); |
| 988 if (testPath.fIsRRectForFill) { | 1052 if (testPath.fIsRRectForFill) { |
| 1053 TestCase fillPathCase2(path, fillPaint, reporter); | |
| 989 REPORTER_ASSERT(reporter, rrect == testPath.fRRect); | 1054 REPORTER_ASSERT(reporter, rrect == testPath.fRRect); |
| 990 TestCase fillRRectCase(rrect, fillPaint, reporter); | 1055 TestCase fillRRectCase(rrect, fillPaint, reporter); |
| 991 fillPathCase.compare(reporter, fillRRectCase, TestCase::kAllSame_Com parisonExpecation); | 1056 fillPathCase2.compare(reporter, fillRRectCase, TestCase::kAllSame_Co mparisonExpecation); |
| 992 } | 1057 } |
| 993 | 1058 |
| 994 SkPaint strokePaint; | 1059 SkPaint strokePaint; |
| 995 strokePaint.setStrokeWidth(3.f); | 1060 strokePaint.setStrokeWidth(3.f); |
| 996 strokePaint.setStyle(SkPaint::kStroke_Style); | 1061 strokePaint.setStyle(SkPaint::kStroke_Style); |
| 997 TestCase strokePathCase(path, strokePaint, reporter); | 1062 TestCase strokePathCase(path, strokePaint, reporter); |
| 998 REPORTER_ASSERT(reporter, testPath.fIsRRectForStroke == | 1063 REPORTER_ASSERT(reporter, testPath.fIsRRectForStroke == |
| 999 strokePathCase.baseShape().asRRect(&rrect)); | 1064 strokePathCase.baseShape().asRRect(&rrect, nul lptr, nullptr)); |
| 1000 if (testPath.fIsRRectForStroke) { | 1065 if (testPath.fIsRRectForStroke) { |
| 1001 REPORTER_ASSERT(reporter, rrect == testPath.fRRect); | 1066 REPORTER_ASSERT(reporter, rrect == testPath.fRRect); |
| 1002 TestCase strokeRRectCase(rrect, strokePaint, reporter); | 1067 TestCase strokeRRectCase(rrect, strokePaint, reporter); |
| 1003 strokePathCase.compare(reporter, strokeRRectCase, | 1068 strokePathCase.compare(reporter, strokeRRectCase, |
| 1004 TestCase::kAllSame_ComparisonExpecation); | 1069 TestCase::kAllSame_ComparisonExpecation); |
| 1005 } | 1070 } |
| 1006 } | 1071 } |
| 1007 | 1072 |
| 1008 // Test a volatile empty path. | 1073 // Test a volatile empty path. |
| 1009 test_volatile_path(reporter, SkPath(), true); | 1074 test_volatile_path(reporter, SkPath(), true); |
| 1010 | 1075 |
| 1011 test_empty_shape(reporter); | 1076 test_empty_shape(reporter); |
| 1012 } | 1077 } |
| 1013 | 1078 |
| 1014 #endif | 1079 #endif |
| OLD | NEW |