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" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 | 75 |
76 namespace { | 76 namespace { |
77 class TestCase { | 77 class TestCase { |
78 public: | 78 public: |
79 template <typename GEO> | 79 template <typename GEO> |
80 TestCase(const GEO& geo, const SkPaint& paint, skiatest::Reporter* r, | 80 TestCase(const GEO& geo, const SkPaint& paint, skiatest::Reporter* r, |
81 SkScalar scale = SK_Scalar1) : fBase(geo, paint) { | 81 SkScalar scale = SK_Scalar1) : fBase(geo, paint) { |
82 this->init(r, scale); | 82 this->init(r, scale); |
83 } | 83 } |
84 | 84 |
| 85 TestCase(const GrShape& shape, skiatest::Reporter* r, SkScalar scale = SK_Sc
alar1) |
| 86 : fBase(shape) { |
| 87 this->init(r, scale); |
| 88 } |
| 89 |
85 struct SelfExpectations { | 90 struct SelfExpectations { |
86 bool fPEHasEffect; | 91 bool fPEHasEffect; |
87 bool fPEHasValidKey; | 92 bool fPEHasValidKey; |
88 bool fStrokeApplies; | 93 bool fStrokeApplies; |
89 }; | 94 }; |
90 | 95 |
91 void testExpectations(skiatest::Reporter* reporter, SelfExpectations expecta
tions) const; | 96 void testExpectations(skiatest::Reporter* reporter, SelfExpectations expecta
tions) const; |
92 | 97 |
93 enum ComparisonExpecation { | 98 enum ComparisonExpecation { |
94 kAllDifferent_ComparisonExpecation, | 99 kAllDifferent_ComparisonExpecation, |
(...skipping 19 matching lines...) Expand all Loading... |
114 SkPath path; | 119 SkPath path; |
115 shape.asPath(&path); | 120 shape.asPath(&path); |
116 // If the bounds are empty, the path ought to be as well. | 121 // If the bounds are empty, the path ought to be as well. |
117 if (bounds.isEmpty()) { | 122 if (bounds.isEmpty()) { |
118 REPORTER_ASSERT(r, path.isEmpty()); | 123 REPORTER_ASSERT(r, path.isEmpty()); |
119 return; | 124 return; |
120 } | 125 } |
121 if (path.isEmpty()) { | 126 if (path.isEmpty()) { |
122 return; | 127 return; |
123 } | 128 } |
124 REPORTER_ASSERT(r, test_bounds_by_rasterizing(path, bounds)); | 129 // The bounds API explicitly calls out that it does not consider inverse
ness. |
| 130 SkPath p = path; |
| 131 p.setFillType(SkPath::ConvertToNonInverseFillType(path.getFillType())); |
| 132 REPORTER_ASSERT(r, test_bounds_by_rasterizing(p, bounds)); |
125 } | 133 } |
126 | 134 |
127 void init(skiatest::Reporter* r, SkScalar scale) { | 135 void init(skiatest::Reporter* r, SkScalar scale) { |
128 fAppliedPE = fBase.applyStyle(GrStyle::Apply::kPathEffectOnly,
scale); | 136 fAppliedPE = fBase.applyStyle(GrStyle::Apply::kPathEffectOnly,
scale); |
129 fAppliedPEThenStroke = fAppliedPE.applyStyle(GrStyle::Apply::kPathEffect
AndStrokeRec, | 137 fAppliedPEThenStroke = fAppliedPE.applyStyle(GrStyle::Apply::kPathEffect
AndStrokeRec, |
130 scale); | 138 scale); |
131 fAppliedFull = fBase.applyStyle(GrStyle::Apply::kPathEffectAndSt
rokeRec, scale); | 139 fAppliedFull = fBase.applyStyle(GrStyle::Apply::kPathEffectAndSt
rokeRec, scale); |
132 | 140 |
133 make_key(&fBaseKey, fBase); | 141 make_key(&fBaseKey, fBase); |
134 make_key(&fAppliedPEKey, fAppliedPE); | 142 make_key(&fAppliedPEKey, fAppliedPE); |
135 make_key(&fAppliedPEThenStrokeKey, fAppliedPEThenStroke); | 143 make_key(&fAppliedPEThenStrokeKey, fAppliedPEThenStroke); |
136 make_key(&fAppliedFullKey, fAppliedFull); | 144 make_key(&fAppliedFullKey, fAppliedFull); |
137 | 145 |
138 // Applying the path effect and then the stroke should always be the sam
e as applying | 146 // Applying the path effect and then the stroke should always be the sam
e as applying |
139 // both in one go. | 147 // both in one go. |
140 REPORTER_ASSERT(r, fAppliedPEThenStrokeKey == fAppliedFullKey); | 148 REPORTER_ASSERT(r, fAppliedPEThenStrokeKey == fAppliedFullKey); |
141 SkPath a, b; | 149 SkPath a, b; |
142 fAppliedPEThenStroke.asPath(&a); | 150 fAppliedPEThenStroke.asPath(&a); |
143 fAppliedFull.asPath(&b); | 151 fAppliedFull.asPath(&b); |
144 // If the output of the path effect is a rrect then it is possible for a
and b to be | 152 // 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: | 153 // 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 | 154 // 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, | 155 // 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 | 156 // now that there is no longer a path effect, the direction and starting
index get |
149 // canonicalized before the stroke. | 157 // canonicalized before the stroke. |
150 if (fAppliedPE.asRRect(nullptr, nullptr, nullptr)) { | 158 if (fAppliedPE.asRRect(nullptr, nullptr, nullptr, nullptr)) { |
151 REPORTER_ASSERT(r, paths_fill_same(a, b)); | 159 REPORTER_ASSERT(r, paths_fill_same(a, b)); |
152 } else { | 160 } else { |
153 REPORTER_ASSERT(r, a == b); | 161 REPORTER_ASSERT(r, a == b); |
154 } | 162 } |
155 REPORTER_ASSERT(r, fAppliedFull.isEmpty() == fAppliedPEThenStroke.isEmpt
y()); | 163 REPORTER_ASSERT(r, fAppliedFull.isEmpty() == fAppliedPEThenStroke.isEmpt
y()); |
156 | 164 |
157 SkPath path; | 165 SkPath path; |
158 fBase.asPath(&path); | 166 fBase.asPath(&path); |
159 REPORTER_ASSERT(r, path.isEmpty() == fBase.isEmpty()); | 167 REPORTER_ASSERT(r, path.isEmpty() == fBase.isEmpty()); |
160 REPORTER_ASSERT(r, path.getSegmentMasks() == fBase.segmentMask()); | 168 REPORTER_ASSERT(r, path.getSegmentMasks() == fBase.segmentMask()); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 // but one has a path effect in its style and the other doesn't then asPath(
) and the unstyled | 262 // but one has a path effect in its style and the other doesn't then asPath(
) and the unstyled |
255 // key will differ. GrShape will have canonicalized the direction and start
point for the shape | 263 // key will differ. GrShape will have canonicalized the direction and start
point for the shape |
256 // without the path effect. If *both* have path effects then they should hav
e both preserved | 264 // without the path effect. If *both* have path effects then they should hav
e both preserved |
257 // the direction and starting point. | 265 // the direction and starting point. |
258 | 266 |
259 // The asRRect() output params are all initialized just to silence compiler
warnings about | 267 // The asRRect() output params are all initialized just to silence compiler
warnings about |
260 // uninitialized variables. | 268 // uninitialized variables. |
261 SkRRect rrectA = SkRRect::MakeEmpty(), rrectB = SkRRect::MakeEmpty(); | 269 SkRRect rrectA = SkRRect::MakeEmpty(), rrectB = SkRRect::MakeEmpty(); |
262 SkPath::Direction dirA = SkPath::kCW_Direction, dirB = SkPath::kCW_Direction
; | 270 SkPath::Direction dirA = SkPath::kCW_Direction, dirB = SkPath::kCW_Direction
; |
263 unsigned startA = ~0U, startB = ~0U; | 271 unsigned startA = ~0U, startB = ~0U; |
| 272 bool invertedA = true, invertedB = true; |
264 | 273 |
265 bool aIsRRect = a.asRRect(&rrectA, &dirA, &startA); | 274 bool aIsRRect = a.asRRect(&rrectA, &dirA, &startA, &invertedA); |
266 bool bIsRRect = b.asRRect(&rrectB, &dirB, &startB); | 275 bool bIsRRect = b.asRRect(&rrectB, &dirB, &startB, &invertedB); |
267 bool aHasPE = a.style().hasPathEffect(); | 276 bool aHasPE = a.style().hasPathEffect(); |
268 bool bHasPE = b.style().hasPathEffect(); | 277 bool bHasPE = b.style().hasPathEffect(); |
269 bool allowSameRRectButDiffStartAndDir = (aIsRRect && bIsRRect) && (aHasPE !=
bHasPE); | 278 bool allowSameRRectButDiffStartAndDir = (aIsRRect && bIsRRect) && (aHasPE !=
bHasPE); |
| 279 |
270 SkPath pathA, pathB; | 280 SkPath pathA, pathB; |
271 a.asPath(&pathA); | 281 a.asPath(&pathA); |
272 b.asPath(&pathB); | 282 b.asPath(&pathB); |
| 283 |
| 284 // Having a fill style or non-dash path effect can prevent 'a' but not 'b' f
rom turning an |
| 285 // inverse fill type into a non-inverse fill type. |
| 286 bool ignoreInversenessDifference = false; |
| 287 if (pathA.isInverseFillType() != pathB.isInverseFillType()) { |
| 288 const GrShape* s1 = pathA.isInverseFillType() ? &a : &b; |
| 289 const GrShape* s2 = pathA.isInverseFillType() ? &b : &a; |
| 290 SkStrokeRec::Style style1 = s1->style().strokeRec().getStyle(); |
| 291 SkStrokeRec::Style style2 = s2->style().strokeRec().getStyle(); |
| 292 bool canDropInverse1 = !s1->style().hasNonDashPathEffect() && |
| 293 (SkStrokeRec::kStroke_Style == style1 || |
| 294 SkStrokeRec::kHairline_Style == style1); |
| 295 bool canDropInverse2 = !s2->style().hasNonDashPathEffect() && |
| 296 (SkStrokeRec::kStroke_Style == style2 || |
| 297 SkStrokeRec::kHairline_Style == style2); |
| 298 ignoreInversenessDifference = !canDropInverse1 && canDropInverse2; |
| 299 } |
| 300 |
273 if (allowSameRRectButDiffStartAndDir) { | 301 if (allowSameRRectButDiffStartAndDir) { |
274 REPORTER_ASSERT(r, rrectA == rrectB); | 302 REPORTER_ASSERT(r, rrectA == rrectB); |
275 REPORTER_ASSERT(r, paths_fill_same(pathA, pathB)); | 303 REPORTER_ASSERT(r, paths_fill_same(pathA, pathB)); |
| 304 REPORTER_ASSERT(r, ignoreInversenessDifference || invertedA == invertedB
); |
276 } else { | 305 } else { |
277 REPORTER_ASSERT(r, pathA == pathB); | 306 SkPath pA = pathA; |
278 REPORTER_ASSERT(r, keyA == keyB); | 307 SkPath pB = pathB; |
| 308 if (ignoreInversenessDifference) { |
| 309 pA.setFillType(SkPath::ConvertToNonInverseFillType(pathA.getFillType
())); |
| 310 pB.setFillType(SkPath::ConvertToNonInverseFillType(pathB.getFillType
())); |
| 311 REPORTER_ASSERT(r, keyA != keyB); |
| 312 } else { |
| 313 REPORTER_ASSERT(r, keyA == keyB); |
| 314 } |
| 315 REPORTER_ASSERT(r, pA == pB); |
279 REPORTER_ASSERT(r, aIsRRect == bIsRRect); | 316 REPORTER_ASSERT(r, aIsRRect == bIsRRect); |
280 if (aIsRRect) { | 317 if (aIsRRect) { |
281 REPORTER_ASSERT(r, rrectA == rrectB); | 318 REPORTER_ASSERT(r, rrectA == rrectB); |
282 REPORTER_ASSERT(r, dirA == dirB); | 319 REPORTER_ASSERT(r, dirA == dirB); |
283 REPORTER_ASSERT(r, startA == startB); | 320 REPORTER_ASSERT(r, startA == startB); |
| 321 REPORTER_ASSERT(r, ignoreInversenessDifference || invertedA == inver
tedB); |
284 } | 322 } |
285 } | 323 } |
286 REPORTER_ASSERT(r, a.isEmpty() == b.isEmpty()); | 324 REPORTER_ASSERT(r, a.isEmpty() == b.isEmpty()); |
287 REPORTER_ASSERT(r, a.knownToBeClosed() == b.knownToBeClosed()); | 325 REPORTER_ASSERT(r, a.knownToBeClosed() == b.knownToBeClosed()); |
288 REPORTER_ASSERT(r, a.bounds() == b.bounds()); | 326 REPORTER_ASSERT(r, a.bounds() == b.bounds()); |
289 REPORTER_ASSERT(r, a.segmentMask() == b.segmentMask()); | 327 REPORTER_ASSERT(r, a.segmentMask() == b.segmentMask()); |
290 } | 328 } |
291 | 329 |
292 void TestCase::compare(skiatest::Reporter* r, const TestCase& that, | 330 void TestCase::compare(skiatest::Reporter* r, const TestCase& that, |
293 ComparisonExpecation expectation) const { | 331 ComparisonExpecation expectation) const { |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 TestCase strokeAndFillCase1(geo, strokeAndFill, reporter, kS1); | 489 TestCase strokeAndFillCase1(geo, strokeAndFill, reporter, kS1); |
452 TestCase strokeAndFillCase2(geo, strokeAndFill, reporter, kS2); | 490 TestCase strokeAndFillCase2(geo, strokeAndFill, reporter, kS2); |
453 SkPaint strokeAndFillDash = strokeDash; | 491 SkPaint strokeAndFillDash = strokeDash; |
454 strokeAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style); | 492 strokeAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style); |
455 // Dash is ignored for stroke and fill | 493 // Dash is ignored for stroke and fill |
456 TestCase strokeAndFillDashCase1(geo, strokeAndFillDash, reporter, kS1); | 494 TestCase strokeAndFillDashCase1(geo, strokeAndFillDash, reporter, kS1); |
457 TestCase strokeAndFillDashCase2(geo, strokeAndFillDash, reporter, kS2); | 495 TestCase strokeAndFillDashCase2(geo, strokeAndFillDash, reporter, kS2); |
458 // Scale affects the stroke. Though, this can wind up creating a rect when t
he input is a rect. | 496 // Scale affects the stroke. Though, this can wind up creating a rect when t
he input is a rect. |
459 // In that case we wind up with a pure geometry key and the geometries are t
he same. | 497 // In that case we wind up with a pure geometry key and the geometries are t
he same. |
460 SkRRect rrect; | 498 SkRRect rrect; |
461 if (strokeAndFillCase1.appliedFullStyleShape().asRRect(&rrect, nullptr, null
ptr)) { | 499 if (strokeAndFillCase1.appliedFullStyleShape().asRRect(&rrect, nullptr, null
ptr, nullptr)) { |
462 // We currently only expect to get here in the rect->rect case. | 500 // We currently only expect to get here in the rect->rect case. |
463 REPORTER_ASSERT(reporter, rrect.isRect()); | 501 REPORTER_ASSERT(reporter, rrect.isRect()); |
464 REPORTER_ASSERT(reporter, | 502 REPORTER_ASSERT(reporter, |
465 strokeAndFillCase1.baseShape().asRRect(&rrect, nullptr,
nullptr) && | 503 strokeAndFillCase1.baseShape().asRRect(&rrect, nullptr,
nullptr, nullptr) && |
466 rrect.isRect()); | 504 rrect.isRect()); |
467 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, | 505 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, |
468 TestCase::kAllSame_ComparisonExpecation); | 506 TestCase::kAllSame_ComparisonExpecation); |
469 } else { | 507 } else { |
470 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, | 508 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, |
471 TestCase::kSameUpToStroke_ComparisonExpecatio
n); | 509 TestCase::kSameUpToStroke_ComparisonExpecatio
n); |
472 strokeAndFillDashCase1.compare(reporter, strokeAndFillDashCase2, | 510 strokeAndFillDashCase1.compare(reporter, strokeAndFillDashCase2, |
473 TestCase::kSameUpToStroke_ComparisonExpec
ation); | 511 TestCase::kSameUpToStroke_ComparisonExpec
ation); |
474 } | 512 } |
475 strokeAndFillDashCase1.compare(reporter, strokeAndFillCase1, | 513 strokeAndFillDashCase1.compare(reporter, strokeAndFillCase1, |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 TestCase::kSameUpToStroke_ComparisonExpecation); | 718 TestCase::kSameUpToStroke_ComparisonExpecation); |
681 | 719 |
682 TestCase rrectFillCase(RRectPathEffect::RRect(), fill, reporter); | 720 TestCase rrectFillCase(RRectPathEffect::RRect(), fill, reporter); |
683 SkPaint stroke = peStroke; | 721 SkPaint stroke = peStroke; |
684 stroke.setPathEffect(nullptr); | 722 stroke.setPathEffect(nullptr); |
685 TestCase rrectStrokeCase(RRectPathEffect::RRect(), stroke, reporter); | 723 TestCase rrectStrokeCase(RRectPathEffect::RRect(), stroke, reporter); |
686 | 724 |
687 SkRRect rrect; | 725 SkRRect rrect; |
688 // Applying the path effect should make a SkRRect shape. There is no further
stroking in the | 726 // Applying the path effect should make a SkRRect shape. There is no further
stroking in the |
689 // geoPECase, so the full style should be the same as just the PE. | 727 // geoPECase, so the full style should be the same as just the PE. |
690 REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectShape().asRRect(&rrect,
nullptr, nullptr)); | 728 REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectShape().asRRect(&rrect,
nullptr, nullptr, |
| 729 nullptr
)); |
691 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); | 730 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); |
692 REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectKey() == rrectFillCase.
baseKey()); | 731 REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectKey() == rrectFillCase.
baseKey()); |
693 | 732 |
694 REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleShape().asRRect(&rrect,
nullptr, nullptr)); | 733 REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleShape().asRRect(&rrect,
nullptr, nullptr, |
| 734 nullptr)
); |
695 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); | 735 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); |
696 REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleKey() == rrectFillCase.b
aseKey()); | 736 REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleKey() == rrectFillCase.b
aseKey()); |
697 | 737 |
698 // In the PE+stroke case applying the full style should be the same as just
stroking the rrect. | 738 // In the PE+stroke case applying the full style should be the same as just
stroking the rrect. |
699 REPORTER_ASSERT(reporter, | 739 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectShape().asRRect(&
rrect, nullptr, |
700 geoPEStrokeCase.appliedPathEffectShape().asRRect(&rrect, nul
lptr, nullptr)); | 740 n
ullptr, nullptr)); |
701 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); | 741 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); |
702 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectKey() == rrectFil
lCase.baseKey()); | 742 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectKey() == rrectFil
lCase.baseKey()); |
703 | 743 |
704 REPORTER_ASSERT(reporter, | 744 REPORTER_ASSERT(reporter, !geoPEStrokeCase.appliedFullStyleShape().asRRect(&
rrect, nullptr, |
705 !geoPEStrokeCase.appliedFullStyleShape().asRRect(&rrect, nul
lptr, nullptr)); | 745 n
ullptr, nullptr)); |
706 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleKey() == | 746 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleKey() == |
707 rrectStrokeCase.appliedFullStyleKey()); | 747 rrectStrokeCase.appliedFullStyleKey()); |
708 } | 748 } |
709 | 749 |
710 template <typename GEO> | 750 template <typename GEO> |
711 void test_unknown_path_effect(skiatest::Reporter* reporter, const GEO& geo) { | 751 void test_unknown_path_effect(skiatest::Reporter* reporter, const GEO& geo) { |
712 /** | 752 /** |
713 * This path effect just adds two lineTos to the input path. | 753 * This path effect just adds two lineTos to the input path. |
714 */ | 754 */ |
715 class AddLineTosPathEffect : SkPathEffect { | 755 class AddLineTosPathEffect : SkPathEffect { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 * This path effect just changes the stroke rec to hairline. | 794 * This path effect just changes the stroke rec to hairline. |
755 */ | 795 */ |
756 class MakeHairlinePathEffect : SkPathEffect { | 796 class MakeHairlinePathEffect : SkPathEffect { |
757 public: | 797 public: |
758 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* strokeRec, | 798 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* strokeRec, |
759 const SkRect* cullR) const override { | 799 const SkRect* cullR) const override { |
760 *dst = src; | 800 *dst = src; |
761 strokeRec->setHairlineStyle(); | 801 strokeRec->setHairlineStyle(); |
762 return true; | 802 return true; |
763 } | 803 } |
764 void computeFastBounds(SkRect* dst, const SkRect& src) const override {
*dst = src; } | 804 void computeFastBounds(SkRect* dst, const SkRect& src) const override {
*dst = src; } |
765 static sk_sp<SkPathEffect> Make() { | 805 static sk_sp<SkPathEffect> Make() { |
766 return sk_sp<SkPathEffect>(new MakeHairlinePathEffect); | 806 return sk_sp<SkPathEffect>(new MakeHairlinePathEffect); |
767 } | 807 } |
768 Factory getFactory() const override { return nullptr; } | 808 Factory getFactory() const override { return nullptr; } |
769 void toString(SkString*) const override {} | 809 void toString(SkString*) const override {} |
770 private: | 810 private: |
771 MakeHairlinePathEffect() {} | 811 MakeHairlinePathEffect() {} |
772 }; | 812 }; |
773 | 813 |
774 SkPaint fill; | 814 SkPaint fill; |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 dashAndStrokeEmptyRRectCase.compare(reporter, fillEmptyCase, | 1021 dashAndStrokeEmptyRRectCase.compare(reporter, fillEmptyCase, |
982 TestCase::kAllSame_ComparisonExpecation)
; | 1022 TestCase::kAllSame_ComparisonExpecation)
; |
983 | 1023 |
984 // Same for a rect. | 1024 // Same for a rect. |
985 SkRect emptyRect = SkRect::MakeEmpty(); | 1025 SkRect emptyRect = SkRect::MakeEmpty(); |
986 TestCase dashAndStrokeEmptyRectCase(emptyRect, dashAndStroke, reporter); | 1026 TestCase dashAndStrokeEmptyRectCase(emptyRect, dashAndStroke, reporter); |
987 dashAndStrokeEmptyRectCase.compare(reporter, fillEmptyCase, | 1027 dashAndStrokeEmptyRectCase.compare(reporter, fillEmptyCase, |
988 TestCase::kAllSame_ComparisonExpecation); | 1028 TestCase::kAllSame_ComparisonExpecation); |
989 } | 1029 } |
990 | 1030 |
| 1031 // rect and oval types have rrect start indices that collapse to the same point.
Here we select the |
| 1032 // canonical point in these cases. |
| 1033 unsigned canonicalize_rrect_start(int s, const SkRRect& rrect) { |
| 1034 switch (rrect.getType()) { |
| 1035 case SkRRect::kRect_Type: |
| 1036 return (s + 1) & 0b110; |
| 1037 case SkRRect::kOval_Type: |
| 1038 return s & 0b110; |
| 1039 default: |
| 1040 return s; |
| 1041 } |
| 1042 } |
| 1043 |
| 1044 void test_rrect(skiatest::Reporter* r, const SkRRect& rrect) { |
| 1045 enum { |
| 1046 kFill, |
| 1047 kStroke, |
| 1048 kHairline, |
| 1049 kStrokeAndFill |
| 1050 }; |
| 1051 |
| 1052 // SkStrokeRec has no default cons., so init with kFill before calling the s
etters below. |
| 1053 SkStrokeRec strokeRecs[4] { SkStrokeRec::kFill_InitStyle, SkStrokeRec::kFill
_InitStyle, |
| 1054 SkStrokeRec::kFill_InitStyle, SkStrokeRec::kFill
_InitStyle}; |
| 1055 strokeRecs[kFill].setFillStyle(); |
| 1056 strokeRecs[kStroke].setStrokeStyle(2.f); |
| 1057 strokeRecs[kHairline].setHairlineStyle(); |
| 1058 strokeRecs[kStrokeAndFill].setStrokeStyle(3.f, true); |
| 1059 sk_sp<SkPathEffect> dashEffect = make_dash(); |
| 1060 |
| 1061 GrShape shapes[2 /* inverted */] |
| 1062 [2 /* direction */] |
| 1063 [8 /* start index */] |
| 1064 [SK_ARRAY_COUNT(strokeRecs)] |
| 1065 [2 /* dash */]; |
| 1066 for (int inverted = 0; inverted < 2; ++inverted) { |
| 1067 for (int ccw = 0; ccw < 2; ++ccw) { |
| 1068 for (unsigned s = 0; s < 8; ++s) { |
| 1069 for (size_t style = 0; style < SK_ARRAY_COUNT(strokeRecs); ++sty
le) { |
| 1070 for (int dash = 0; dash < 2; ++dash) { |
| 1071 SkPath::Direction dir = ccw ? SkPath::kCCW_Direction |
| 1072 : SkPath::kCW_Direction; |
| 1073 SkPathEffect* pe = dash ? dashEffect.get() : nullptr; |
| 1074 shapes[inverted][ccw][s][style][dash] = |
| 1075 GrShape(rrect, dir, s, SkToBool(inverted), |
| 1076 GrStyle(strokeRecs[style], pe)); |
| 1077 } |
| 1078 } |
| 1079 } |
| 1080 } |
| 1081 } |
| 1082 |
| 1083 const GrShape& exampleFillCase = shapes[0][0][0][kFill][0]; |
| 1084 Key exampleFillCaseKey; |
| 1085 make_key(&exampleFillCaseKey, exampleFillCase); |
| 1086 |
| 1087 const GrShape& exampleStrokeAndFillCase = shapes[0][0][0][kStrokeAndFill][0]
; |
| 1088 Key exampleStrokeAndFillCaseKey; |
| 1089 make_key(&exampleStrokeAndFillCaseKey, exampleStrokeAndFillCase); |
| 1090 |
| 1091 const GrShape& exampleInvFillCase = shapes[1][0][0][kFill][0]; |
| 1092 Key exampleInvFillCaseKey; |
| 1093 make_key(&exampleInvFillCaseKey, exampleInvFillCase); |
| 1094 |
| 1095 const GrShape& exampleInvStrokeAndFillCase = shapes[1][0][0][kStrokeAndFill]
[0]; |
| 1096 Key exampleInvStrokeAndFillCaseKey; |
| 1097 make_key(&exampleInvStrokeAndFillCaseKey, exampleInvStrokeAndFillCase); |
| 1098 |
| 1099 const GrShape& exampleStrokeCase = shapes[0][0][0][kStroke][0]; |
| 1100 Key exampleStrokeCaseKey; |
| 1101 make_key(&exampleStrokeCaseKey, exampleStrokeCase); |
| 1102 |
| 1103 const GrShape& exampleHairlineCase = shapes[0][0][0][kHairline][0]; |
| 1104 Key exampleHairlineCaseKey; |
| 1105 make_key(&exampleHairlineCaseKey, exampleHairlineCase); |
| 1106 |
| 1107 // These are dummy initializations to suppress warnings. |
| 1108 SkRRect rr = SkRRect::MakeEmpty(); |
| 1109 SkPath::Direction dir = SkPath::kCW_Direction; |
| 1110 unsigned start = ~0U; |
| 1111 bool inv = true; |
| 1112 |
| 1113 REPORTER_ASSERT(r, exampleFillCase.asRRect(&rr, &dir, &start, &inv)); |
| 1114 REPORTER_ASSERT(r, rr == rrect); |
| 1115 REPORTER_ASSERT(r, SkPath::kCW_Direction == dir); |
| 1116 REPORTER_ASSERT(r, 0 == start); |
| 1117 REPORTER_ASSERT(r, !inv); |
| 1118 |
| 1119 REPORTER_ASSERT(r, exampleInvFillCase.asRRect(&rr, &dir, &start, &inv)); |
| 1120 REPORTER_ASSERT(r, rr == rrect); |
| 1121 REPORTER_ASSERT(r, SkPath::kCW_Direction == dir); |
| 1122 REPORTER_ASSERT(r, 0 == start); |
| 1123 REPORTER_ASSERT(r, inv); |
| 1124 |
| 1125 REPORTER_ASSERT(r, exampleStrokeAndFillCase.asRRect(&rr, &dir, &start, &inv)
); |
| 1126 REPORTER_ASSERT(r, rr == rrect); |
| 1127 REPORTER_ASSERT(r, SkPath::kCW_Direction == dir); |
| 1128 REPORTER_ASSERT(r, 0 == start); |
| 1129 REPORTER_ASSERT(r, !inv); |
| 1130 |
| 1131 REPORTER_ASSERT(r, exampleInvStrokeAndFillCase.asRRect(&rr, &dir, &start, &i
nv)); |
| 1132 REPORTER_ASSERT(r, rr == rrect); |
| 1133 REPORTER_ASSERT(r, SkPath::kCW_Direction == dir); |
| 1134 REPORTER_ASSERT(r, 0 == start); |
| 1135 REPORTER_ASSERT(r, inv); |
| 1136 |
| 1137 REPORTER_ASSERT(r, exampleHairlineCase.asRRect(&rr, &dir, &start, &inv)); |
| 1138 REPORTER_ASSERT(r, rr == rrect); |
| 1139 REPORTER_ASSERT(r, SkPath::kCW_Direction == dir); |
| 1140 REPORTER_ASSERT(r, 0 == start); |
| 1141 REPORTER_ASSERT(r, !inv); |
| 1142 |
| 1143 REPORTER_ASSERT(r, exampleStrokeCase.asRRect(&rr, &dir, &start, &inv)); |
| 1144 REPORTER_ASSERT(r, rr == rrect); |
| 1145 REPORTER_ASSERT(r, SkPath::kCW_Direction == dir); |
| 1146 REPORTER_ASSERT(r, 0 == start); |
| 1147 REPORTER_ASSERT(r, !inv); |
| 1148 |
| 1149 // Remember that the key reflects the geometry before styling is applied. |
| 1150 REPORTER_ASSERT(r, exampleFillCaseKey != exampleInvFillCaseKey); |
| 1151 REPORTER_ASSERT(r, exampleFillCaseKey == exampleStrokeAndFillCaseKey); |
| 1152 REPORTER_ASSERT(r, exampleFillCaseKey != exampleInvStrokeAndFillCaseKey); |
| 1153 REPORTER_ASSERT(r, exampleFillCaseKey == exampleStrokeCaseKey); |
| 1154 REPORTER_ASSERT(r, exampleFillCaseKey == exampleHairlineCaseKey); |
| 1155 REPORTER_ASSERT(r, exampleInvStrokeAndFillCaseKey == exampleInvFillCaseKey); |
| 1156 |
| 1157 for (int inverted = 0; inverted < 2; ++inverted) { |
| 1158 for (int ccw = 0; ccw < 2; ++ccw) { |
| 1159 for (unsigned s = 0; s < 8; ++s) { |
| 1160 for (int dash = 0; dash < 2; ++dash) { |
| 1161 const GrShape& fillCase = shapes[inverted][ccw][s][kFill][da
sh]; |
| 1162 Key fillCaseKey; |
| 1163 make_key(&fillCaseKey, fillCase); |
| 1164 |
| 1165 const GrShape& strokeAndFillCase = |
| 1166 shapes[inverted][ccw][s][kStrokeAndFill][dash]; |
| 1167 Key strokeAndFillCaseKey; |
| 1168 make_key(&strokeAndFillCaseKey, strokeAndFillCase); |
| 1169 |
| 1170 // Both fill and stroke-and-fill shapes must respect the inv
erseness and both |
| 1171 // ignore dashing. |
| 1172 REPORTER_ASSERT(r, !fillCase.style().pathEffect()); |
| 1173 REPORTER_ASSERT(r, !strokeAndFillCase.style().pathEffect()); |
| 1174 TestCase a(fillCase, r); |
| 1175 TestCase b(inverted ? exampleInvFillCase : exampleFillCase,
r); |
| 1176 TestCase c(strokeAndFillCase, r); |
| 1177 TestCase d(inverted ? exampleInvStrokeAndFillCase |
| 1178 : exampleStrokeAndFillCase, r); |
| 1179 a.compare(r, b, TestCase::kAllSame_ComparisonExpecation); |
| 1180 c.compare(r, d, TestCase::kAllSame_ComparisonExpecation); |
| 1181 |
| 1182 const GrShape& strokeCase = shapes[inverted][ccw][s][kStroke
][dash]; |
| 1183 const GrShape& hairlineCase = shapes[inverted][ccw][s][kHair
line][dash]; |
| 1184 |
| 1185 TestCase e(strokeCase, r); |
| 1186 TestCase f(exampleStrokeCase, r); |
| 1187 TestCase g(hairlineCase, r); |
| 1188 TestCase h(exampleHairlineCase, r); |
| 1189 |
| 1190 // Both hairline and stroke shapes must respect the dashing
and both |
| 1191 // ignore inverseness. |
| 1192 if (dash) { |
| 1193 unsigned expectedStart = canonicalize_rrect_start(s, rre
ct); |
| 1194 REPORTER_ASSERT(r, strokeCase.style().pathEffect()); |
| 1195 REPORTER_ASSERT(r, hairlineCase.style().pathEffect()); |
| 1196 |
| 1197 REPORTER_ASSERT(r, strokeCase.asRRect(&rr, &dir, &start,
&inv)); |
| 1198 REPORTER_ASSERT(r, rr == rrect); |
| 1199 REPORTER_ASSERT(r, (SkPath::kCCW_Direction == dir) == cc
w); |
| 1200 REPORTER_ASSERT(r, start == expectedStart); |
| 1201 REPORTER_ASSERT(r, !inv); |
| 1202 REPORTER_ASSERT(r, hairlineCase.asRRect(&rr, &dir, &star
t, &inv)); |
| 1203 REPORTER_ASSERT(r, rr == rrect); |
| 1204 REPORTER_ASSERT(r, (SkPath::kCCW_Direction == dir) == cc
w); |
| 1205 REPORTER_ASSERT(r, start == expectedStart); |
| 1206 REPORTER_ASSERT(r, !inv); |
| 1207 |
| 1208 // The pre-style case for the dash will match the non-da
sh example iff the |
| 1209 // dir and start match (dir=cw, start=0). |
| 1210 if (0 == expectedStart && 0 == ccw) { |
| 1211 e.compare(r, f, TestCase::kSameUpToPE_ComparisonExpe
cation); |
| 1212 g.compare(r, h, TestCase::kSameUpToPE_ComparisonExpe
cation); |
| 1213 } else { |
| 1214 e.compare(r, f, TestCase::kAllDifferent_ComparisonEx
pecation); |
| 1215 g.compare(r, h, TestCase::kAllDifferent_ComparisonEx
pecation); |
| 1216 } |
| 1217 } else { |
| 1218 REPORTER_ASSERT(r, !strokeCase.style().pathEffect()); |
| 1219 REPORTER_ASSERT(r, !hairlineCase.style().pathEffect()); |
| 1220 e.compare(r, f, TestCase::kAllSame_ComparisonExpecation)
; |
| 1221 g.compare(r, h, TestCase::kAllSame_ComparisonExpecation)
; |
| 1222 } |
| 1223 } |
| 1224 } |
| 1225 } |
| 1226 } |
| 1227 } |
| 1228 |
991 DEF_TEST(GrShape, reporter) { | 1229 DEF_TEST(GrShape, reporter) { |
992 for (auto r : { SkRect::MakeWH(10, 20), | 1230 for (auto r : { SkRect::MakeWH(10, 20), |
993 SkRect::MakeWH(-10, -20), | 1231 SkRect::MakeWH(-10, -20), |
994 SkRect::MakeWH(-10, 20), | 1232 SkRect::MakeWH(-10, 20), |
995 SkRect::MakeWH(10, -20)}) { | 1233 SkRect::MakeWH(10, -20)}) { |
996 test_basic(reporter, r); | 1234 test_basic(reporter, r); |
997 test_scale(reporter, r); | 1235 test_scale(reporter, r); |
998 test_dash_fill(reporter, r); | 1236 test_dash_fill(reporter, r); |
999 test_null_dash(reporter, r); | 1237 test_null_dash(reporter, r); |
1000 // Test modifying various stroke params. | 1238 // Test modifying various stroke params. |
(...skipping 11 matching lines...) Expand all Loading... |
1012 test_unknown_path_effect(reporter, r); | 1250 test_unknown_path_effect(reporter, r); |
1013 test_path_effect_makes_empty_shape(reporter, r); | 1251 test_path_effect_makes_empty_shape(reporter, r); |
1014 test_path_effect_fails(reporter, r); | 1252 test_path_effect_fails(reporter, r); |
1015 test_make_hairline_path_effect(reporter, r, true); | 1253 test_make_hairline_path_effect(reporter, r, true); |
1016 } | 1254 } |
1017 | 1255 |
1018 for (auto rr : { SkRRect::MakeRect(SkRect::MakeWH(10, 10)), | 1256 for (auto rr : { SkRRect::MakeRect(SkRect::MakeWH(10, 10)), |
1019 SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4), | 1257 SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4), |
1020 SkRRect::MakeOval(SkRect::MakeWH(20, 20))}) { | 1258 SkRRect::MakeOval(SkRect::MakeWH(20, 20))}) { |
1021 test_basic(reporter, rr); | 1259 test_basic(reporter, rr); |
| 1260 test_rrect(reporter, rr); |
1022 test_scale(reporter, rr); | 1261 test_scale(reporter, rr); |
1023 test_dash_fill(reporter, rr); | 1262 test_dash_fill(reporter, rr); |
1024 test_null_dash(reporter, rr); | 1263 test_null_dash(reporter, rr); |
1025 // Test modifying various stroke params. | 1264 // Test modifying various stroke params. |
1026 test_stroke_param<SkRRect, SkScalar>( | 1265 test_stroke_param<SkRRect, SkScalar>( |
1027 reporter, rr, | 1266 reporter, rr, |
1028 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, | 1267 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, |
1029 SkIntToScalar(2), SkIntToScalar(4)); | 1268 SkIntToScalar(2), SkIntToScalar(4)); |
1030 test_stroke_param<SkRRect, SkPaint::Join>( | 1269 test_stroke_param<SkRRect, SkPaint::Join>( |
1031 reporter, rr, | 1270 reporter, rr, |
1032 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);
}, | 1271 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);
}, |
1033 SkPaint::kMiter_Join, SkPaint::kRound_Join); | 1272 SkPaint::kMiter_Join, SkPaint::kRound_Join); |
1034 test_stroke_cap(reporter, rr); | 1273 test_stroke_cap(reporter, rr); |
1035 test_miter_limit(reporter, rr); | 1274 test_miter_limit(reporter, rr); |
1036 test_path_effect_makes_rrect(reporter, rr); | 1275 test_path_effect_makes_rrect(reporter, rr); |
1037 test_unknown_path_effect(reporter, rr); | 1276 test_unknown_path_effect(reporter, rr); |
1038 test_path_effect_makes_empty_shape(reporter, rr); | 1277 test_path_effect_makes_empty_shape(reporter, rr); |
1039 test_path_effect_fails(reporter, rr); | 1278 test_path_effect_fails(reporter, rr); |
1040 test_make_hairline_path_effect(reporter, rr, true); | 1279 test_make_hairline_path_effect(reporter, rr, true); |
1041 } | 1280 } |
1042 | 1281 |
1043 struct TestPath { | 1282 struct TestPath { |
1044 TestPath(const SkPath& path, bool isRRectFill, bool isRRectStroke ,const
SkRRect& rrect) | 1283 TestPath(const SkPath& path, bool isRRectFill, bool isRRectStroke, const
SkRRect& rrect) |
1045 : fPath(path) | 1284 : fPath(path) |
1046 , fIsRRectForFill(isRRectFill) | 1285 , fIsRRectForFill(isRRectFill) |
1047 , fIsRRectForStroke(isRRectStroke) | 1286 , fIsRRectForStroke(isRRectStroke) |
1048 , fRRect(rrect) {} | 1287 , fRRect(rrect) {} |
1049 SkPath fPath; | 1288 SkPath fPath; |
1050 bool fIsRRectForFill; | 1289 bool fIsRRectForFill; |
1051 bool fIsRRectForStroke; | 1290 bool fIsRRectForStroke; |
1052 SkRRect fRRect; | 1291 SkRRect fRRect; |
1053 }; | 1292 }; |
1054 SkTArray<TestPath> paths; | 1293 SkTArray<TestPath> paths; |
(...skipping 11 matching lines...) Expand all Loading... |
1066 openRectPath.lineTo(10, 0); | 1305 openRectPath.lineTo(10, 0); |
1067 openRectPath.lineTo(10, 10); | 1306 openRectPath.lineTo(10, 10); |
1068 openRectPath.lineTo(0, 10); | 1307 openRectPath.lineTo(0, 10); |
1069 paths.emplace_back(openRectPath, true, false, SkRRect::MakeRect(SkRect::Make
WH(10, 10))); | 1308 paths.emplace_back(openRectPath, true, false, SkRRect::MakeRect(SkRect::Make
WH(10, 10))); |
1070 | 1309 |
1071 SkPath quadPath; | 1310 SkPath quadPath; |
1072 quadPath.quadTo(10, 10, 5, 8); | 1311 quadPath.quadTo(10, 10, 5, 8); |
1073 paths.emplace_back(quadPath, false, false, SkRRect()); | 1312 paths.emplace_back(quadPath, false, false, SkRRect()); |
1074 | 1313 |
1075 for (auto testPath : paths) { | 1314 for (auto testPath : paths) { |
| 1315 for (bool inverseFill : {false, true}) { |
| 1316 if (inverseFill) { |
| 1317 if (testPath.fPath.getFillType() == SkPath::kEvenOdd_FillType) { |
| 1318 testPath.fPath.setFillType(SkPath::kInverseEvenOdd_FillType)
; |
| 1319 } else { |
| 1320 SkASSERT(testPath.fPath.getFillType() == SkPath::kWinding_Fi
llType); |
| 1321 testPath.fPath.setFillType(SkPath::kInverseWinding_FillType)
; |
| 1322 } |
| 1323 } |
| 1324 const SkPath& path = testPath.fPath; |
| 1325 // These tests all assume that the original GrShape for fill and str
oke will be the |
| 1326 // same. |
| 1327 // However, that is not the case in special cases (e.g. an unclosed
rect becomes a RRect |
| 1328 // GrShape with a fill style but becomes a Path GrShape when stroked
). |
| 1329 if (testPath.fIsRRectForFill == testPath.fIsRRectForStroke) { |
| 1330 test_basic(reporter, path); |
| 1331 test_null_dash(reporter, path); |
| 1332 test_path_effect_makes_rrect(reporter, path); |
| 1333 } |
| 1334 test_scale(reporter, path); |
| 1335 // This test uses a stroking paint, hence use of fIsRRectForStroke |
| 1336 test_volatile_path(reporter, path, testPath.fIsRRectForStroke); |
| 1337 test_dash_fill(reporter, path); |
| 1338 // Test modifying various stroke params. |
| 1339 test_stroke_param<SkPath, SkScalar>( |
| 1340 reporter, path, |
| 1341 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, |
| 1342 SkIntToScalar(2), SkIntToScalar(4)); |
| 1343 test_stroke_param<SkPath, SkPaint::Join>( |
| 1344 reporter, path, |
| 1345 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);}, |
| 1346 SkPaint::kMiter_Join, SkPaint::kRound_Join); |
| 1347 test_stroke_cap(reporter, path); |
| 1348 test_miter_limit(reporter, path); |
| 1349 test_unknown_path_effect(reporter, path); |
| 1350 test_path_effect_makes_empty_shape(reporter, path); |
| 1351 test_path_effect_fails(reporter, path); |
| 1352 test_make_hairline_path_effect(reporter, path, testPath.fIsRRectForS
troke); |
| 1353 } |
| 1354 } |
| 1355 for (auto testPath : paths) { |
1076 const SkPath& path = testPath.fPath; | 1356 const SkPath& path = testPath.fPath; |
1077 // These tests all assume that the original GrShape for fill and stroke
will be the same. | |
1078 // However, that is not the case in special cases (e.g. a unclosed rect
becomes a RRect | |
1079 // GrShape with a fill style but becomes a Path GrShape when stroked). | |
1080 if (testPath.fIsRRectForFill == testPath.fIsRRectForStroke) { | |
1081 test_basic(reporter, path); | |
1082 test_null_dash(reporter, path); | |
1083 test_path_effect_makes_rrect(reporter, path); | |
1084 } | |
1085 test_scale(reporter, path); | |
1086 // This test uses a stroking paint, hence use of fIsRRectForStroke | |
1087 test_volatile_path(reporter, path, testPath.fIsRRectForStroke); | |
1088 test_dash_fill(reporter, path); | |
1089 // Test modifying various stroke params. | |
1090 test_stroke_param<SkPath, SkScalar>( | |
1091 reporter, path, | |
1092 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, | |
1093 SkIntToScalar(2), SkIntToScalar(4)); | |
1094 test_stroke_param<SkPath, SkPaint::Join>( | |
1095 reporter, path, | |
1096 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);}, | |
1097 SkPaint::kMiter_Join, SkPaint::kRound_Join); | |
1098 test_stroke_cap(reporter, path); | |
1099 test_miter_limit(reporter, path); | |
1100 test_unknown_path_effect(reporter, path); | |
1101 test_path_effect_makes_empty_shape(reporter, path); | |
1102 test_path_effect_fails(reporter, path); | |
1103 test_make_hairline_path_effect(reporter, path, testPath.fIsRRectForStrok
e); | |
1104 | 1357 |
1105 SkPaint fillPaint; | 1358 SkPaint fillPaint; |
1106 TestCase fillPathCase(path, fillPaint, reporter); | 1359 TestCase fillPathCase(path, fillPaint, reporter); |
1107 SkRRect rrect; | 1360 SkRRect rrect; |
1108 REPORTER_ASSERT(reporter, testPath.fIsRRectForFill == | 1361 REPORTER_ASSERT(reporter, testPath.fIsRRectForFill == |
1109 fillPathCase.baseShape().asRRect(&rrect, nullp
tr, nullptr)); | 1362 fillPathCase.baseShape().asRRect(&rrect, nullp
tr, nullptr, |
| 1363 nullptr)); |
1110 if (testPath.fIsRRectForFill) { | 1364 if (testPath.fIsRRectForFill) { |
1111 TestCase fillPathCase2(path, fillPaint, reporter); | 1365 TestCase fillPathCase2(testPath.fPath, fillPaint, reporter); |
1112 REPORTER_ASSERT(reporter, rrect == testPath.fRRect); | 1366 REPORTER_ASSERT(reporter, rrect == testPath.fRRect); |
1113 TestCase fillRRectCase(rrect, fillPaint, reporter); | 1367 TestCase fillRRectCase(rrect, fillPaint, reporter); |
1114 fillPathCase2.compare(reporter, fillRRectCase, TestCase::kAllSame_Co
mparisonExpecation); | 1368 fillPathCase2.compare(reporter, fillRRectCase, |
| 1369 TestCase::kAllSame_ComparisonExpecation); |
1115 } | 1370 } |
1116 | |
1117 SkPaint strokePaint; | 1371 SkPaint strokePaint; |
1118 strokePaint.setStrokeWidth(3.f); | 1372 strokePaint.setStrokeWidth(3.f); |
1119 strokePaint.setStyle(SkPaint::kStroke_Style); | 1373 strokePaint.setStyle(SkPaint::kStroke_Style); |
1120 TestCase strokePathCase(path, strokePaint, reporter); | 1374 TestCase strokePathCase(path, strokePaint, reporter); |
1121 REPORTER_ASSERT(reporter, testPath.fIsRRectForStroke == | 1375 REPORTER_ASSERT(reporter, testPath.fIsRRectForStroke == |
1122 strokePathCase.baseShape().asRRect(&rrect, nul
lptr, nullptr)); | 1376 strokePathCase.baseShape().asRRect(&rrect, nul
lptr, nullptr, |
| 1377 nullptr)); |
1123 if (testPath.fIsRRectForStroke) { | 1378 if (testPath.fIsRRectForStroke) { |
1124 REPORTER_ASSERT(reporter, rrect == testPath.fRRect); | 1379 REPORTER_ASSERT(reporter, rrect == testPath.fRRect); |
1125 TestCase strokeRRectCase(rrect, strokePaint, reporter); | 1380 TestCase strokeRRectCase(rrect, strokePaint, reporter); |
1126 strokePathCase.compare(reporter, strokeRRectCase, | 1381 strokePathCase.compare(reporter, strokeRRectCase, |
1127 TestCase::kAllSame_ComparisonExpecation); | 1382 TestCase::kAllSame_ComparisonExpecation); |
1128 } | 1383 } |
1129 } | 1384 } |
1130 | 1385 |
1131 // Test a volatile empty path. | 1386 // Test a volatile empty path. |
1132 test_volatile_path(reporter, SkPath(), true); | 1387 test_volatile_path(reporter, SkPath(), true); |
1133 | 1388 |
1134 test_empty_shape(reporter); | 1389 test_empty_shape(reporter); |
1135 } | 1390 } |
1136 | 1391 |
1137 #endif | 1392 #endif |
OLD | NEW |