Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: tests/GrShapeTest.cpp

Issue 2277483002: Update GrShape test to allow more flexible shape creation. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Address comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 return false; 67 return false;
68 } 68 }
69 } 69 }
70 #ifdef SK_BUILD_FOR_WIN 70 #ifdef SK_BUILD_FOR_WIN
71 free(const_cast<uint8_t*>(kZeros)); 71 free(const_cast<uint8_t*>(kZeros));
72 #endif 72 #endif
73 return true; 73 return true;
74 } 74 }
75 75
76 namespace { 76 namespace {
77 /**
78 * Geo is a factory for creating a GrShape from another representation. It also answers some
79 * questions about expected behavior for GrShape given the inputs.
80 */
81 class Geo {
82 public:
83 virtual ~Geo() {};
84 virtual GrShape makeShape(const SkPaint&) const = 0;
85 virtual SkPath path() const = 0;
86 // These functions allow tests to check for special cases where style gets
87 // applied by GrShape in its constructor (without calling GrShape::applyStyl e).
88 // These unfortunately rely on knowing details of GrShape's implementation.
89 // These predicates are factored out here to avoid littering the rest of the
90 // test code with GrShape implementation details.
91 virtual bool fillChangesGeom() const { return false; }
92 virtual bool strokeIsConvertedToFill() const { return false; }
93 virtual bool strokeAndFillIsConvertedToFill(const SkPaint&) const { return f alse; }
94 // Is this something we expect GrShape to recognize as something simpler tha n a path.
95 virtual bool isNonPath(const SkPaint& paint) const { return true; }
96 };
97
98 class RectGeo : public Geo {
99 public:
100 RectGeo(const SkRect& rect) : fRect(rect) {}
101
102 SkPath path() const override {
103 SkPath path;
104 path.addRect(fRect);
105 return path;
106 }
107
108 GrShape makeShape(const SkPaint& paint) const override {
109 return GrShape(fRect, paint);
110 }
111
112 bool strokeAndFillIsConvertedToFill(const SkPaint& paint) const override {
113 SkASSERT(paint.getStyle() == SkPaint::kStrokeAndFill_Style);
114 // Converted to an outset rectangle.
115 return paint.getStrokeJoin() == SkPaint::kMiter_Join &&
116 paint.getStrokeMiter() >= SK_ScalarSqrt2;
117 }
118
119 private:
120 SkRect fRect;
121 };
122
123 class RRectGeo : public Geo {
124 public:
125 RRectGeo(const SkRRect& rrect) : fRRect(rrect) {}
126
127 GrShape makeShape(const SkPaint& paint) const override {
128 return GrShape(fRRect, paint);
129 }
130
131 SkPath path() const override {
132 SkPath path;
133 path.addRRect(fRRect);
134 return path;
135 }
136
137 bool strokeAndFillIsConvertedToFill(const SkPaint& paint) const override {
138 SkASSERT(paint.getStyle() == SkPaint::kStrokeAndFill_Style);
139 if (fRRect.isRect()) {
140 return RectGeo(fRRect.rect()).strokeAndFillIsConvertedToFill(paint);
141 }
142 return false;
143 }
144
145 private:
146 SkRRect fRRect;
147 };
148
149 class PathGeo : public Geo {
150 public:
151 enum class Invert { kNo, kYes };
152
153 PathGeo(const SkPath& path, Invert invert) : fPath(path) {
154 SkASSERT(!path.isInverseFillType());
155 if (Invert::kYes == invert) {
156 if (fPath.getFillType() == SkPath::kEvenOdd_FillType) {
157 fPath.setFillType(SkPath::kInverseEvenOdd_FillType);
158 } else {
159 SkASSERT(fPath.getFillType() == SkPath::kWinding_FillType);
160 fPath.setFillType(SkPath::kInverseWinding_FillType);
161 }
162 }
163 }
164
165 GrShape makeShape(const SkPaint& paint) const override {
166 return GrShape(fPath, paint);
167 }
168
169 SkPath path() const override { return fPath; }
170
171 bool fillChangesGeom() const override {
172 // unclosed rects get closed. Lines get turned into empty geometry
173 return this->isUnclosedRect() || (fPath.isLine(nullptr) && !fPath.isInve rseFillType());
174 }
175
176 bool strokeIsConvertedToFill() const override {
177 return this->isAxisAlignedLine();
178 }
179
180 bool strokeAndFillIsConvertedToFill(const SkPaint& paint) const override {
181 SkASSERT(paint.getStyle() == SkPaint::kStrokeAndFill_Style);
182 if (this->isAxisAlignedLine()) {
183 // The fill is ignored (zero area) and the stroke is converted to a rrect.
184 return true;
185 }
186 SkRect rect;
187 unsigned start;
188 SkPath::Direction dir;
189 if (SkPathPriv::IsSimpleClosedRect(fPath, &rect, &dir, &start)) {
190 return RectGeo(rect).strokeAndFillIsConvertedToFill(paint);
191 }
192 return false;
193 }
194
195 bool isNonPath(const SkPaint& paint) const override {
196 return fPath.isLine(nullptr) || fPath.isEmpty();
197 }
198
199 private:
200 bool isAxisAlignedLine() const {
201 SkPoint pts[2];
202 if (!fPath.isLine(pts)) {
203 return false;
204 }
205 return pts[0].fX == pts[1].fX || pts[0].fY == pts[1].fY;
206 }
207
208 bool isUnclosedRect() const {
209 bool closed;
210 return fPath.isRect(nullptr, &closed, nullptr) && !closed;
211 }
212
213 SkPath fPath;
214 };
215
216 class RRectPathGeo : public PathGeo {
217 public:
218 enum class RRectForStroke { kNo, kYes };
219
220 RRectPathGeo(const SkPath& path, const SkRRect& equivalentRRect, RRectForStr oke rrectForStroke,
221 Invert invert)
222 : PathGeo(path, invert)
223 , fRRect(equivalentRRect)
224 , fRRectForStroke(rrectForStroke) {}
225
226 RRectPathGeo(const SkPath& path, const SkRect& equivalentRect, RRectForStrok e rrectForStroke,
227 Invert invert)
228 : RRectPathGeo(path, SkRRect::MakeRect(equivalentRect), rrectForStro ke, invert) {}
229
230 bool isNonPath(const SkPaint& paint) const override {
231 if (SkPaint::kFill_Style == paint.getStyle() || RRectForStroke::kYes == fRRectForStroke) {
232 return true;
233 }
234 return false;
235 }
236
237 const SkRRect& rrect() const { return fRRect; }
238
239 private:
240 SkRRect fRRect;
241 RRectForStroke fRRectForStroke;
242 };
243
77 class TestCase { 244 class TestCase {
78 public: 245 public:
79 template <typename GEO> 246 TestCase(const Geo& geo, const SkPaint& paint, skiatest::Reporter* r,
80 TestCase(const GEO& geo, const SkPaint& paint, skiatest::Reporter* r, 247 SkScalar scale = SK_Scalar1) : fBase(geo.makeShape(paint)) {
81 SkScalar scale = SK_Scalar1) : fBase(geo, paint) {
82 this->init(r, scale); 248 this->init(r, scale);
83 } 249 }
84 250
251 template<typename... ShapeArgs>
252 TestCase(skiatest::Reporter* r, ShapeArgs... shapeArgs)
253 : fBase(shapeArgs...) {
254 this->init(r, SK_Scalar1);
255 }
256
85 TestCase(const GrShape& shape, skiatest::Reporter* r, SkScalar scale = SK_Sc alar1) 257 TestCase(const GrShape& shape, skiatest::Reporter* r, SkScalar scale = SK_Sc alar1)
86 : fBase(shape) { 258 : fBase(shape) {
87 this->init(r, scale); 259 this->init(r, scale);
88 } 260 }
89 261
90 struct SelfExpectations { 262 struct SelfExpectations {
91 bool fPEHasEffect; 263 bool fPEHasEffect;
92 bool fPEHasValidKey; 264 bool fPEHasValidKey;
93 bool fStrokeApplies; 265 bool fStrokeApplies;
94 }; 266 };
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 static const SkScalar kIntervals[] = { 0.25, 3.f, 0.5, 2.f }; 598 static const SkScalar kIntervals[] = { 0.25, 3.f, 0.5, 2.f };
427 static const SkScalar kPhase = 0.75; 599 static const SkScalar kPhase = 0.75;
428 return SkDashPathEffect::Make(kIntervals, SK_ARRAY_COUNT(kIntervals), kPhase ); 600 return SkDashPathEffect::Make(kIntervals, SK_ARRAY_COUNT(kIntervals), kPhase );
429 } 601 }
430 602
431 static sk_sp<SkPathEffect> make_null_dash() { 603 static sk_sp<SkPathEffect> make_null_dash() {
432 static const SkScalar kNullIntervals[] = {0, 0, 0, 0, 0, 0}; 604 static const SkScalar kNullIntervals[] = {0, 0, 0, 0, 0, 0};
433 return SkDashPathEffect::Make(kNullIntervals, SK_ARRAY_COUNT(kNullIntervals) , 0.f); 605 return SkDashPathEffect::Make(kNullIntervals, SK_ARRAY_COUNT(kNullIntervals) , 0.f);
434 } 606 }
435 607
436 ////////////////////////////////////////////////////////////////////////////// 608 static void test_basic(skiatest::Reporter* reporter, const Geo& geo) {
437 // These functions allow tests to check for special cases where style gets
438 // applied by GrShape in its constructor (without calling GrShape::applyStyle).
439 // These unfortunately rely on knowing details of GrShape's implementation.
440 // These predicates are factored out here to avoid littering the rest of the
441 // test code with GrShape implementation details.
442
443 static bool path_is_axis_aligned_line(const SkPath& path) {
444 SkPoint pts[2];
445 if (!path.isLine(pts)) {
446 return false;
447 }
448 return pts[0].fX == pts[1].fX || pts[0].fY == pts[1].fY;
449 }
450
451 static bool path_is_unclosed_rect(const SkPath& path) {
452 bool closed;
453 return path.isRect(nullptr, &closed, nullptr) && !closed;
454 }
455
456 // Will a GrShape constructed from a geometry perform a geometric transformation if the style is
457 // simple fill that would not otherwise be applied.
458 template <typename GEO> static bool fill_changes_geom(const GEO& geo) { return f alse; }
459 template <> bool fill_changes_geom<SkPath>(const SkPath& path) {
460 // unclosed rects get closed. Lines get turned into empty geometry
461 return path_is_unclosed_rect(path) || (path.isLine(nullptr) && !path.isInver seFillType());
462 }
463
464 // Will a GrShape constructed from the geometry with a stroke style (without pat h effect) perform a
465 // geometric transformation that applies the the stroke immediately without stor ing a stroke style.
466 template <typename GEO> static bool stroke_is_converted_to_fill(const GEO& geo) { return false; }
467 template <> bool stroke_is_converted_to_fill(const SkPath& path) {
468 // converted to a rrect.
469 return path_is_axis_aligned_line(path);
470 }
471
472 // Will a GrShape constructed from the geometry with a stroke-and-fill style (wi thout path effect)
473 // perform a geometric transformation that applies the the stroke immediately wi thout storing a
474 // stroke-and-fill style.
475 template <typename GEO> static bool stroke_and_fill_is_converted_to_fill(const G EO& geo, const SkPaint& paint);
476 template <> bool stroke_and_fill_is_converted_to_fill(const SkRect& rect, const SkPaint& paint) {
477 SkASSERT(paint.getStyle() == SkPaint::kStrokeAndFill_Style);
478 // Converted to an outset rectangle.
479 return paint.getStrokeJoin() == SkPaint::kMiter_Join &&
480 paint.getStrokeMiter() >= SK_ScalarSqrt2;
481 }
482 template <> bool stroke_and_fill_is_converted_to_fill(const SkPath& path, const SkPaint& paint) {
483 SkASSERT(paint.getStyle() == SkPaint::kStrokeAndFill_Style);
484 if (path_is_axis_aligned_line(path)) {
485 // The fill is ignored (zero area) and the stroke is converted to a rrec t.
486 return true;
487 }
488 SkRect rect;
489 unsigned start;
490 SkPath::Direction dir;
491 if (SkPathPriv::IsSimpleClosedRect(path, &rect, &dir, &start)) {
492 return stroke_and_fill_is_converted_to_fill<SkRect>(rect, paint);
493 }
494 return false;
495 }
496 template <> bool stroke_and_fill_is_converted_to_fill(const SkRRect& rr, const S kPaint& paint) {
497 SkASSERT(paint.getStyle() == SkPaint::kStrokeAndFill_Style);
498 if (rr.isRect()) {
499 return stroke_and_fill_is_converted_to_fill<SkRect>(rr.rect(), paint);
500 }
501 return false;
502 }
503
504 //////////////////////////////////////////////////////////////////////////////
505
506 template<typename GEO>
507 static void test_basic(skiatest::Reporter* reporter, const GEO& geo) {
508 sk_sp<SkPathEffect> dashPE = make_dash(); 609 sk_sp<SkPathEffect> dashPE = make_dash();
509 610
510 TestCase::SelfExpectations expectations; 611 TestCase::SelfExpectations expectations;
511 SkPaint fill; 612 SkPaint fill;
512 613
513 TestCase fillCase(geo, fill, reporter); 614 TestCase fillCase(geo, fill, reporter);
514 expectations.fPEHasEffect = false; 615 expectations.fPEHasEffect = false;
515 expectations.fPEHasValidKey = false; 616 expectations.fPEHasValidKey = false;
516 expectations.fStrokeApplies = false; 617 expectations.fStrokeApplies = false;
517 fillCase.testExpectations(reporter, expectations); 618 fillCase.testExpectations(reporter, expectations);
518 // Test that another GrShape instance built from the same primitive is the s ame. 619 // Test that another GrShape instance built from the same primitive is the s ame.
519 TestCase(geo, fill, reporter).compare(reporter, fillCase, 620 TestCase(geo, fill, reporter).compare(reporter, fillCase,
520 TestCase::kAllSame_ComparisonExpecatio n); 621 TestCase::kAllSame_ComparisonExpecatio n);
521 622
522 SkPaint stroke2RoundBevel; 623 SkPaint stroke2RoundBevel;
523 stroke2RoundBevel.setStyle(SkPaint::kStroke_Style); 624 stroke2RoundBevel.setStyle(SkPaint::kStroke_Style);
524 stroke2RoundBevel.setStrokeCap(SkPaint::kRound_Cap); 625 stroke2RoundBevel.setStrokeCap(SkPaint::kRound_Cap);
525 stroke2RoundBevel.setStrokeJoin(SkPaint::kBevel_Join); 626 stroke2RoundBevel.setStrokeJoin(SkPaint::kBevel_Join);
526 stroke2RoundBevel.setStrokeWidth(2.f); 627 stroke2RoundBevel.setStrokeWidth(2.f);
527 TestCase stroke2RoundBevelCase(geo, stroke2RoundBevel, reporter); 628 TestCase stroke2RoundBevelCase(geo, stroke2RoundBevel, reporter);
528 expectations.fPEHasValidKey = true; 629 expectations.fPEHasValidKey = true;
529 expectations.fPEHasEffect = false; 630 expectations.fPEHasEffect = false;
530 expectations.fStrokeApplies = !stroke_is_converted_to_fill(geo); 631 expectations.fStrokeApplies = !geo.strokeIsConvertedToFill();
531 stroke2RoundBevelCase.testExpectations(reporter, expectations); 632 stroke2RoundBevelCase.testExpectations(reporter, expectations);
532 TestCase(geo, stroke2RoundBevel, reporter).compare(reporter, stroke2RoundBev elCase, 633 TestCase(geo, stroke2RoundBevel, reporter).compare(reporter, stroke2RoundBev elCase,
533 TestCase::kAllSame_Compar isonExpecation); 634 TestCase::kAllSame_Compar isonExpecation);
534 635
535 SkPaint stroke2RoundBevelDash = stroke2RoundBevel; 636 SkPaint stroke2RoundBevelDash = stroke2RoundBevel;
536 stroke2RoundBevelDash.setPathEffect(make_dash()); 637 stroke2RoundBevelDash.setPathEffect(make_dash());
537 TestCase stroke2RoundBevelDashCase(geo, stroke2RoundBevelDash, reporter); 638 TestCase stroke2RoundBevelDashCase(geo, stroke2RoundBevelDash, reporter);
538 expectations.fPEHasValidKey = true; 639 expectations.fPEHasValidKey = true;
539 expectations.fPEHasEffect = true; 640 expectations.fPEHasEffect = true;
540 expectations.fStrokeApplies = true; 641 expectations.fStrokeApplies = true;
541 stroke2RoundBevelDashCase.testExpectations(reporter, expectations); 642 stroke2RoundBevelDashCase.testExpectations(reporter, expectations);
542 TestCase(geo, stroke2RoundBevelDash, reporter).compare(reporter, stroke2Roun dBevelDashCase, 643 TestCase(geo, stroke2RoundBevelDash, reporter).compare(reporter, stroke2Roun dBevelDashCase,
543 TestCase::kAllSame_Co mparisonExpecation); 644 TestCase::kAllSame_Co mparisonExpecation);
544 645
545 if (fill_changes_geom(geo) || stroke_is_converted_to_fill(geo)) { 646 if (geo.fillChangesGeom() || geo.strokeIsConvertedToFill()) {
546 fillCase.compare(reporter, stroke2RoundBevelCase, 647 fillCase.compare(reporter, stroke2RoundBevelCase,
547 TestCase::kAllDifferent_ComparisonExpecation); 648 TestCase::kAllDifferent_ComparisonExpecation);
548 fillCase.compare(reporter, stroke2RoundBevelDashCase, 649 fillCase.compare(reporter, stroke2RoundBevelDashCase,
549 TestCase::kAllDifferent_ComparisonExpecation); 650 TestCase::kAllDifferent_ComparisonExpecation);
550 } else { 651 } else {
551 fillCase.compare(reporter, stroke2RoundBevelCase, 652 fillCase.compare(reporter, stroke2RoundBevelCase,
552 TestCase::kSameUpToStroke_ComparisonExpecation); 653 TestCase::kSameUpToStroke_ComparisonExpecation);
553 fillCase.compare(reporter, stroke2RoundBevelDashCase, 654 fillCase.compare(reporter, stroke2RoundBevelDashCase,
554 TestCase::kSameUpToPE_ComparisonExpecation); 655 TestCase::kSameUpToPE_ComparisonExpecation);
555 } 656 }
556 if (stroke_is_converted_to_fill(geo)) { 657 if (geo.strokeIsConvertedToFill()) {
557 stroke2RoundBevelCase.compare(reporter, stroke2RoundBevelDashCase, 658 stroke2RoundBevelCase.compare(reporter, stroke2RoundBevelDashCase,
558 TestCase::kAllDifferent_ComparisonExpecati on); 659 TestCase::kAllDifferent_ComparisonExpecati on);
559 } else { 660 } else {
560 stroke2RoundBevelCase.compare(reporter, stroke2RoundBevelDashCase, 661 stroke2RoundBevelCase.compare(reporter, stroke2RoundBevelDashCase,
561 TestCase::kSameUpToPE_ComparisonExpecation ); 662 TestCase::kSameUpToPE_ComparisonExpecation );
562 } 663 }
563 664
564 // Stroke and fill cases 665 // Stroke and fill cases
565 SkPaint stroke2RoundBevelAndFill = stroke2RoundBevel; 666 SkPaint stroke2RoundBevelAndFill = stroke2RoundBevel;
566 stroke2RoundBevelAndFill.setStyle(SkPaint::kStrokeAndFill_Style); 667 stroke2RoundBevelAndFill.setStyle(SkPaint::kStrokeAndFill_Style);
567 TestCase stroke2RoundBevelAndFillCase(geo, stroke2RoundBevelAndFill, reporte r); 668 TestCase stroke2RoundBevelAndFillCase(geo, stroke2RoundBevelAndFill, reporte r);
568 expectations.fPEHasValidKey = true; 669 expectations.fPEHasValidKey = true;
569 expectations.fPEHasEffect = false; 670 expectations.fPEHasEffect = false;
570 expectations.fStrokeApplies = !stroke_is_converted_to_fill(geo); 671 expectations.fStrokeApplies = !geo.strokeIsConvertedToFill();
571 stroke2RoundBevelAndFillCase.testExpectations(reporter, expectations); 672 stroke2RoundBevelAndFillCase.testExpectations(reporter, expectations);
572 TestCase(geo, stroke2RoundBevelAndFill, reporter).compare(reporter, 673 TestCase(geo, stroke2RoundBevelAndFill, reporter).compare(reporter,
573 stroke2RoundBevelAndFillCase, TestCase::kAllSame_ComparisonExpecatio n); 674 stroke2RoundBevelAndFillCase, TestCase::kAllSame_ComparisonExpecatio n);
574 675
575 SkPaint stroke2RoundBevelAndFillDash = stroke2RoundBevelDash; 676 SkPaint stroke2RoundBevelAndFillDash = stroke2RoundBevelDash;
576 stroke2RoundBevelAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style); 677 stroke2RoundBevelAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style);
577 TestCase stroke2RoundBevelAndFillDashCase(geo, stroke2RoundBevelAndFillDash, reporter); 678 TestCase stroke2RoundBevelAndFillDashCase(geo, stroke2RoundBevelAndFillDash, reporter);
578 expectations.fPEHasValidKey = true; 679 expectations.fPEHasValidKey = true;
579 expectations.fPEHasEffect = false; 680 expectations.fPEHasEffect = false;
580 expectations.fStrokeApplies = !stroke_is_converted_to_fill(geo); 681 expectations.fStrokeApplies = !geo.strokeIsConvertedToFill();
581 stroke2RoundBevelAndFillDashCase.testExpectations(reporter, expectations); 682 stroke2RoundBevelAndFillDashCase.testExpectations(reporter, expectations);
582 TestCase(geo, stroke2RoundBevelAndFillDash, reporter).compare( 683 TestCase(geo, stroke2RoundBevelAndFillDash, reporter).compare(
583 reporter, stroke2RoundBevelAndFillDashCase, TestCase::kAllSame_Compariso nExpecation); 684 reporter, stroke2RoundBevelAndFillDashCase, TestCase::kAllSame_Compariso nExpecation);
584 stroke2RoundBevelAndFillDashCase.compare(reporter, stroke2RoundBevelAndFillC ase, 685 stroke2RoundBevelAndFillDashCase.compare(reporter, stroke2RoundBevelAndFillC ase,
585 TestCase::kAllSame_ComparisonExpeca tion); 686 TestCase::kAllSame_ComparisonExpeca tion);
586 687
587 SkPaint hairline; 688 SkPaint hairline;
588 hairline.setStyle(SkPaint::kStroke_Style); 689 hairline.setStyle(SkPaint::kStroke_Style);
589 hairline.setStrokeWidth(0.f); 690 hairline.setStrokeWidth(0.f);
590 TestCase hairlineCase(geo, hairline, reporter); 691 TestCase hairlineCase(geo, hairline, reporter);
591 // Since hairline style doesn't change the SkPath data, it is keyed identica lly to fill (except 692 // Since hairline style doesn't change the SkPath data, it is keyed identica lly to fill (except
592 // in the line and unclosed rect cases). 693 // in the line and unclosed rect cases).
593 if (fill_changes_geom(geo)) { 694 if (geo.fillChangesGeom()) {
594 hairlineCase.compare(reporter, fillCase, TestCase::kAllDifferent_Compari sonExpecation); 695 hairlineCase.compare(reporter, fillCase, TestCase::kAllDifferent_Compari sonExpecation);
595 } else { 696 } else {
596 hairlineCase.compare(reporter, fillCase, TestCase::kAllSame_ComparisonEx pecation); 697 hairlineCase.compare(reporter, fillCase, TestCase::kAllSame_ComparisonEx pecation);
597 } 698 }
598 REPORTER_ASSERT(reporter, hairlineCase.baseShape().style().isSimpleHairline( )); 699 REPORTER_ASSERT(reporter, hairlineCase.baseShape().style().isSimpleHairline( ));
599 REPORTER_ASSERT(reporter, hairlineCase.appliedFullStyleShape().style().isSim pleHairline()); 700 REPORTER_ASSERT(reporter, hairlineCase.appliedFullStyleShape().style().isSim pleHairline());
600 REPORTER_ASSERT(reporter, hairlineCase.appliedPathEffectShape().style().isSi mpleHairline()); 701 REPORTER_ASSERT(reporter, hairlineCase.appliedPathEffectShape().style().isSi mpleHairline());
601 702
602 } 703 }
603 704
604 template<typename GEO> 705 static void test_scale(skiatest::Reporter* reporter, const Geo& geo) {
605 static void test_scale(skiatest::Reporter* reporter, const GEO& geo) {
606 sk_sp<SkPathEffect> dashPE = make_dash(); 706 sk_sp<SkPathEffect> dashPE = make_dash();
607 707
608 static const SkScalar kS1 = 1.f; 708 static const SkScalar kS1 = 1.f;
609 static const SkScalar kS2 = 2.f; 709 static const SkScalar kS2 = 2.f;
610 710
611 SkPaint fill; 711 SkPaint fill;
612 TestCase fillCase1(geo, fill, reporter, kS1); 712 TestCase fillCase1(geo, fill, reporter, kS1);
613 TestCase fillCase2(geo, fill, reporter, kS2); 713 TestCase fillCase2(geo, fill, reporter, kS2);
614 // Scale doesn't affect fills. 714 // Scale doesn't affect fills.
615 fillCase1.compare(reporter, fillCase2, TestCase::kAllSame_ComparisonExpecati on); 715 fillCase1.compare(reporter, fillCase2, TestCase::kAllSame_ComparisonExpecati on);
616 716
617 SkPaint hairline; 717 SkPaint hairline;
618 hairline.setStyle(SkPaint::kStroke_Style); 718 hairline.setStyle(SkPaint::kStroke_Style);
619 hairline.setStrokeWidth(0.f); 719 hairline.setStrokeWidth(0.f);
620 TestCase hairlineCase1(geo, hairline, reporter, kS1); 720 TestCase hairlineCase1(geo, hairline, reporter, kS1);
621 TestCase hairlineCase2(geo, hairline, reporter, kS2); 721 TestCase hairlineCase2(geo, hairline, reporter, kS2);
622 // Scale doesn't affect hairlines. 722 // Scale doesn't affect hairlines.
623 hairlineCase1.compare(reporter, hairlineCase2, TestCase::kAllSame_Comparison Expecation); 723 hairlineCase1.compare(reporter, hairlineCase2, TestCase::kAllSame_Comparison Expecation);
624 724
625 SkPaint stroke; 725 SkPaint stroke;
626 stroke.setStyle(SkPaint::kStroke_Style); 726 stroke.setStyle(SkPaint::kStroke_Style);
627 stroke.setStrokeWidth(2.f); 727 stroke.setStrokeWidth(2.f);
628 TestCase strokeCase1(geo, stroke, reporter, kS1); 728 TestCase strokeCase1(geo, stroke, reporter, kS1);
629 TestCase strokeCase2(geo, stroke, reporter, kS2); 729 TestCase strokeCase2(geo, stroke, reporter, kS2);
630 // Scale affects the stroke 730 // Scale affects the stroke
631 if (stroke_is_converted_to_fill(geo)) { 731 if (geo.strokeIsConvertedToFill()) {
632 REPORTER_ASSERT(reporter, !strokeCase1.baseShape().style().applies()); 732 REPORTER_ASSERT(reporter, !strokeCase1.baseShape().style().applies());
633 strokeCase1.compare(reporter, strokeCase2, TestCase::kAllSame_Comparison Expecation); 733 strokeCase1.compare(reporter, strokeCase2, TestCase::kAllSame_Comparison Expecation);
634 } else { 734 } else {
635 strokeCase1.compare(reporter, strokeCase2, TestCase::kSameUpToStroke_Com parisonExpecation); 735 strokeCase1.compare(reporter, strokeCase2, TestCase::kSameUpToStroke_Com parisonExpecation);
636 } 736 }
637 737
638 SkPaint strokeDash = stroke; 738 SkPaint strokeDash = stroke;
639 strokeDash.setPathEffect(make_dash()); 739 strokeDash.setPathEffect(make_dash());
640 TestCase strokeDashCase1(geo, strokeDash, reporter, kS1); 740 TestCase strokeDashCase1(geo, strokeDash, reporter, kS1);
641 TestCase strokeDashCase2(geo, strokeDash, reporter, kS2); 741 TestCase strokeDashCase2(geo, strokeDash, reporter, kS2);
642 // Scale affects the dash and the stroke. 742 // Scale affects the dash and the stroke.
643 strokeDashCase1.compare(reporter, strokeDashCase2, 743 strokeDashCase1.compare(reporter, strokeDashCase2,
644 TestCase::kSameUpToPE_ComparisonExpecation); 744 TestCase::kSameUpToPE_ComparisonExpecation);
645 745
646 // Stroke and fill cases 746 // Stroke and fill cases
647 SkPaint strokeAndFill = stroke; 747 SkPaint strokeAndFill = stroke;
648 strokeAndFill.setStyle(SkPaint::kStrokeAndFill_Style); 748 strokeAndFill.setStyle(SkPaint::kStrokeAndFill_Style);
649 TestCase strokeAndFillCase1(geo, strokeAndFill, reporter, kS1); 749 TestCase strokeAndFillCase1(geo, strokeAndFill, reporter, kS1);
650 TestCase strokeAndFillCase2(geo, strokeAndFill, reporter, kS2); 750 TestCase strokeAndFillCase2(geo, strokeAndFill, reporter, kS2);
651 SkPaint strokeAndFillDash = strokeDash; 751 SkPaint strokeAndFillDash = strokeDash;
652 strokeAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style); 752 strokeAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style);
653 // Dash is ignored for stroke and fill 753 // Dash is ignored for stroke and fill
654 TestCase strokeAndFillDashCase1(geo, strokeAndFillDash, reporter, kS1); 754 TestCase strokeAndFillDashCase1(geo, strokeAndFillDash, reporter, kS1);
655 TestCase strokeAndFillDashCase2(geo, strokeAndFillDash, reporter, kS2); 755 TestCase strokeAndFillDashCase2(geo, strokeAndFillDash, reporter, kS2);
656 // Scale affects the stroke, but check to make sure this didn't become a sim pler shape (e.g. 756 // Scale affects the stroke, but check to make sure this didn't become a sim pler shape (e.g.
657 // stroke-and-filled rect can become a rect), in which case the scale should n't matter and the 757 // stroke-and-filled rect can become a rect), in which case the scale should n't matter and the
658 // geometries should agree. 758 // geometries should agree.
659 if (stroke_and_fill_is_converted_to_fill(geo, strokeAndFillDash)) { 759 if (geo.strokeAndFillIsConvertedToFill(strokeAndFillDash)) {
660 REPORTER_ASSERT(reporter, !strokeAndFillCase1.baseShape().style().applie s()); 760 REPORTER_ASSERT(reporter, !strokeAndFillCase1.baseShape().style().applie s());
661 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, 761 strokeAndFillCase1.compare(reporter, strokeAndFillCase2,
662 TestCase::kAllSame_ComparisonExpecation); 762 TestCase::kAllSame_ComparisonExpecation);
663 strokeAndFillDashCase1.compare(reporter, strokeAndFillDashCase2, 763 strokeAndFillDashCase1.compare(reporter, strokeAndFillDashCase2,
664 TestCase::kAllSame_ComparisonExpecation); 764 TestCase::kAllSame_ComparisonExpecation);
665 } else { 765 } else {
666 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, 766 strokeAndFillCase1.compare(reporter, strokeAndFillCase2,
667 TestCase::kSameUpToStroke_ComparisonExpecatio n); 767 TestCase::kSameUpToStroke_ComparisonExpecatio n);
668 } 768 }
669 strokeAndFillDashCase1.compare(reporter, strokeAndFillCase1, 769 strokeAndFillDashCase1.compare(reporter, strokeAndFillCase1,
670 TestCase::kAllSame_ComparisonExpecation); 770 TestCase::kAllSame_ComparisonExpecation);
671 strokeAndFillDashCase2.compare(reporter, strokeAndFillCase2, 771 strokeAndFillDashCase2.compare(reporter, strokeAndFillCase2,
672 TestCase::kAllSame_ComparisonExpecation); 772 TestCase::kAllSame_ComparisonExpecation);
673 } 773 }
674 774
675 template <typename GEO, typename T> 775 template <typename T>
676 static void test_stroke_param_impl(skiatest::Reporter* reporter, const GEO& geo, 776 static void test_stroke_param_impl(skiatest::Reporter* reporter, const Geo& geo,
677 std::function<void(SkPaint*, T)> setter, T a, T b, 777 std::function<void(SkPaint*, T)> setter, T a, T b,
678 bool paramAffectsStroke, 778 bool paramAffectsStroke,
679 bool paramAffectsDashAndStroke) { 779 bool paramAffectsDashAndStroke) {
680 // Set the stroke width so that we don't get hairline. However, call the set ter afterward so 780 // Set the stroke width so that we don't get hairline. However, call the set ter afterward so
681 // that it can override the stroke width. 781 // that it can override the stroke width.
682 SkPaint strokeA; 782 SkPaint strokeA;
683 strokeA.setStyle(SkPaint::kStroke_Style); 783 strokeA.setStyle(SkPaint::kStroke_Style);
684 strokeA.setStrokeWidth(2.f); 784 strokeA.setStrokeWidth(2.f);
685 setter(&strokeA, a); 785 setter(&strokeA, a);
686 SkPaint strokeB; 786 SkPaint strokeB;
687 strokeB.setStyle(SkPaint::kStroke_Style); 787 strokeB.setStyle(SkPaint::kStroke_Style);
688 strokeB.setStrokeWidth(2.f); 788 strokeB.setStrokeWidth(2.f);
689 setter(&strokeB, b); 789 setter(&strokeB, b);
690 790
691 TestCase strokeACase(geo, strokeA, reporter); 791 TestCase strokeACase(geo, strokeA, reporter);
692 TestCase strokeBCase(geo, strokeB, reporter); 792 TestCase strokeBCase(geo, strokeB, reporter);
693 if (paramAffectsStroke) { 793 if (paramAffectsStroke) {
694 // If stroking is immediately incorporated into a geometric transformati on then the base 794 // If stroking is immediately incorporated into a geometric transformati on then the base
695 // shapes will differ. 795 // shapes will differ.
696 if (stroke_is_converted_to_fill(geo)) { 796 if (geo.strokeIsConvertedToFill()) {
697 strokeACase.compare(reporter, strokeBCase, 797 strokeACase.compare(reporter, strokeBCase,
698 TestCase::kAllDifferent_ComparisonExpecation); 798 TestCase::kAllDifferent_ComparisonExpecation);
699 } else { 799 } else {
700 strokeACase.compare(reporter, strokeBCase, 800 strokeACase.compare(reporter, strokeBCase,
701 TestCase::kSameUpToStroke_ComparisonExpecation); 801 TestCase::kSameUpToStroke_ComparisonExpecation);
702 } 802 }
703 } else { 803 } else {
704 strokeACase.compare(reporter, strokeBCase, TestCase::kAllSame_Comparison Expecation); 804 strokeACase.compare(reporter, strokeBCase, TestCase::kAllSame_Comparison Expecation);
705 } 805 }
706 806
707 SkPaint strokeAndFillA = strokeA; 807 SkPaint strokeAndFillA = strokeA;
708 SkPaint strokeAndFillB = strokeB; 808 SkPaint strokeAndFillB = strokeB;
709 strokeAndFillA.setStyle(SkPaint::kStrokeAndFill_Style); 809 strokeAndFillA.setStyle(SkPaint::kStrokeAndFill_Style);
710 strokeAndFillB.setStyle(SkPaint::kStrokeAndFill_Style); 810 strokeAndFillB.setStyle(SkPaint::kStrokeAndFill_Style);
711 TestCase strokeAndFillACase(geo, strokeAndFillA, reporter); 811 TestCase strokeAndFillACase(geo, strokeAndFillA, reporter);
712 TestCase strokeAndFillBCase(geo, strokeAndFillB, reporter); 812 TestCase strokeAndFillBCase(geo, strokeAndFillB, reporter);
713 if (paramAffectsStroke) { 813 if (paramAffectsStroke) {
714 // If stroking is immediately incorporated into a geometric transformati on then the base 814 // If stroking is immediately incorporated into a geometric transformati on then the base
715 // shapes will differ. 815 // shapes will differ.
716 if (stroke_and_fill_is_converted_to_fill(geo, strokeAndFillA) || 816 if (geo.strokeAndFillIsConvertedToFill(strokeAndFillA) ||
717 stroke_and_fill_is_converted_to_fill(geo, strokeAndFillB)) { 817 geo.strokeAndFillIsConvertedToFill(strokeAndFillB)) {
718 strokeAndFillACase.compare(reporter, strokeAndFillBCase, 818 strokeAndFillACase.compare(reporter, strokeAndFillBCase,
719 TestCase::kAllDifferent_ComparisonExpecat ion); 819 TestCase::kAllDifferent_ComparisonExpecat ion);
720 } else { 820 } else {
721 strokeAndFillACase.compare(reporter, strokeAndFillBCase, 821 strokeAndFillACase.compare(reporter, strokeAndFillBCase,
722 TestCase::kSameUpToStroke_ComparisonExpec ation); 822 TestCase::kSameUpToStroke_ComparisonExpec ation);
723 } 823 }
724 } else { 824 } else {
725 strokeAndFillACase.compare(reporter, strokeAndFillBCase, 825 strokeAndFillACase.compare(reporter, strokeAndFillBCase,
726 TestCase::kAllSame_ComparisonExpecation); 826 TestCase::kAllSame_ComparisonExpecation);
727 } 827 }
(...skipping 13 matching lines...) Expand all
741 dashB.setPathEffect(make_dash()); 841 dashB.setPathEffect(make_dash());
742 TestCase dashACase(geo, dashA, reporter); 842 TestCase dashACase(geo, dashA, reporter);
743 TestCase dashBCase(geo, dashB, reporter); 843 TestCase dashBCase(geo, dashB, reporter);
744 if (paramAffectsDashAndStroke) { 844 if (paramAffectsDashAndStroke) {
745 dashACase.compare(reporter, dashBCase, TestCase::kSameUpToStroke_Compari sonExpecation); 845 dashACase.compare(reporter, dashBCase, TestCase::kSameUpToStroke_Compari sonExpecation);
746 } else { 846 } else {
747 dashACase.compare(reporter, dashBCase, TestCase::kAllSame_ComparisonExpe cation); 847 dashACase.compare(reporter, dashBCase, TestCase::kAllSame_ComparisonExpe cation);
748 } 848 }
749 } 849 }
750 850
751 template <typename GEO, typename T> 851 template <typename T>
752 static void test_stroke_param(skiatest::Reporter* reporter, const GEO& geo, 852 static void test_stroke_param(skiatest::Reporter* reporter, const Geo& geo,
753 std::function<void(SkPaint*, T)> setter, T a, T b) { 853 std::function<void(SkPaint*, T)> setter, T a, T b) {
754 test_stroke_param_impl(reporter, geo, setter, a, b, true, true); 854 test_stroke_param_impl(reporter, geo, setter, a, b, true, true);
755 }; 855 };
756 856
757 template <typename GEO> 857 static void test_stroke_cap(skiatest::Reporter* reporter, const Geo& geo) {
758 static void test_stroke_cap(skiatest::Reporter* reporter, const GEO& geo) { 858 SkPaint hairline;
759 GrShape shape(geo, GrStyle(SkStrokeRec::kHairline_InitStyle)); 859 hairline.setStrokeWidth(0);
860 hairline.setStyle(SkPaint::kStroke_Style);
861 GrShape shape = geo.makeShape(hairline);
760 // The cap should only affect shapes that may be open. 862 // The cap should only affect shapes that may be open.
761 bool affectsStroke = !shape.knownToBeClosed(); 863 bool affectsStroke = !shape.knownToBeClosed();
762 // Dashing adds ends that need caps. 864 // Dashing adds ends that need caps.
763 bool affectsDashAndStroke = true; 865 bool affectsDashAndStroke = true;
764 test_stroke_param_impl<GEO, SkPaint::Cap>( 866 test_stroke_param_impl<SkPaint::Cap>(
765 reporter, 867 reporter,
766 geo, 868 geo,
767 [](SkPaint* p, SkPaint::Cap c) { p->setStrokeCap(c);}, 869 [](SkPaint* p, SkPaint::Cap c) { p->setStrokeCap(c);},
768 SkPaint::kButt_Cap, SkPaint::kRound_Cap, 870 SkPaint::kButt_Cap, SkPaint::kRound_Cap,
769 affectsStroke, 871 affectsStroke,
770 affectsDashAndStroke); 872 affectsDashAndStroke);
771 }; 873 };
772 874
773 static bool shape_known_not_to_have_joins(const GrShape& shape) { 875 static bool shape_known_not_to_have_joins(const GrShape& shape) {
774 return shape.asLine(nullptr, nullptr) || shape.isEmpty(); 876 return shape.asLine(nullptr, nullptr) || shape.isEmpty();
775 } 877 }
776 878
777 template <typename GEO> 879 static void test_stroke_join(skiatest::Reporter* reporter, const Geo& geo) {
778 static void test_stroke_join(skiatest::Reporter* reporter, const GEO& geo) { 880 SkPaint hairline;
779 GrShape shape(geo, GrStyle(SkStrokeRec::kHairline_InitStyle)); 881 hairline.setStrokeWidth(0);
882 hairline.setStyle(SkPaint::kStroke_Style);
883 GrShape shape = geo.makeShape(hairline);
780 // GrShape recognizes certain types don't have joins and will prevent the jo in type from 884 // GrShape recognizes certain types don't have joins and will prevent the jo in type from
781 // affecting the style key. 885 // affecting the style key.
782 // Dashing doesn't add additional joins. However, GrShape currently loses tr ack of this 886 // Dashing doesn't add additional joins. However, GrShape currently loses tr ack of this
783 // after applying the dash. 887 // after applying the dash.
784 bool affectsStroke = !shape_known_not_to_have_joins(shape); 888 bool affectsStroke = !shape_known_not_to_have_joins(shape);
785 test_stroke_param_impl<GEO, SkPaint::Join>( 889 test_stroke_param_impl<SkPaint::Join>(
786 reporter, 890 reporter,
787 geo, 891 geo,
788 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);}, 892 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);},
789 SkPaint::kRound_Join, SkPaint::kBevel_Join, 893 SkPaint::kRound_Join, SkPaint::kBevel_Join,
790 affectsStroke, true); 894 affectsStroke, true);
791 }; 895 };
792 896
793 template <typename GEO> 897 static void test_miter_limit(skiatest::Reporter* reporter, const Geo& geo) {
794 static void test_miter_limit(skiatest::Reporter* reporter, const GEO& geo) {
795 auto setMiterJoinAndLimit = [](SkPaint* p, SkScalar miter) { 898 auto setMiterJoinAndLimit = [](SkPaint* p, SkScalar miter) {
796 p->setStrokeJoin(SkPaint::kMiter_Join); 899 p->setStrokeJoin(SkPaint::kMiter_Join);
797 p->setStrokeMiter(miter); 900 p->setStrokeMiter(miter);
798 }; 901 };
799 902
800 auto setOtherJoinAndLimit = [](SkPaint* p, SkScalar miter) { 903 auto setOtherJoinAndLimit = [](SkPaint* p, SkScalar miter) {
801 p->setStrokeJoin(SkPaint::kRound_Join); 904 p->setStrokeJoin(SkPaint::kRound_Join);
802 p->setStrokeMiter(miter); 905 p->setStrokeMiter(miter);
803 }; 906 };
804 907
805 GrShape shape(geo, GrStyle(SkStrokeRec::kHairline_InitStyle)); 908 SkPaint hairline;
909 hairline.setStrokeWidth(0);
910 hairline.setStyle(SkPaint::kStroke_Style);
911 GrShape shape = geo.makeShape(hairline);
806 bool mayHaveJoins = !shape_known_not_to_have_joins(shape); 912 bool mayHaveJoins = !shape_known_not_to_have_joins(shape);
807 913
808 // The miter limit should affect stroked and dashed-stroked cases when the j oin type is 914 // The miter limit should affect stroked and dashed-stroked cases when the j oin type is
809 // miter. 915 // miter.
810 test_stroke_param_impl<GEO, SkScalar>( 916 test_stroke_param_impl<SkScalar>(
811 reporter, 917 reporter,
812 geo, 918 geo,
813 setMiterJoinAndLimit, 919 setMiterJoinAndLimit,
814 0.5f, 0.75f, 920 0.5f, 0.75f,
815 mayHaveJoins, 921 mayHaveJoins,
816 true); 922 true);
817 923
818 // The miter limit should not affect stroked and dashed-stroked cases when t he join type is 924 // The miter limit should not affect stroked and dashed-stroked cases when t he join type is
819 // not miter. 925 // not miter.
820 test_stroke_param_impl<GEO, SkScalar>( 926 test_stroke_param_impl<SkScalar>(
821 reporter, 927 reporter,
822 geo, 928 geo,
823 setOtherJoinAndLimit, 929 setOtherJoinAndLimit,
824 0.5f, 0.75f, 930 0.5f, 0.75f,
825 false, 931 false,
826 false); 932 false);
827 } 933 }
828 934
829 template<typename GEO> 935 static void test_dash_fill(skiatest::Reporter* reporter, const Geo& geo) {
830 static void test_dash_fill(skiatest::Reporter* reporter, const GEO& geo) {
831 // A dash with no stroke should have no effect 936 // A dash with no stroke should have no effect
832 using DashFactoryFn = sk_sp<SkPathEffect>(*)(); 937 using DashFactoryFn = sk_sp<SkPathEffect>(*)();
833 for (DashFactoryFn md : {&make_dash, &make_null_dash}) { 938 for (DashFactoryFn md : {&make_dash, &make_null_dash}) {
834 SkPaint dashFill; 939 SkPaint dashFill;
835 dashFill.setPathEffect((*md)()); 940 dashFill.setPathEffect((*md)());
836 TestCase dashFillCase(geo, dashFill, reporter); 941 TestCase dashFillCase(geo, dashFill, reporter);
837 942
838 TestCase fillCase(geo, SkPaint(), reporter); 943 TestCase fillCase(geo, SkPaint(), reporter);
839 dashFillCase.compare(reporter, fillCase, TestCase::kAllSame_ComparisonEx pecation); 944 dashFillCase.compare(reporter, fillCase, TestCase::kAllSame_ComparisonEx pecation);
840 } 945 }
841 } 946 }
842 947
843 template<typename GEO> 948 void test_null_dash(skiatest::Reporter* reporter, const Geo& geo) {
844 void test_null_dash(skiatest::Reporter* reporter, const GEO& geo) {
845 SkPaint fill; 949 SkPaint fill;
846 SkPaint stroke; 950 SkPaint stroke;
847 stroke.setStyle(SkPaint::kStroke_Style); 951 stroke.setStyle(SkPaint::kStroke_Style);
848 stroke.setStrokeWidth(1.f); 952 stroke.setStrokeWidth(1.f);
849 SkPaint dash; 953 SkPaint dash;
850 dash.setStyle(SkPaint::kStroke_Style); 954 dash.setStyle(SkPaint::kStroke_Style);
851 dash.setStrokeWidth(1.f); 955 dash.setStrokeWidth(1.f);
852 dash.setPathEffect(make_dash()); 956 dash.setPathEffect(make_dash());
853 SkPaint nullDash; 957 SkPaint nullDash;
854 nullDash.setStyle(SkPaint::kStroke_Style); 958 nullDash.setStyle(SkPaint::kStroke_Style);
855 nullDash.setStrokeWidth(1.f); 959 nullDash.setStrokeWidth(1.f);
856 nullDash.setPathEffect(make_null_dash()); 960 nullDash.setPathEffect(make_null_dash());
857 961
858 TestCase fillCase(geo, fill, reporter); 962 TestCase fillCase(geo, fill, reporter);
859 TestCase strokeCase(geo, stroke, reporter); 963 TestCase strokeCase(geo, stroke, reporter);
860 TestCase dashCase(geo, dash, reporter); 964 TestCase dashCase(geo, dash, reporter);
861 TestCase nullDashCase(geo, nullDash, reporter); 965 TestCase nullDashCase(geo, nullDash, reporter);
862 966
863 // We expect the null dash to be ignored so nullDashCase should match stroke Case, always. 967 // We expect the null dash to be ignored so nullDashCase should match stroke Case, always.
864 nullDashCase.compare(reporter, strokeCase, TestCase::kAllSame_ComparisonExpe cation); 968 nullDashCase.compare(reporter, strokeCase, TestCase::kAllSame_ComparisonExpe cation);
865 // Check whether the fillCase or strokeCase/nullDashCase would undergo a geo metric tranformation 969 // Check whether the fillCase or strokeCase/nullDashCase would undergo a geo metric tranformation
866 // on construction in order to determine how to compare the fill and stroke. 970 // on construction in order to determine how to compare the fill and stroke.
867 if (fill_changes_geom(geo) || stroke_is_converted_to_fill(geo)) { 971 if (geo.fillChangesGeom() || geo.strokeIsConvertedToFill()) {
868 nullDashCase.compare(reporter, fillCase, TestCase::kAllDifferent_Compari sonExpecation); 972 nullDashCase.compare(reporter, fillCase, TestCase::kAllDifferent_Compari sonExpecation);
869 } else { 973 } else {
870 nullDashCase.compare(reporter, fillCase, TestCase::kSameUpToStroke_Compa risonExpecation); 974 nullDashCase.compare(reporter, fillCase, TestCase::kSameUpToStroke_Compa risonExpecation);
871 } 975 }
872 // In the null dash case we may immediately convert to a fill, but not for t he normal dash case. 976 // In the null dash case we may immediately convert to a fill, but not for t he normal dash case.
873 if (stroke_is_converted_to_fill(geo)) { 977 if (geo.strokeIsConvertedToFill()) {
874 nullDashCase.compare(reporter, dashCase, TestCase::kAllDifferent_Compari sonExpecation); 978 nullDashCase.compare(reporter, dashCase, TestCase::kAllDifferent_Compari sonExpecation);
875 } else { 979 } else {
876 nullDashCase.compare(reporter, dashCase, TestCase::kSameUpToPE_Compariso nExpecation); 980 nullDashCase.compare(reporter, dashCase, TestCase::kSameUpToPE_Compariso nExpecation);
877 } 981 }
878 } 982 }
879 983
880 template <typename GEO> 984 void test_path_effect_makes_rrect(skiatest::Reporter* reporter, const Geo& geo) {
881 void test_path_effect_makes_rrect(skiatest::Reporter* reporter, const GEO& geo) {
882 /** 985 /**
883 * This path effect takes any input path and turns it into a rrect. It passe s through stroke 986 * This path effect takes any input path and turns it into a rrect. It passe s through stroke
884 * info. 987 * info.
885 */ 988 */
886 class RRectPathEffect : SkPathEffect { 989 class RRectPathEffect : SkPathEffect {
887 public: 990 public:
888 static const SkRRect& RRect() { 991 static const SkRRect& RRect() {
889 static const SkRRect kRRect = SkRRect::MakeRectXY(SkRect::MakeWH(12, 12), 3, 5); 992 static const SkRRect kRRect = SkRRect::MakeRectXY(SkRect::MakeWH(12, 12), 3, 5);
890 return kRRect; 993 return kRRect;
891 } 994 }
(...skipping 22 matching lines...) Expand all
914 TestCase geoPECase(geo, pe, reporter); 1017 TestCase geoPECase(geo, pe, reporter);
915 1018
916 SkPaint peStroke; 1019 SkPaint peStroke;
917 peStroke.setPathEffect(RRectPathEffect::Make()); 1020 peStroke.setPathEffect(RRectPathEffect::Make());
918 peStroke.setStrokeWidth(2.f); 1021 peStroke.setStrokeWidth(2.f);
919 peStroke.setStyle(SkPaint::kStroke_Style); 1022 peStroke.setStyle(SkPaint::kStroke_Style);
920 TestCase geoPEStrokeCase(geo, peStroke, reporter); 1023 TestCase geoPEStrokeCase(geo, peStroke, reporter);
921 1024
922 // Check whether constructing the filled case would cause the base shape to have a different 1025 // Check whether constructing the filled case would cause the base shape to have a different
923 // geometry (because of a geometric transformation upon initial GrShape cons truction). 1026 // geometry (because of a geometric transformation upon initial GrShape cons truction).
924 if (fill_changes_geom(geo)) { 1027 if (geo.fillChangesGeom()) {
925 fillGeoCase.compare(reporter, geoPECase, TestCase::kAllDifferent_Compari sonExpecation); 1028 fillGeoCase.compare(reporter, geoPECase, TestCase::kAllDifferent_Compari sonExpecation);
926 fillGeoCase.compare(reporter, geoPEStrokeCase, 1029 fillGeoCase.compare(reporter, geoPEStrokeCase,
927 TestCase::kAllDifferent_ComparisonExpecation); 1030 TestCase::kAllDifferent_ComparisonExpecation);
928 } else { 1031 } else {
929 fillGeoCase.compare(reporter, geoPECase, TestCase::kSameUpToPE_Compariso nExpecation); 1032 fillGeoCase.compare(reporter, geoPECase, TestCase::kSameUpToPE_Compariso nExpecation);
930 fillGeoCase.compare(reporter, geoPEStrokeCase, TestCase::kSameUpToPE_Com parisonExpecation); 1033 fillGeoCase.compare(reporter, geoPEStrokeCase, TestCase::kSameUpToPE_Com parisonExpecation);
931 } 1034 }
932 geoPECase.compare(reporter, geoPEStrokeCase, 1035 geoPECase.compare(reporter, geoPEStrokeCase,
933 TestCase::kSameUpToStroke_ComparisonExpecation); 1036 TestCase::kSameUpToStroke_ComparisonExpecation);
934 1037
935 TestCase rrectFillCase(RRectPathEffect::RRect(), fill, reporter); 1038 TestCase rrectFillCase(reporter, RRectPathEffect::RRect(), fill);
936 SkPaint stroke = peStroke; 1039 SkPaint stroke = peStroke;
937 stroke.setPathEffect(nullptr); 1040 stroke.setPathEffect(nullptr);
938 TestCase rrectStrokeCase(RRectPathEffect::RRect(), stroke, reporter); 1041 TestCase rrectStrokeCase(reporter, RRectPathEffect::RRect(), stroke);
939 1042
940 SkRRect rrect; 1043 SkRRect rrect;
941 // Applying the path effect should make a SkRRect shape. There is no further stroking in the 1044 // Applying the path effect should make a SkRRect shape. There is no further stroking in the
942 // geoPECase, so the full style should be the same as just the PE. 1045 // geoPECase, so the full style should be the same as just the PE.
943 REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectShape().asRRect(&rrect, nullptr, nullptr, 1046 REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectShape().asRRect(&rrect, nullptr, nullptr,
944 nullptr )); 1047 nullptr ));
945 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); 1048 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect());
946 REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectKey() == rrectFillCase. baseKey()); 1049 REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectKey() == rrectFillCase. baseKey());
947 1050
948 REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleShape().asRRect(&rrect, nullptr, nullptr, 1051 REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleShape().asRRect(&rrect, nullptr, nullptr,
949 nullptr) ); 1052 nullptr) );
950 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); 1053 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect());
951 REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleKey() == rrectFillCase.b aseKey()); 1054 REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleKey() == rrectFillCase.b aseKey());
952 1055
953 // In the PE+stroke case applying the full style should be the same as just stroking the rrect. 1056 // In the PE+stroke case applying the full style should be the same as just stroking the rrect.
954 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectShape().asRRect(& rrect, nullptr, 1057 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectShape().asRRect(& rrect, nullptr,
955 n ullptr, nullptr)); 1058 n ullptr, nullptr));
956 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect()); 1059 REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect());
957 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectKey() == rrectFil lCase.baseKey()); 1060 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectKey() == rrectFil lCase.baseKey());
958 1061
959 REPORTER_ASSERT(reporter, !geoPEStrokeCase.appliedFullStyleShape().asRRect(& rrect, nullptr, 1062 REPORTER_ASSERT(reporter, !geoPEStrokeCase.appliedFullStyleShape().asRRect(& rrect, nullptr,
960 n ullptr, nullptr)); 1063 n ullptr, nullptr));
961 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleKey() == 1064 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleKey() ==
962 rrectStrokeCase.appliedFullStyleKey()); 1065 rrectStrokeCase.appliedFullStyleKey());
963 } 1066 }
964 1067
965 template <typename GEO> 1068 void test_unknown_path_effect(skiatest::Reporter* reporter, const Geo& geo) {
966 void test_unknown_path_effect(skiatest::Reporter* reporter, const GEO& geo) {
967 /** 1069 /**
968 * This path effect just adds two lineTos to the input path. 1070 * This path effect just adds two lineTos to the input path.
969 */ 1071 */
970 class AddLineTosPathEffect : SkPathEffect { 1072 class AddLineTosPathEffect : SkPathEffect {
971 public: 1073 public:
972 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, 1074 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
973 const SkRect* cullR) const override { 1075 const SkRect* cullR) const override {
974 *dst = src; 1076 *dst = src;
975 dst->lineTo(0, 0); 1077 dst->lineTo(0, 0);
976 dst->lineTo(10, 10); 1078 dst->lineTo(10, 10);
(...skipping 19 matching lines...) Expand all
996 peStroke.setStrokeWidth(2.f); 1098 peStroke.setStrokeWidth(2.f);
997 peStroke.setStyle(SkPaint::kStroke_Style); 1099 peStroke.setStyle(SkPaint::kStroke_Style);
998 TestCase geoPEStrokeCase(geo, peStroke, reporter); 1100 TestCase geoPEStrokeCase(geo, peStroke, reporter);
999 TestCase::SelfExpectations expectations; 1101 TestCase::SelfExpectations expectations;
1000 expectations.fPEHasEffect = true; 1102 expectations.fPEHasEffect = true;
1001 expectations.fPEHasValidKey = false; 1103 expectations.fPEHasValidKey = false;
1002 expectations.fStrokeApplies = true; 1104 expectations.fStrokeApplies = true;
1003 geoPEStrokeCase.testExpectations(reporter, expectations); 1105 geoPEStrokeCase.testExpectations(reporter, expectations);
1004 } 1106 }
1005 1107
1006 template <typename GEO> 1108 void test_make_hairline_path_effect(skiatest::Reporter* reporter, const Geo& geo ) {
1007 void test_make_hairline_path_effect(skiatest::Reporter* reporter, const GEO& geo , bool isNonPath) {
1008 /** 1109 /**
1009 * This path effect just changes the stroke rec to hairline. 1110 * This path effect just changes the stroke rec to hairline.
1010 */ 1111 */
1011 class MakeHairlinePathEffect : SkPathEffect { 1112 class MakeHairlinePathEffect : SkPathEffect {
1012 public: 1113 public:
1013 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* strokeRec, 1114 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* strokeRec,
1014 const SkRect* cullR) const override { 1115 const SkRect* cullR) const override {
1015 *dst = src; 1116 *dst = src;
1016 strokeRec->setHairlineStyle(); 1117 strokeRec->setHairlineStyle();
1017 return true; 1118 return true;
(...skipping 11 matching lines...) Expand all
1029 SkPaint fill; 1130 SkPaint fill;
1030 SkPaint pe; 1131 SkPaint pe;
1031 pe.setPathEffect(MakeHairlinePathEffect::Make()); 1132 pe.setPathEffect(MakeHairlinePathEffect::Make());
1032 1133
1033 TestCase peCase(geo, pe, reporter); 1134 TestCase peCase(geo, pe, reporter);
1034 1135
1035 SkPath a, b, c; 1136 SkPath a, b, c;
1036 peCase.baseShape().asPath(&a); 1137 peCase.baseShape().asPath(&a);
1037 peCase.appliedPathEffectShape().asPath(&b); 1138 peCase.appliedPathEffectShape().asPath(&b);
1038 peCase.appliedFullStyleShape().asPath(&c); 1139 peCase.appliedFullStyleShape().asPath(&c);
1039 if (isNonPath) { 1140 if (geo.isNonPath(pe)) {
1040 // RRect types can have a change in start index or direction after the P E is applied. This 1141 // RRect types can have a change in start index or direction after the P E is applied. This
1041 // is because once the PE is applied, GrShape may canonicalize the dir a nd index since it 1142 // is because once the PE is applied, GrShape may canonicalize the dir a nd index since it
1042 // is not germane to the styling any longer. 1143 // is not germane to the styling any longer.
1043 // Instead we just check that the paths would fill the same both before and after styling. 1144 // Instead we just check that the paths would fill the same both before and after styling.
1044 REPORTER_ASSERT(reporter, paths_fill_same(a, b)); 1145 REPORTER_ASSERT(reporter, paths_fill_same(a, b));
1045 REPORTER_ASSERT(reporter, paths_fill_same(a, c)); 1146 REPORTER_ASSERT(reporter, paths_fill_same(a, c));
1046 } else { 1147 } else {
1047 // The base shape cannot perform canonicalization on the path's fill typ e because of an 1148 // The base shape cannot perform canonicalization on the path's fill typ e because of an
1048 // unknown path effect. However, after the path effect is applied the re sulting hairline 1149 // unknown path effect. However, after the path effect is applied the re sulting hairline
1049 // shape will canonicalize the path fill type since hairlines (and strok ing in general) 1150 // shape will canonicalize the path fill type since hairlines (and strok ing in general)
1050 // don't distinguish between even/odd and non-zero winding. 1151 // don't distinguish between even/odd and non-zero winding.
1051 a.setFillType(b.getFillType()); 1152 a.setFillType(b.getFillType());
1052 REPORTER_ASSERT(reporter, a == b); 1153 REPORTER_ASSERT(reporter, a == b);
1053 REPORTER_ASSERT(reporter, a == c); 1154 REPORTER_ASSERT(reporter, a == c);
1054 REPORTER_ASSERT(reporter, peCase.appliedPathEffectKey().empty()); 1155 REPORTER_ASSERT(reporter, peCase.appliedPathEffectKey().empty());
1055 REPORTER_ASSERT(reporter, peCase.appliedFullStyleKey().empty()); 1156 REPORTER_ASSERT(reporter, peCase.appliedFullStyleKey().empty());
1056 } 1157 }
1057 REPORTER_ASSERT(reporter, peCase.appliedPathEffectShape().style().isSimpleHa irline()); 1158 REPORTER_ASSERT(reporter, peCase.appliedPathEffectShape().style().isSimpleHa irline());
1058 REPORTER_ASSERT(reporter, peCase.appliedFullStyleShape().style().isSimpleHai rline()); 1159 REPORTER_ASSERT(reporter, peCase.appliedFullStyleShape().style().isSimpleHai rline());
1059 } 1160 }
1060 1161
1061 /** 1162 void test_volatile_path(skiatest::Reporter* reporter, const Geo& geo) {
1062 * isNonPath indicates whether the initial shape made from the path is expected to be recognized 1163 SkPath vPath = geo.path();
1063 * as a simpler shape type (e.g. rrect)
1064 */
1065 void test_volatile_path(skiatest::Reporter* reporter, const SkPath& path,
1066 bool isNonPath) {
1067 SkPath vPath(path);
1068 vPath.setIsVolatile(true); 1164 vPath.setIsVolatile(true);
1069 1165
1070 SkPaint dashAndStroke; 1166 SkPaint dashAndStroke;
1071 dashAndStroke.setPathEffect(make_dash()); 1167 dashAndStroke.setPathEffect(make_dash());
1072 dashAndStroke.setStrokeWidth(2.f); 1168 dashAndStroke.setStrokeWidth(2.f);
1073 dashAndStroke.setStyle(SkPaint::kStroke_Style); 1169 dashAndStroke.setStyle(SkPaint::kStroke_Style);
1074 TestCase volatileCase(vPath, dashAndStroke, reporter); 1170 TestCase volatileCase(reporter, vPath, dashAndStroke);
1075 // We expect a shape made from a volatile path to have a key iff the shape i s recognized 1171 // We expect a shape made from a volatile path to have a key iff the shape i s recognized
1076 // as a specialized geometry. 1172 // as a specialized geometry.
1077 if (isNonPath) { 1173 if (geo.isNonPath(dashAndStroke)) {
1078 REPORTER_ASSERT(reporter, SkToBool(volatileCase.baseKey().count())); 1174 REPORTER_ASSERT(reporter, SkToBool(volatileCase.baseKey().count()));
1079 // In this case all the keys should be identical to the non-volatile cas e. 1175 // In this case all the keys should be identical to the non-volatile cas e.
1080 TestCase nonVolatileCase(path, dashAndStroke, reporter); 1176 TestCase nonVolatileCase(reporter, geo.path(), dashAndStroke);
1081 volatileCase.compare(reporter, nonVolatileCase, TestCase::kAllSame_Compa risonExpecation); 1177 volatileCase.compare(reporter, nonVolatileCase, TestCase::kAllSame_Compa risonExpecation);
1082 } else { 1178 } else {
1083 // None of the keys should be valid. 1179 // None of the keys should be valid.
1084 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.baseKey().count())); 1180 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.baseKey().count()));
1085 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.appliedPathEffectKey(). count())); 1181 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.appliedPathEffectKey(). count()));
1086 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.appliedFullStyleKey().c ount())); 1182 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.appliedFullStyleKey().c ount()));
1087 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.appliedPathEffectThenSt rokeKey().count())); 1183 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.appliedPathEffectThenSt rokeKey().count()));
1088 } 1184 }
1089 } 1185 }
1090 1186
1091 template <typename GEO> 1187 void test_path_effect_makes_empty_shape(skiatest::Reporter* reporter, const Geo& geo) {
1092 void test_path_effect_makes_empty_shape(skiatest::Reporter* reporter, const GEO& geo) {
1093 /** 1188 /**
1094 * This path effect returns an empty path. 1189 * This path effect returns an empty path.
1095 */ 1190 */
1096 class EmptyPathEffect : SkPathEffect { 1191 class EmptyPathEffect : SkPathEffect {
1097 public: 1192 public:
1098 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, 1193 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
1099 const SkRect* cullR) const override { 1194 const SkRect* cullR) const override {
1100 dst->reset(); 1195 dst->reset();
1101 return true; 1196 return true;
1102 } 1197 }
(...skipping 27 matching lines...) Expand all
1130 peStroke.setStrokeWidth(2.f); 1225 peStroke.setStrokeWidth(2.f);
1131 peStroke.setStyle(SkPaint::kStroke_Style); 1226 peStroke.setStyle(SkPaint::kStroke_Style);
1132 TestCase geoPEStrokeCase(geo, peStroke, reporter); 1227 TestCase geoPEStrokeCase(geo, peStroke, reporter);
1133 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleKey() == emptyKey) ; 1228 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleKey() == emptyKey) ;
1134 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectKey() == emptyKey ); 1229 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectKey() == emptyKey );
1135 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectThenStrokeKey() = = emptyKey); 1230 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectThenStrokeKey() = = emptyKey);
1136 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectShape().isEmpty() ); 1231 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectShape().isEmpty() );
1137 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleShape().isEmpty()) ; 1232 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleShape().isEmpty()) ;
1138 } 1233 }
1139 1234
1140 template <typename GEO> 1235 void test_path_effect_fails(skiatest::Reporter* reporter, const Geo& geo) {
1141 void test_path_effect_fails(skiatest::Reporter* reporter, const GEO& geo) {
1142 /** 1236 /**
1143 * This path effect always fails to apply. 1237 * This path effect always fails to apply.
1144 */ 1238 */
1145 class FailurePathEffect : SkPathEffect { 1239 class FailurePathEffect : SkPathEffect {
1146 public: 1240 public:
1147 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, 1241 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
1148 const SkRect* cullR) const override { 1242 const SkRect* cullR) const override {
1149 return false; 1243 return false;
1150 } 1244 }
1151 void computeFastBounds(SkRect* dst, const SkRect& src) const override { 1245 void computeFastBounds(SkRect* dst, const SkRect& src) const override {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 REPORTER_ASSERT(reporter, paths_fill_same(a, b)); 1290 REPORTER_ASSERT(reporter, paths_fill_same(a, b));
1197 1291
1198 strokeCase.appliedFullStyleShape().asPath(&a); 1292 strokeCase.appliedFullStyleShape().asPath(&a);
1199 peStrokeCase.appliedFullStyleShape().asPath(&b); 1293 peStrokeCase.appliedFullStyleShape().asPath(&b);
1200 REPORTER_ASSERT(reporter, paths_fill_same(a, b)); 1294 REPORTER_ASSERT(reporter, paths_fill_same(a, b));
1201 } 1295 }
1202 1296
1203 void test_empty_shape(skiatest::Reporter* reporter) { 1297 void test_empty_shape(skiatest::Reporter* reporter) {
1204 SkPath emptyPath; 1298 SkPath emptyPath;
1205 SkPaint fill; 1299 SkPaint fill;
1206 TestCase fillEmptyCase(emptyPath, fill, reporter); 1300 TestCase fillEmptyCase(reporter, emptyPath, fill);
1207 REPORTER_ASSERT(reporter, fillEmptyCase.baseShape().isEmpty()); 1301 REPORTER_ASSERT(reporter, fillEmptyCase.baseShape().isEmpty());
1208 REPORTER_ASSERT(reporter, fillEmptyCase.appliedPathEffectShape().isEmpty()); 1302 REPORTER_ASSERT(reporter, fillEmptyCase.appliedPathEffectShape().isEmpty());
1209 REPORTER_ASSERT(reporter, fillEmptyCase.appliedFullStyleShape().isEmpty()); 1303 REPORTER_ASSERT(reporter, fillEmptyCase.appliedFullStyleShape().isEmpty());
1210 1304
1211 Key emptyKey(fillEmptyCase.baseKey()); 1305 Key emptyKey(fillEmptyCase.baseKey());
1212 REPORTER_ASSERT(reporter, emptyKey.count()); 1306 REPORTER_ASSERT(reporter, emptyKey.count());
1213 TestCase::SelfExpectations expectations; 1307 TestCase::SelfExpectations expectations;
1214 expectations.fStrokeApplies = false; 1308 expectations.fStrokeApplies = false;
1215 expectations.fPEHasEffect = false; 1309 expectations.fPEHasEffect = false;
1216 // This will test whether applying style preserves emptiness 1310 // This will test whether applying style preserves emptiness
1217 fillEmptyCase.testExpectations(reporter, expectations); 1311 fillEmptyCase.testExpectations(reporter, expectations);
1218 1312
1219 // Stroking an empty path should have no effect 1313 // Stroking an empty path should have no effect
1220 SkPath emptyPath2; 1314 SkPath emptyPath2;
1221 SkPaint stroke; 1315 SkPaint stroke;
1222 stroke.setStrokeWidth(2.f); 1316 stroke.setStrokeWidth(2.f);
1223 stroke.setStyle(SkPaint::kStroke_Style); 1317 stroke.setStyle(SkPaint::kStroke_Style);
1224 TestCase strokeEmptyCase(emptyPath2, stroke, reporter); 1318 TestCase strokeEmptyCase(reporter, emptyPath2, stroke);
1225 strokeEmptyCase.compare(reporter, fillEmptyCase, TestCase::kAllSame_Comparis onExpecation); 1319 strokeEmptyCase.compare(reporter, fillEmptyCase, TestCase::kAllSame_Comparis onExpecation);
1226 1320
1227 // Dashing and stroking an empty path should have no effect 1321 // Dashing and stroking an empty path should have no effect
1228 SkPath emptyPath3; 1322 SkPath emptyPath3;
1229 SkPaint dashAndStroke; 1323 SkPaint dashAndStroke;
1230 dashAndStroke.setPathEffect(make_dash()); 1324 dashAndStroke.setPathEffect(make_dash());
1231 dashAndStroke.setStrokeWidth(2.f); 1325 dashAndStroke.setStrokeWidth(2.f);
1232 dashAndStroke.setStyle(SkPaint::kStroke_Style); 1326 dashAndStroke.setStyle(SkPaint::kStroke_Style);
1233 TestCase dashAndStrokeEmptyCase(emptyPath3, dashAndStroke, reporter); 1327 TestCase dashAndStrokeEmptyCase(reporter, emptyPath3, dashAndStroke);
1234 dashAndStrokeEmptyCase.compare(reporter, fillEmptyCase, 1328 dashAndStrokeEmptyCase.compare(reporter, fillEmptyCase,
1235 TestCase::kAllSame_ComparisonExpecation); 1329 TestCase::kAllSame_ComparisonExpecation);
1236 1330
1237 // A shape made from an empty rrect should behave the same as an empty path. 1331 // A shape made from an empty rrect should behave the same as an empty path.
1238 SkRRect emptyRRect = SkRRect::MakeRect(SkRect::MakeEmpty()); 1332 SkRRect emptyRRect = SkRRect::MakeRect(SkRect::MakeEmpty());
1239 REPORTER_ASSERT(reporter, emptyRRect.getType() == SkRRect::kEmpty_Type); 1333 REPORTER_ASSERT(reporter, emptyRRect.getType() == SkRRect::kEmpty_Type);
1240 TestCase dashAndStrokeEmptyRRectCase(emptyRRect, dashAndStroke, reporter); 1334 TestCase dashAndStrokeEmptyRRectCase(reporter, emptyRRect, dashAndStroke);
1241 dashAndStrokeEmptyRRectCase.compare(reporter, fillEmptyCase, 1335 dashAndStrokeEmptyRRectCase.compare(reporter, fillEmptyCase,
1242 TestCase::kAllSame_ComparisonExpecation) ; 1336 TestCase::kAllSame_ComparisonExpecation) ;
1243 1337
1244 // Same for a rect. 1338 // Same for a rect.
1245 SkRect emptyRect = SkRect::MakeEmpty(); 1339 SkRect emptyRect = SkRect::MakeEmpty();
1246 TestCase dashAndStrokeEmptyRectCase(emptyRect, dashAndStroke, reporter); 1340 TestCase dashAndStrokeEmptyRectCase(reporter, emptyRect, dashAndStroke);
1247 dashAndStrokeEmptyRectCase.compare(reporter, fillEmptyCase, 1341 dashAndStrokeEmptyRectCase.compare(reporter, fillEmptyCase,
1248 TestCase::kAllSame_ComparisonExpecation); 1342 TestCase::kAllSame_ComparisonExpecation);
1249 } 1343 }
1250 1344
1251 // rect and oval types have rrect start indices that collapse to the same point. Here we select the 1345 // rect and oval types have rrect start indices that collapse to the same point. Here we select the
1252 // canonical point in these cases. 1346 // canonical point in these cases.
1253 unsigned canonicalize_rrect_start(int s, const SkRRect& rrect) { 1347 unsigned canonicalize_rrect_start(int s, const SkRRect& rrect) {
1254 switch (rrect.getType()) { 1348 switch (rrect.getType()) {
1255 case SkRRect::kRect_Type: 1349 case SkRRect::kRect_Type:
1256 return (s + 1) & 0b110; 1350 return (s + 1) & 0b110;
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 SkPaint fill; 1622 SkPaint fill;
1529 SkPaint stroke; 1623 SkPaint stroke;
1530 stroke.setStyle(SkPaint::kStroke_Style); 1624 stroke.setStyle(SkPaint::kStroke_Style);
1531 stroke.setStrokeWidth(2.f); 1625 stroke.setStrokeWidth(2.f);
1532 SkPaint hairline; 1626 SkPaint hairline;
1533 hairline.setStyle(SkPaint::kStroke_Style); 1627 hairline.setStyle(SkPaint::kStroke_Style);
1534 hairline.setStrokeWidth(0.f); 1628 hairline.setStrokeWidth(0.f);
1535 SkPaint dash = stroke; 1629 SkPaint dash = stroke;
1536 dash.setPathEffect(make_dash()); 1630 dash.setPathEffect(make_dash());
1537 1631
1538 TestCase fillAB(lineAB, fill, r); 1632 TestCase fillAB(r, lineAB, fill);
1539 TestCase fillEmpty(SkPath(), fill, r); 1633 TestCase fillEmpty(r, SkPath(), fill);
1540 fillAB.compare(r, fillEmpty, TestCase::kAllSame_ComparisonExpecation); 1634 fillAB.compare(r, fillEmpty, TestCase::kAllSame_ComparisonExpecation);
1541 REPORTER_ASSERT(r, !fillAB.baseShape().asLine(nullptr, nullptr)); 1635 REPORTER_ASSERT(r, !fillAB.baseShape().asLine(nullptr, nullptr));
1542 1636
1543 TestCase strokeAB(lineAB, stroke, r); 1637 TestCase strokeAB(r, lineAB, stroke);
1544 TestCase strokeBA(lineBA, stroke, r); 1638 TestCase strokeBA(r, lineBA, stroke);
1545 TestCase strokeAC(lineAC, stroke, r); 1639 TestCase strokeAC(r, lineAC, stroke);
1546 1640
1547 TestCase hairlineAB(lineAB, hairline, r); 1641 TestCase hairlineAB(r, lineAB, hairline);
1548 TestCase hairlineBA(lineBA, hairline, r); 1642 TestCase hairlineBA(r, lineBA, hairline);
1549 TestCase hairlineAC(lineAC, hairline, r); 1643 TestCase hairlineAC(r, lineAC, hairline);
1550 1644
1551 TestCase dashAB(lineAB, dash, r); 1645 TestCase dashAB(r, lineAB, dash);
1552 TestCase dashBA(lineBA, dash, r); 1646 TestCase dashBA(r, lineBA, dash);
1553 TestCase dashAC(lineAC, dash, r); 1647 TestCase dashAC(r, lineAC, dash);
1554 1648
1555 strokeAB.compare(r, fillAB, TestCase::kAllDifferent_ComparisonExpecation); 1649 strokeAB.compare(r, fillAB, TestCase::kAllDifferent_ComparisonExpecation);
1556 1650
1557 strokeAB.compare(r, strokeBA, TestCase::kAllSame_ComparisonExpecation); 1651 strokeAB.compare(r, strokeBA, TestCase::kAllSame_ComparisonExpecation);
1558 strokeAB.compare(r, strokeAC, TestCase::kAllDifferent_ComparisonExpecation); 1652 strokeAB.compare(r, strokeAC, TestCase::kAllDifferent_ComparisonExpecation);
1559 1653
1560 hairlineAB.compare(r, hairlineBA, TestCase::kAllSame_ComparisonExpecation); 1654 hairlineAB.compare(r, hairlineBA, TestCase::kAllSame_ComparisonExpecation);
1561 hairlineAB.compare(r, hairlineAC, TestCase::kAllDifferent_ComparisonExpecati on); 1655 hairlineAB.compare(r, hairlineAC, TestCase::kAllDifferent_ComparisonExpecati on);
1562 1656
1563 dashAB.compare(r, dashBA, TestCase::kAllDifferent_ComparisonExpecation); 1657 dashAB.compare(r, dashBA, TestCase::kAllDifferent_ComparisonExpecation);
(...skipping 24 matching lines...) Expand all
1588 REPORTER_ASSERT(r, strokeAB.baseShape().asLine(pts, &inverted) && !inverted && 1682 REPORTER_ASSERT(r, strokeAB.baseShape().asLine(pts, &inverted) && !inverted &&
1589 pts[0] == canonicalPts[0] && pts[1] == canonicalPts[1]); 1683 pts[0] == canonicalPts[0] && pts[1] == canonicalPts[1]);
1590 REPORTER_ASSERT(r, hairlineAB.baseShape().asLine(pts, &inverted) && !inverte d && 1684 REPORTER_ASSERT(r, hairlineAB.baseShape().asLine(pts, &inverted) && !inverte d &&
1591 pts[0] == canonicalPts[0] && pts[1] == canonicalPts[1]); 1685 pts[0] == canonicalPts[0] && pts[1] == canonicalPts[1]);
1592 REPORTER_ASSERT(r, dashAB.baseShape().asLine(pts, &inverted) && !inverted && 1686 REPORTER_ASSERT(r, dashAB.baseShape().asLine(pts, &inverted) && !inverted &&
1593 pts[0] == kA && pts[1] == kB); 1687 pts[0] == kA && pts[1] == kB);
1594 REPORTER_ASSERT(r, dashBA.baseShape().asLine(pts, &inverted) && !inverted && 1688 REPORTER_ASSERT(r, dashBA.baseShape().asLine(pts, &inverted) && !inverted &&
1595 pts[0] == kB && pts[1] == kA); 1689 pts[0] == kB && pts[1] == kA);
1596 1690
1597 1691
1598 TestCase strokeInvAB(invLineAB, stroke, r); 1692 TestCase strokeInvAB(r, invLineAB, stroke);
1599 TestCase hairlineInvAB(invLineAB, hairline, r); 1693 TestCase hairlineInvAB(r, invLineAB, hairline);
1600 TestCase dashInvAB(invLineAB, dash, r); 1694 TestCase dashInvAB(r, invLineAB, dash);
1601 strokeInvAB.compare(r, strokeAB, TestCase::kAllDifferent_ComparisonExpecatio n); 1695 strokeInvAB.compare(r, strokeAB, TestCase::kAllDifferent_ComparisonExpecatio n);
1602 hairlineInvAB.compare(r, hairlineAB, TestCase::kAllDifferent_ComparisonExpec ation); 1696 hairlineInvAB.compare(r, hairlineAB, TestCase::kAllDifferent_ComparisonExpec ation);
1603 // Dashing ignores inverse. 1697 // Dashing ignores inverse.
1604 dashInvAB.compare(r, dashAB, TestCase::kAllSame_ComparisonExpecation); 1698 dashInvAB.compare(r, dashAB, TestCase::kAllSame_ComparisonExpecation);
1605 1699
1606 REPORTER_ASSERT(r, strokeInvAB.baseShape().asLine(pts, &inverted) && inverte d && 1700 REPORTER_ASSERT(r, strokeInvAB.baseShape().asLine(pts, &inverted) && inverte d &&
1607 pts[0] == canonicalPts[0] && pts[1] == canonicalPts[1]); 1701 pts[0] == canonicalPts[0] && pts[1] == canonicalPts[1]);
1608 REPORTER_ASSERT(r, hairlineInvAB.baseShape().asLine(pts, &inverted) && inver ted && 1702 REPORTER_ASSERT(r, hairlineInvAB.baseShape().asLine(pts, &inverted) && inver ted &&
1609 pts[0] == canonicalPts[0] && pts[1] == canonicalPts[1]); 1703 pts[0] == canonicalPts[0] && pts[1] == canonicalPts[1]);
1610 // Dashing ignores inverse. 1704 // Dashing ignores inverse.
(...skipping 15 matching lines...) Expand all
1626 SkPaint roundCap = buttCap; 1720 SkPaint roundCap = buttCap;
1627 roundCap.setStrokeCap(SkPaint::kRound_Cap); 1721 roundCap.setStrokeCap(SkPaint::kRound_Cap);
1628 1722
1629 // vertical 1723 // vertical
1630 SkPath linePath; 1724 SkPath linePath;
1631 linePath.moveTo(4, 4); 1725 linePath.moveTo(4, 4);
1632 linePath.lineTo(4, 5); 1726 linePath.lineTo(4, 5);
1633 1727
1634 SkPaint fill; 1728 SkPaint fill;
1635 1729
1636 TestCase(linePath, buttCap, r).compare(r, TestCase(SkRect::MakeLTRB(2, 4, 6, 5), fill, r), 1730 TestCase(r, linePath, buttCap).compare(r, TestCase(r, SkRect::MakeLTRB(2, 4, 6, 5), fill),
1637 TestCase::kAllSame_ComparisonExpecati on); 1731 TestCase::kAllSame_ComparisonExpecati on);
1638 1732
1639 TestCase(linePath, squareCap, r).compare(r, TestCase(SkRect::MakeLTRB(2, 2, 6, 7), fill, r), 1733 TestCase(r, linePath, squareCap).compare(r, TestCase(r, SkRect::MakeLTRB(2, 2, 6, 7), fill),
1640 TestCase::kAllSame_ComparisonExpeca tion); 1734 TestCase::kAllSame_ComparisonExpeca tion);
1641 1735
1642 TestCase(linePath, roundCap, r).compare(r, 1736 TestCase(r, linePath, roundCap).compare(r,
1643 TestCase(SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 6, 7), 2, 2), fill, r), 1737 TestCase(r, SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 6, 7), 2, 2), fil l),
1644 TestCase::kAllSame_ComparisonExpecation); 1738 TestCase::kAllSame_ComparisonExpecation);
1645 1739
1646 // horizontal 1740 // horizontal
1647 linePath.reset(); 1741 linePath.reset();
1648 linePath.moveTo(4, 4); 1742 linePath.moveTo(4, 4);
1649 linePath.lineTo(5, 4); 1743 linePath.lineTo(5, 4);
1650 1744
1651 TestCase(linePath, buttCap, r).compare(r, TestCase(SkRect::MakeLTRB(4, 2, 5, 6), fill, r), 1745 TestCase(r, linePath, buttCap).compare(r, TestCase(r, SkRect::MakeLTRB(4, 2, 5, 6), fill),
1652 TestCase::kAllSame_ComparisonExpecati on); 1746 TestCase::kAllSame_ComparisonExpecati on);
1653 TestCase(linePath, squareCap, r).compare(r, TestCase(SkRect::MakeLTRB(2, 2, 7, 6), fill, r), 1747 TestCase(r, linePath, squareCap).compare(r, TestCase(r, SkRect::MakeLTRB(2, 2, 7, 6), fill),
1654 TestCase::kAllSame_ComparisonExpeca tion); 1748 TestCase::kAllSame_ComparisonExpeca tion);
1655 TestCase(linePath, roundCap, r).compare(r, 1749 TestCase(r, linePath, roundCap).compare(r,
1656 TestCase(SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 7, 6), 2, 2), fill, r), 1750 TestCase(r, SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 7, 6), 2, 2), fi ll),
1657 TestCase::kAllSame_ComparisonExpecation); 1751 TestCase::kAllSame_ComparisonExpecation);
1658 1752
1659 // point 1753 // point
1660 linePath.reset(); 1754 linePath.reset();
1661 linePath.moveTo(4, 4); 1755 linePath.moveTo(4, 4);
1662 linePath.lineTo(4, 4); 1756 linePath.lineTo(4, 4);
1663 1757
1664 TestCase(linePath, buttCap, r).compare(r, TestCase(SkRect::MakeEmpty(), fill , r), 1758 TestCase(r, linePath, buttCap).compare(r, TestCase(r, SkRect::MakeEmpty(), f ill),
1665 TestCase::kAllSame_ComparisonExpecati on); 1759 TestCase::kAllSame_ComparisonExpecati on);
1666 TestCase(linePath, squareCap, r).compare(r, TestCase(SkRect::MakeLTRB(2, 2, 6, 6), fill, r), 1760 TestCase(r, linePath, squareCap).compare(r, TestCase(r, SkRect::MakeLTRB(2, 2, 6, 6), fill),
1667 TestCase::kAllSame_ComparisonExpeca tion); 1761 TestCase::kAllSame_ComparisonExpeca tion);
1668 TestCase(linePath, roundCap, r).compare(r, 1762 TestCase(r, linePath, roundCap).compare(r,
1669 TestCase(SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 6, 6), 2, 2), fill, r), 1763 TestCase(r, SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 6, 6), 2, 2), fil l),
1670 TestCase::kAllSame_ComparisonExpecation); 1764 TestCase::kAllSame_ComparisonExpecation);
1671 } 1765 }
1672 1766
1673 DEF_TEST(GrShape, reporter) { 1767 DEF_TEST(GrShape, reporter) {
1768 SkTArray<std::unique_ptr<Geo>> geos;
1769 SkTArray<std::unique_ptr<RRectPathGeo>> rrectPathGeos;
1770
1674 for (auto r : { SkRect::MakeWH(10, 20), 1771 for (auto r : { SkRect::MakeWH(10, 20),
1675 SkRect::MakeWH(-10, -20), 1772 SkRect::MakeWH(-10, -20),
1676 SkRect::MakeWH(-10, 20), 1773 SkRect::MakeWH(-10, 20),
1677 SkRect::MakeWH(10, -20)}) { 1774 SkRect::MakeWH(10, -20)}) {
1678 test_basic(reporter, r); 1775 geos.emplace_back(new RectGeo(r));
1679 test_scale(reporter, r); 1776 SkPath rectPath;
1680 test_dash_fill(reporter, r); 1777 rectPath.addRect(r);
1681 test_null_dash(reporter, r); 1778 geos.emplace_back(new RRectPathGeo(rectPath, r, RRectPathGeo::RRectForSt roke::kYes,
1682 // Test modifying various stroke params. 1779 PathGeo::Invert::kNo));
1683 test_stroke_param<SkRect, SkScalar>( 1780 geos.emplace_back(new RRectPathGeo(rectPath, r, RRectPathGeo::RRectForSt roke::kYes,
1684 reporter, r, 1781 PathGeo::Invert::kYes));
1685 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, 1782 rrectPathGeos.emplace_back(new RRectPathGeo(rectPath, r, RRectPathGeo::R RectForStroke::kYes,
1686 SkIntToScalar(2), SkIntToScalar(4)); 1783 PathGeo::Invert::kNo));
1687 test_stroke_join(reporter, r);
1688 test_stroke_cap(reporter, r);
1689 test_miter_limit(reporter, r);
1690 test_path_effect_makes_rrect(reporter, r);
1691 test_unknown_path_effect(reporter, r);
1692 test_path_effect_makes_empty_shape(reporter, r);
1693 test_path_effect_fails(reporter, r);
1694 test_make_hairline_path_effect(reporter, r, true);
1695 GrShape shape(r);
1696 REPORTER_ASSERT(reporter, !shape.asLine(nullptr, nullptr));
1697 } 1784 }
1698
1699 for (auto rr : { SkRRect::MakeRect(SkRect::MakeWH(10, 10)), 1785 for (auto rr : { SkRRect::MakeRect(SkRect::MakeWH(10, 10)),
1700 SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4), 1786 SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4),
1701 SkRRect::MakeOval(SkRect::MakeWH(20, 20))}) { 1787 SkRRect::MakeOval(SkRect::MakeWH(20, 20))}) {
1702 test_basic(reporter, rr); 1788 geos.emplace_back(new RRectGeo(rr));
1703 test_rrect(reporter, rr); 1789 test_rrect(reporter, rr);
1704 test_scale(reporter, rr); 1790 SkPath rectPath;
1705 test_dash_fill(reporter, rr); 1791 rectPath.addRRect(rr);
1706 test_null_dash(reporter, rr); 1792 geos.emplace_back(new RRectPathGeo(rectPath, rr, RRectPathGeo::RRectForS troke::kYes,
1707 // Test modifying various stroke params. 1793 PathGeo::Invert::kNo));
1708 test_stroke_param<SkRRect, SkScalar>( 1794 geos.emplace_back(new RRectPathGeo(rectPath, rr, RRectPathGeo::RRectForS troke::kYes,
1709 reporter, rr, 1795 PathGeo::Invert::kYes));
1710 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, 1796 rrectPathGeos.emplace_back(new RRectPathGeo(rectPath, rr,
1711 SkIntToScalar(2), SkIntToScalar(4)); 1797 RRectPathGeo::RRectForStroke ::kYes,
1712 test_stroke_join(reporter, rr); 1798 PathGeo::Invert::kNo));
1713 test_stroke_cap(reporter, rr);
1714 test_miter_limit(reporter, rr);
1715 test_path_effect_makes_rrect(reporter, rr);
1716 test_unknown_path_effect(reporter, rr);
1717 test_path_effect_makes_empty_shape(reporter, rr);
1718 test_path_effect_fails(reporter, rr);
1719 test_make_hairline_path_effect(reporter, rr, true);
1720 GrShape shape(rr);
1721 REPORTER_ASSERT(reporter, !shape.asLine(nullptr, nullptr));
1722 } 1799 }
1723 1800
1724 struct TestPath {
1725 TestPath(const SkPath& path, bool isRRectFill, bool isRRectStroke, bool isLine,
1726 const SkRRect& rrect)
1727 : fPath(path)
1728 , fIsRRectForFill(isRRectFill)
1729 , fIsRRectForStroke(isRRectStroke)
1730 , fIsLine(isLine)
1731 , fRRect(rrect) {}
1732 SkPath fPath;
1733 bool fIsRRectForFill;
1734 bool fIsRRectForStroke;
1735 bool fIsLine;
1736 SkRRect fRRect;
1737 };
1738 SkTArray<TestPath> paths;
1739
1740 SkPath circlePath;
1741 circlePath.addCircle(10, 10, 10);
1742 paths.emplace_back(circlePath, true, true, false, SkRRect::MakeOval(SkRect:: MakeWH(20,20)));
1743
1744 SkPath rectPath;
1745 rectPath.addRect(SkRect::MakeWH(10, 10));
1746 paths.emplace_back(rectPath, true, true, false, SkRRect::MakeRect(SkRect::Ma keWH(10, 10)));
1747
1748 SkPath openRectPath; 1801 SkPath openRectPath;
1749 openRectPath.moveTo(0, 0); 1802 openRectPath.moveTo(0, 0);
1750 openRectPath.lineTo(10, 0); 1803 openRectPath.lineTo(10, 0);
1751 openRectPath.lineTo(10, 10); 1804 openRectPath.lineTo(10, 10);
1752 openRectPath.lineTo(0, 10); 1805 openRectPath.lineTo(0, 10);
1753 paths.emplace_back(openRectPath, true, false, false, SkRRect::MakeRect(SkRec t::MakeWH(10, 10))); 1806 geos.emplace_back(new RRectPathGeo(openRectPath, SkRect::MakeWH(10, 10),
1807 RRectPathGeo::RRectForStroke::kNo, PathGe o::Invert::kNo));
1808 geos.emplace_back(new RRectPathGeo(openRectPath, SkRect::MakeWH(10, 10),
1809 RRectPathGeo::RRectForStroke::kNo, PathGe o::Invert::kYes));
1810 rrectPathGeos.emplace_back(new RRectPathGeo(openRectPath, SkRect::MakeWH(10, 10),
1811 RRectPathGeo::RRectForStroke::kN o,
1812 PathGeo::Invert::kNo));
1754 1813
1755 SkPath quadPath; 1814 SkPath quadPath;
1756 quadPath.quadTo(10, 10, 5, 8); 1815 quadPath.quadTo(10, 10, 5, 8);
1757 paths.emplace_back(quadPath, false, false, false, SkRRect()); 1816 geos.emplace_back(new PathGeo(quadPath, PathGeo::Invert::kNo));
1817 geos.emplace_back(new PathGeo(quadPath, PathGeo::Invert::kYes));
1758 1818
1759 SkPath linePath; 1819 SkPath linePath;
1760 linePath.lineTo(10, 10); 1820 linePath.lineTo(10, 10);
1761 paths.emplace_back(linePath, false, false, true, SkRRect()); 1821 geos.emplace_back(new PathGeo(linePath, PathGeo::Invert::kNo));
1822 geos.emplace_back(new PathGeo(linePath, PathGeo::Invert::kYes));
1762 1823
1763 // Horizontal and vertical paths become rrects when stroked. 1824 // Horizontal and vertical paths become rrects when stroked.
1764 SkPath vLinePath; 1825 SkPath vLinePath;
1765 vLinePath.lineTo(0, 10); 1826 vLinePath.lineTo(0, 10);
1766 paths.emplace_back(vLinePath, false, false, true, SkRRect()); 1827 geos.emplace_back(new PathGeo(vLinePath, PathGeo::Invert::kNo));
1828 geos.emplace_back(new PathGeo(vLinePath, PathGeo::Invert::kYes));
1767 1829
1768 SkPath hLinePath; 1830 SkPath hLinePath;
1769 hLinePath.lineTo(10, 0); 1831 hLinePath.lineTo(10, 0);
1770 paths.emplace_back(hLinePath, false, false, true, SkRRect()); 1832 geos.emplace_back(new PathGeo(hLinePath, PathGeo::Invert::kNo));
1833 geos.emplace_back(new PathGeo(hLinePath, PathGeo::Invert::kYes));
1771 1834
1772 for (auto testPath : paths) { 1835 for (int i = 0; i < geos.count(); ++i) {
1773 for (bool inverseFill : {false, true}) { 1836 test_basic(reporter, *geos[i]);
1774 if (inverseFill) { 1837 test_scale(reporter, *geos[i]);
1775 if (testPath.fPath.getFillType() == SkPath::kEvenOdd_FillType) { 1838 test_dash_fill(reporter, *geos[i]);
1776 testPath.fPath.setFillType(SkPath::kInverseEvenOdd_FillType) ; 1839 test_null_dash(reporter, *geos[i]);
1777 } else { 1840 // Test modifying various stroke params.
1778 SkASSERT(testPath.fPath.getFillType() == SkPath::kWinding_Fi llType); 1841 test_stroke_param<SkScalar>(
1779 testPath.fPath.setFillType(SkPath::kInverseWinding_FillType) ; 1842 reporter, *geos[i],
1780 }
1781 }
1782 const SkPath& path = testPath.fPath;
1783 test_basic(reporter, path);
1784 test_null_dash(reporter, path);
1785 test_path_effect_makes_rrect(reporter, path);
1786 test_scale(reporter, path);
1787 // This test uses a stroking paint, hence use of fIsRRectForStroke
1788 test_volatile_path(reporter, path, testPath.fIsRRectForStroke || tes tPath.fIsLine);
1789 test_dash_fill(reporter, path);
1790 // Test modifying various stroke params.
1791 test_stroke_param<SkPath, SkScalar>(
1792 reporter, path,
1793 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, 1843 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);},
1794 SkIntToScalar(2), SkIntToScalar(4)); 1844 SkIntToScalar(2), SkIntToScalar(4));
1795 test_stroke_join(reporter, path); 1845 test_stroke_join(reporter, *geos[i]);
1796 test_stroke_cap(reporter, path); 1846 test_stroke_cap(reporter, *geos[i]);
1797 test_miter_limit(reporter, path); 1847 test_miter_limit(reporter, *geos[i]);
1798 test_unknown_path_effect(reporter, path); 1848 test_path_effect_makes_rrect(reporter, *geos[i]);
1799 test_path_effect_makes_empty_shape(reporter, path); 1849 test_unknown_path_effect(reporter, *geos[i]);
1800 test_path_effect_fails(reporter, path); 1850 test_path_effect_makes_empty_shape(reporter, *geos[i]);
1801 test_make_hairline_path_effect(reporter, path, testPath.fIsRRectForS troke || 1851 test_path_effect_fails(reporter, *geos[i]);
1802 testPath.fIsLine); 1852 test_make_hairline_path_effect(reporter, *geos[i]);
1803 } 1853 test_volatile_path(reporter, *geos[i]);
1804 } 1854 }
1805 1855
1806 for (auto testPath : paths) { 1856 for (int i = 0; i < rrectPathGeos.count(); ++i) {
1807 const SkPath& path = testPath.fPath; 1857 const RRectPathGeo& rrgeo = *rrectPathGeos[i];
1808
1809 SkPaint fillPaint; 1858 SkPaint fillPaint;
1810 TestCase fillPathCase(path, fillPaint, reporter); 1859 TestCase fillPathCase(reporter, rrgeo.path(), fillPaint);
1811 SkRRect rrect; 1860 SkRRect rrect;
1812 REPORTER_ASSERT(reporter, testPath.fIsRRectForFill == 1861 REPORTER_ASSERT(reporter, rrgeo.isNonPath(fillPaint) ==
1813 fillPathCase.baseShape().asRRect(&rrect, nullp tr, nullptr, 1862 fillPathCase.baseShape().asRRect(&rrect, nullp tr, nullptr,
1814 nullptr)); 1863 nullptr));
1815 if (testPath.fIsRRectForFill) { 1864 if (rrgeo.isNonPath(fillPaint)) {
1816 TestCase fillPathCase2(testPath.fPath, fillPaint, reporter); 1865 TestCase fillPathCase2(reporter, rrgeo.path(), fillPaint);
1817 REPORTER_ASSERT(reporter, rrect == testPath.fRRect); 1866 REPORTER_ASSERT(reporter, rrect == rrgeo.rrect());
1818 TestCase fillRRectCase(rrect, fillPaint, reporter); 1867 TestCase fillRRectCase(reporter, rrect, fillPaint);
1819 fillPathCase2.compare(reporter, fillRRectCase, 1868 fillPathCase2.compare(reporter, fillRRectCase,
1820 TestCase::kAllSame_ComparisonExpecation); 1869 TestCase::kAllSame_ComparisonExpecation);
1821 } 1870 }
1822 SkPaint strokePaint; 1871 SkPaint strokePaint;
1823 strokePaint.setStrokeWidth(3.f); 1872 strokePaint.setStrokeWidth(3.f);
1824 strokePaint.setStyle(SkPaint::kStroke_Style); 1873 strokePaint.setStyle(SkPaint::kStroke_Style);
1825 TestCase strokePathCase(path, strokePaint, reporter); 1874 TestCase strokePathCase(reporter, rrgeo.path(), strokePaint);
1826 if (testPath.fIsRRectForStroke) { 1875 if (rrgeo.isNonPath(strokePaint)) {
1827 REPORTER_ASSERT(reporter, strokePathCase.baseShape().asRRect(&rrect, nullptr, nullptr, 1876 REPORTER_ASSERT(reporter, strokePathCase.baseShape().asRRect(&rrect, nullptr, nullptr,
1828 nullptr )); 1877 nullptr ));
1829 } 1878 REPORTER_ASSERT(reporter, rrect == rrgeo.rrect());
1830 1879 TestCase strokeRRectCase(reporter, rrect, strokePaint);
1831 if (testPath.fIsRRectForStroke) {
1832 REPORTER_ASSERT(reporter, rrect == testPath.fRRect);
1833 TestCase strokeRRectCase(rrect, strokePaint, reporter);
1834 strokePathCase.compare(reporter, strokeRRectCase, 1880 strokePathCase.compare(reporter, strokeRRectCase,
1835 TestCase::kAllSame_ComparisonExpecation); 1881 TestCase::kAllSame_ComparisonExpecation);
1836 } 1882 }
1837 } 1883 }
1838 1884
1839 // Test a volatile empty path. 1885 // Test a volatile empty path.
1840 test_volatile_path(reporter, SkPath(), true); 1886 test_volatile_path(reporter, PathGeo(SkPath(), PathGeo::Invert::kNo));
1841 1887
1842 test_empty_shape(reporter); 1888 test_empty_shape(reporter);
1843 1889
1844 test_lines(reporter); 1890 test_lines(reporter);
1845 1891
1846 test_stroked_lines(reporter); 1892 test_stroked_lines(reporter);
1847 } 1893 }
1848 1894
1849 #endif 1895 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698