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 14 matching lines...) Expand all Loading... |
25 key->reset(size); | 25 key->reset(size); |
26 shape.writeUnstyledKey(key->begin()); | 26 shape.writeUnstyledKey(key->begin()); |
27 return true; | 27 return true; |
28 } | 28 } |
29 | 29 |
30 namespace { | 30 namespace { |
31 | 31 |
32 class TestCase { | 32 class TestCase { |
33 public: | 33 public: |
34 template <typename GEO> | 34 template <typename GEO> |
35 TestCase(const GEO& geo, const SkPaint& paint, skiatest::Reporter* r) : fBas
e(geo, paint) { | 35 TestCase(const GEO& geo, const SkPaint& paint, skiatest::Reporter* r, |
36 this->init(r); | 36 SkScalar scale = SK_Scalar1) : fBase(geo, paint) { |
| 37 this->init(r, scale); |
37 } | 38 } |
38 | 39 |
39 struct SelfExpectations { | 40 struct SelfExpectations { |
40 bool fPEHasEffect; | 41 bool fPEHasEffect; |
41 bool fPEHasValidKey; | 42 bool fPEHasValidKey; |
42 bool fStrokeApplies; | 43 bool fStrokeApplies; |
43 }; | 44 }; |
44 | 45 |
45 void testExpectations(skiatest::Reporter* reporter, SelfExpectations expecta
tions) const; | 46 void testExpectations(skiatest::Reporter* reporter, SelfExpectations expecta
tions) const; |
46 | 47 |
(...skipping 10 matching lines...) Expand all Loading... |
57 const GrShape& appliedPathEffectShape() const { return fAppliedPE; } | 58 const GrShape& appliedPathEffectShape() const { return fAppliedPE; } |
58 const GrShape& appliedFullStyleShape() const { return fAppliedFull; } | 59 const GrShape& appliedFullStyleShape() const { return fAppliedFull; } |
59 | 60 |
60 // The returned array's count will be 0 if the key shape has no key. | 61 // The returned array's count will be 0 if the key shape has no key. |
61 const Key& baseKey() const { return fBaseKey; } | 62 const Key& baseKey() const { return fBaseKey; } |
62 const Key& appliedPathEffectKey() const { return fAppliedPEKey; } | 63 const Key& appliedPathEffectKey() const { return fAppliedPEKey; } |
63 const Key& appliedFullStyleKey() const { return fAppliedFullKey; } | 64 const Key& appliedFullStyleKey() const { return fAppliedFullKey; } |
64 const Key& appliedPathEffectThenStrokeKey() const { return fAppliedPEThenStr
okeKey; } | 65 const Key& appliedPathEffectThenStrokeKey() const { return fAppliedPEThenStr
okeKey; } |
65 | 66 |
66 private: | 67 private: |
67 void init(skiatest::Reporter* r) { | 68 void init(skiatest::Reporter* r, SkScalar scale) { |
68 fAppliedPE = fBase.applyStyle(GrStyle::Apply::kPathEffectOnly)
; | 69 fAppliedPE = fBase.applyStyle(GrStyle::Apply::kPathEffectOnly,
scale); |
69 fAppliedPEThenStroke = fAppliedPE.applyStyle(GrStyle::Apply::kPathEffect
AndStrokeRec); | 70 fAppliedPEThenStroke = fAppliedPE.applyStyle(GrStyle::Apply::kPathEffect
AndStrokeRec, |
70 fAppliedFull = fBase.applyStyle(GrStyle::Apply::kPathEffectAndSt
rokeRec); | 71 scale); |
| 72 fAppliedFull = fBase.applyStyle(GrStyle::Apply::kPathEffectAndSt
rokeRec, scale); |
71 | 73 |
72 make_key(&fBaseKey, fBase); | 74 make_key(&fBaseKey, fBase); |
73 make_key(&fAppliedPEKey, fAppliedPE); | 75 make_key(&fAppliedPEKey, fAppliedPE); |
74 make_key(&fAppliedPEThenStrokeKey, fAppliedPEThenStroke); | 76 make_key(&fAppliedPEThenStrokeKey, fAppliedPEThenStroke); |
75 make_key(&fAppliedFullKey, fAppliedFull); | 77 make_key(&fAppliedFullKey, fAppliedFull); |
76 | 78 |
77 // Applying the path effect and then the stroke should always be the sam
e as applying | 79 // Applying the path effect and then the stroke should always be the sam
e as applying |
78 // both in one go. | 80 // both in one go. |
79 REPORTER_ASSERT(r, fAppliedPEThenStrokeKey == fAppliedFullKey); | 81 REPORTER_ASSERT(r, fAppliedPEThenStrokeKey == fAppliedFullKey); |
80 SkPath a, b; | 82 SkPath a, b; |
81 fAppliedPEThenStroke.asPath(&a); | 83 fAppliedPEThenStroke.asPath(&a); |
82 fAppliedFull.asPath(&b); | 84 fAppliedFull.asPath(&b); |
83 REPORTER_ASSERT(r, a == b); | 85 REPORTER_ASSERT(r, a == b); |
84 | 86 |
85 // Check that the same path is produced when style is applied by GrShape
and GrStyle. | 87 // Check that the same path is produced when style is applied by GrShape
and GrStyle. |
86 SkPath preStyle; | 88 SkPath preStyle; |
87 SkPath postPathEffect; | 89 SkPath postPathEffect; |
88 SkPath postAllStyle; | 90 SkPath postAllStyle; |
89 | 91 |
90 fBase.asPath(&preStyle); | 92 fBase.asPath(&preStyle); |
91 SkStrokeRec postPEStrokeRec(SkStrokeRec::kFill_InitStyle); | 93 SkStrokeRec postPEStrokeRec(SkStrokeRec::kFill_InitStyle); |
92 if (fBase.style().applyPathEffectToPath(&postPathEffect, &postPEStrokeRe
c, preStyle)) { | 94 if (fBase.style().applyPathEffectToPath(&postPathEffect, &postPEStrokeRe
c, preStyle, |
| 95 scale)) { |
93 // run postPathEffect through GrShape to get any geometry reductions
that would have | 96 // run postPathEffect through GrShape to get any geometry reductions
that would have |
94 // occurred to fAppliedPE. | 97 // occurred to fAppliedPE. |
95 GrShape(postPathEffect, GrStyle(postPEStrokeRec, nullptr)).asPath(&p
ostPathEffect); | 98 GrShape(postPathEffect, GrStyle(postPEStrokeRec, nullptr)).asPath(&p
ostPathEffect); |
96 | 99 |
97 SkPath testPath; | 100 SkPath testPath; |
98 fAppliedPE.asPath(&testPath); | 101 fAppliedPE.asPath(&testPath); |
99 REPORTER_ASSERT(r, testPath == postPathEffect); | 102 REPORTER_ASSERT(r, testPath == postPathEffect); |
100 REPORTER_ASSERT(r, postPEStrokeRec.hasEqualEffect(fAppliedPE.style()
.strokeRec())); | 103 REPORTER_ASSERT(r, postPEStrokeRec.hasEqualEffect(fAppliedPE.style()
.strokeRec())); |
101 } | 104 } |
102 SkStrokeRec::InitStyle fillOrHairline; | 105 SkStrokeRec::InitStyle fillOrHairline; |
103 if (fBase.style().applyToPath(&postAllStyle, &fillOrHairline, preStyle))
{ | 106 if (fBase.style().applyToPath(&postAllStyle, &fillOrHairline, preStyle,
scale)) { |
104 // run postPathEffect through GrShape to get any reductions that wou
ld have occurred | 107 // run postPathEffect through GrShape to get any reductions that wou
ld have occurred |
105 // to fAppliedFull. | 108 // to fAppliedFull. |
106 GrShape(postAllStyle, GrStyle(fillOrHairline)).asPath(&postAllStyle)
; | 109 GrShape(postAllStyle, GrStyle(fillOrHairline)).asPath(&postAllStyle)
; |
107 | 110 |
108 SkPath testPath; | 111 SkPath testPath; |
109 fAppliedFull.asPath(&testPath); | 112 fAppliedFull.asPath(&testPath); |
110 REPORTER_ASSERT(r, testPath == postAllStyle); | 113 REPORTER_ASSERT(r, testPath == postAllStyle); |
111 if (fillOrHairline == SkStrokeRec::kFill_InitStyle) { | 114 if (fillOrHairline == SkStrokeRec::kFill_InitStyle) { |
112 REPORTER_ASSERT(r, fAppliedFull.style().isSimpleFill()); | 115 REPORTER_ASSERT(r, fAppliedFull.style().isSimpleFill()); |
113 } else { | 116 } else { |
114 REPORTER_ASSERT(r, fAppliedFull.style().isSimpleHairline()); | 117 REPORTER_ASSERT(r, fAppliedFull.style().isSimpleHairline()); |
115 } | 118 } |
116 } | 119 } |
117 } | 120 } |
118 | 121 |
119 GrShape fBase; | 122 GrShape fBase; |
120 GrShape fAppliedPE; | 123 GrShape fAppliedPE; |
121 GrShape fAppliedPEThenStroke; | 124 GrShape fAppliedPEThenStroke; |
122 GrShape fAppliedFull; | 125 GrShape fAppliedFull; |
123 | 126 |
124 Key fBaseKey; | 127 Key fBaseKey; |
125 Key fAppliedPEKey; | 128 Key fAppliedPEKey; |
126 Key fAppliedPEThenStrokeKey; | 129 Key fAppliedPEThenStrokeKey; |
127 Key fAppliedFullKey; | 130 Key fAppliedFullKey; |
128 | |
129 }; | 131 }; |
130 | 132 |
131 void TestCase::testExpectations(skiatest::Reporter* reporter, SelfExpectations e
xpectations) const { | 133 void TestCase::testExpectations(skiatest::Reporter* reporter, SelfExpectations e
xpectations) const { |
132 // The base's key should always be valid (unless the path is volatile) | 134 // The base's key should always be valid (unless the path is volatile) |
133 REPORTER_ASSERT(reporter, fBaseKey.count()); | 135 REPORTER_ASSERT(reporter, fBaseKey.count()); |
134 if (expectations.fPEHasEffect) { | 136 if (expectations.fPEHasEffect) { |
135 REPORTER_ASSERT(reporter, fBaseKey != fAppliedPEKey); | 137 REPORTER_ASSERT(reporter, fBaseKey != fAppliedPEKey); |
136 REPORTER_ASSERT(reporter, expectations.fPEHasValidKey == SkToBool(fAppli
edPEKey.count())); | 138 REPORTER_ASSERT(reporter, expectations.fPEHasValidKey == SkToBool(fAppli
edPEKey.count())); |
137 REPORTER_ASSERT(reporter, fBaseKey != fAppliedFullKey); | 139 REPORTER_ASSERT(reporter, fBaseKey != fAppliedFullKey); |
138 REPORTER_ASSERT(reporter, expectations.fPEHasValidKey == SkToBool(fAppli
edFullKey.count())); | 140 REPORTER_ASSERT(reporter, expectations.fPEHasValidKey == SkToBool(fAppli
edFullKey.count())); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 hairline.setStyle(SkPaint::kStroke_Style); | 291 hairline.setStyle(SkPaint::kStroke_Style); |
290 hairline.setStrokeWidth(0.f); | 292 hairline.setStrokeWidth(0.f); |
291 TestCase hairlineCase(geo, hairline, reporter); | 293 TestCase hairlineCase(geo, hairline, reporter); |
292 // Since hairline style doesn't change the SkPath data, it is keyed identica
lly to fill. | 294 // Since hairline style doesn't change the SkPath data, it is keyed identica
lly to fill. |
293 hairlineCase.compare(reporter, fillCase, TestCase::kAllSame_ComparisonExpeca
tion); | 295 hairlineCase.compare(reporter, fillCase, TestCase::kAllSame_ComparisonExpeca
tion); |
294 REPORTER_ASSERT(reporter, hairlineCase.baseShape().style().isSimpleHairline(
)); | 296 REPORTER_ASSERT(reporter, hairlineCase.baseShape().style().isSimpleHairline(
)); |
295 REPORTER_ASSERT(reporter, hairlineCase.appliedFullStyleShape().style().isSim
pleHairline()); | 297 REPORTER_ASSERT(reporter, hairlineCase.appliedFullStyleShape().style().isSim
pleHairline()); |
296 REPORTER_ASSERT(reporter, hairlineCase.appliedPathEffectShape().style().isSi
mpleHairline()); | 298 REPORTER_ASSERT(reporter, hairlineCase.appliedPathEffectShape().style().isSi
mpleHairline()); |
297 } | 299 } |
298 | 300 |
| 301 template<typename GEO> |
| 302 static void test_scale(skiatest::Reporter* reporter, const GEO& geo) { |
| 303 sk_sp<SkPathEffect> dashPE = make_dash(); |
| 304 |
| 305 static const SkScalar kS1 = 1.f; |
| 306 static const SkScalar kS2 = 2.f; |
| 307 |
| 308 SkPaint fill; |
| 309 TestCase fillCase1(geo, fill, reporter, kS1); |
| 310 TestCase fillCase2(geo, fill, reporter, kS2); |
| 311 // Scale doesn't affect fills. |
| 312 fillCase1.compare(reporter, fillCase2, TestCase::kAllSame_ComparisonExpecati
on); |
| 313 |
| 314 SkPaint hairline; |
| 315 hairline.setStyle(SkPaint::kStroke_Style); |
| 316 hairline.setStrokeWidth(0.f); |
| 317 TestCase hairlineCase1(geo, hairline, reporter, kS1); |
| 318 TestCase hairlineCase2(geo, hairline, reporter, kS2); |
| 319 // Scale doesn't affect hairlines. |
| 320 hairlineCase1.compare(reporter, hairlineCase2, TestCase::kAllSame_Comparison
Expecation); |
| 321 |
| 322 SkPaint stroke; |
| 323 stroke.setStyle(SkPaint::kStroke_Style); |
| 324 stroke.setStrokeWidth(2.f); |
| 325 TestCase strokeCase1(geo, stroke, reporter, kS1); |
| 326 TestCase strokeCase2(geo, stroke, reporter, kS2); |
| 327 // Scale affects the stroke. |
| 328 strokeCase1.compare(reporter, strokeCase2, TestCase::kSameUpToStroke_Compari
sonExpecation); |
| 329 |
| 330 SkPaint strokeDash = stroke; |
| 331 strokeDash.setPathEffect(make_dash()); |
| 332 TestCase strokeDashCase1(geo, strokeDash, reporter, kS1); |
| 333 TestCase strokeDashCase2(geo, strokeDash, reporter, kS2); |
| 334 // Scale affects the dash and the stroke. |
| 335 strokeDashCase1.compare(reporter, strokeDashCase2, TestCase::kSameUpToPE_Co
mparisonExpecation); |
| 336 |
| 337 // Stroke and fill cases |
| 338 SkPaint strokeAndFill = stroke; |
| 339 strokeAndFill.setStyle(SkPaint::kStrokeAndFill_Style); |
| 340 TestCase strokeAndFillCase1(geo, strokeAndFill, reporter, kS1); |
| 341 TestCase strokeAndFillCase2(geo, strokeAndFill, reporter, kS2); |
| 342 // Scale affects the stroke. Though, this can wind up creating a rect when t
he input is a rect. |
| 343 // In that case we wind up with a pure geometry key and the geometries are t
he same. |
| 344 SkRRect rrect; |
| 345 if (strokeAndFillCase1.appliedFullStyleShape().asRRect(&rrect)) { |
| 346 // We currently only expect to get here in the rect->rect case. |
| 347 REPORTER_ASSERT(reporter, rrect.isRect()); |
| 348 REPORTER_ASSERT(reporter, strokeAndFillCase1.baseShape().asRRect(&rrect)
&& rrect.isRect()); |
| 349 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, |
| 350 TestCase::kAllSame_ComparisonExpecation); |
| 351 } else { |
| 352 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, |
| 353 TestCase::kSameUpToStroke_ComparisonExpecatio
n); |
| 354 } |
| 355 |
| 356 SkPaint strokeAndFillDash = strokeDash; |
| 357 strokeAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style); |
| 358 TestCase strokeAndFillDashCase1(geo, strokeAndFillDash, reporter, kS1); |
| 359 TestCase strokeAndFillDashCase2(geo, strokeAndFillDash, reporter, kS2); |
| 360 // Scale affects the path effect and stroke. |
| 361 strokeAndFillDashCase1.compare(reporter, strokeAndFillDashCase2, |
| 362 TestCase::kSameUpToPE_ComparisonExpecation); |
| 363 } |
| 364 |
299 template <typename GEO, typename T> | 365 template <typename GEO, typename T> |
300 static void test_stroke_param_impl(skiatest::Reporter* reporter, const GEO& geo, | 366 static void test_stroke_param_impl(skiatest::Reporter* reporter, const GEO& geo, |
301 std::function<void(SkPaint*, T)> setter, T a,
T b, | 367 std::function<void(SkPaint*, T)> setter, T a,
T b, |
302 bool paramAffectsStroke, | 368 bool paramAffectsStroke, |
303 bool paramAffectsDashAndStroke) { | 369 bool paramAffectsDashAndStroke) { |
304 // Set the stroke width so that we don't get hairline. However, call the set
ter afterward so | 370 // Set the stroke width so that we don't get hairline. However, call the set
ter afterward so |
305 // that it can override the stroke width. | 371 // that it can override the stroke width. |
306 SkPaint strokeA; | 372 SkPaint strokeA; |
307 strokeA.setStyle(SkPaint::kStroke_Style); | 373 strokeA.setStyle(SkPaint::kStroke_Style); |
308 strokeA.setStrokeWidth(2.f); | 374 strokeA.setStrokeWidth(2.f); |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 dashAndStrokeEmptyRectCase.compare(reporter, fillEmptyCase, | 807 dashAndStrokeEmptyRectCase.compare(reporter, fillEmptyCase, |
742 TestCase::kAllSame_ComparisonExpecation); | 808 TestCase::kAllSame_ComparisonExpecation); |
743 } | 809 } |
744 | 810 |
745 DEF_TEST(GrShape, reporter) { | 811 DEF_TEST(GrShape, reporter) { |
746 sk_sp<SkPathEffect> dashPE = make_dash(); | 812 sk_sp<SkPathEffect> dashPE = make_dash(); |
747 | 813 |
748 for (auto rr : { SkRRect::MakeRect(SkRect::MakeWH(10, 10)), | 814 for (auto rr : { SkRRect::MakeRect(SkRect::MakeWH(10, 10)), |
749 SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4)}) { | 815 SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4)}) { |
750 test_basic(reporter, rr); | 816 test_basic(reporter, rr); |
| 817 test_scale(reporter, rr); |
751 test_dash_fill(reporter, rr); | 818 test_dash_fill(reporter, rr); |
752 test_null_dash(reporter, rr); | 819 test_null_dash(reporter, rr); |
753 // Test modifying various stroke params. | 820 // Test modifying various stroke params. |
754 test_stroke_param<SkRRect, SkScalar>( | 821 test_stroke_param<SkRRect, SkScalar>( |
755 reporter, rr, | 822 reporter, rr, |
756 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, | 823 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, |
757 SkIntToScalar(2), SkIntToScalar(4)); | 824 SkIntToScalar(2), SkIntToScalar(4)); |
758 test_stroke_param<SkRRect, SkPaint::Join>( | 825 test_stroke_param<SkRRect, SkPaint::Join>( |
759 reporter, rr, | 826 reporter, rr, |
760 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);
}, | 827 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);
}, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 for (auto testPath : paths) { | 869 for (auto testPath : paths) { |
803 const SkPath& path = testPath.fPath; | 870 const SkPath& path = testPath.fPath; |
804 // These tests all assume that the original GrShape for fill and stroke
will be the same. | 871 // These tests all assume that the original GrShape for fill and stroke
will be the same. |
805 // However, that is not the case in special cases (e.g. a unclosed rect
becomes a RRect | 872 // However, that is not the case in special cases (e.g. a unclosed rect
becomes a RRect |
806 // GrShape with a fill style but becomes a Path GrShape when stroked). | 873 // GrShape with a fill style but becomes a Path GrShape when stroked). |
807 if (testPath.fIsRRectForFill == testPath.fIsRRectForStroke) { | 874 if (testPath.fIsRRectForFill == testPath.fIsRRectForStroke) { |
808 test_basic(reporter, path); | 875 test_basic(reporter, path); |
809 test_null_dash(reporter, path); | 876 test_null_dash(reporter, path); |
810 test_path_effect_makes_rrect(reporter, path); | 877 test_path_effect_makes_rrect(reporter, path); |
811 } | 878 } |
| 879 test_scale(reporter, path); |
812 // This test uses a stroking paint, hence use of fIsRRectForStroke | 880 // This test uses a stroking paint, hence use of fIsRRectForStroke |
813 test_volatile_path(reporter, path, testPath.fIsRRectForStroke); | 881 test_volatile_path(reporter, path, testPath.fIsRRectForStroke); |
814 test_dash_fill(reporter, path); | 882 test_dash_fill(reporter, path); |
815 // Test modifying various stroke params. | 883 // Test modifying various stroke params. |
816 test_stroke_param<SkPath, SkScalar>( | 884 test_stroke_param<SkPath, SkScalar>( |
817 reporter, path, | 885 reporter, path, |
818 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, | 886 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, |
819 SkIntToScalar(2), SkIntToScalar(4)); | 887 SkIntToScalar(2), SkIntToScalar(4)); |
820 test_stroke_param<SkPath, SkPaint::Join>( | 888 test_stroke_param<SkPath, SkPaint::Join>( |
821 reporter, path, | 889 reporter, path, |
(...skipping 30 matching lines...) Expand all Loading... |
852 } | 920 } |
853 } | 921 } |
854 | 922 |
855 // Test a volatile empty path. | 923 // Test a volatile empty path. |
856 test_volatile_path(reporter, SkPath(), true); | 924 test_volatile_path(reporter, SkPath(), true); |
857 | 925 |
858 test_empty_shape(reporter); | 926 test_empty_shape(reporter); |
859 } | 927 } |
860 | 928 |
861 #endif | 929 #endif |
OLD | NEW |