| 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 |