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

Side by Side Diff: tests/GrShapeTest.cpp

Issue 2151313002: In GrShape detect that stroked axis-aligned lines are rrects. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Add accidentally delete semicolon back Created 4 years, 5 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 | « tests/DFPathRendererTest.cpp ('k') | 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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 const Key& baseKey() const { return fBaseKey; } 112 const Key& baseKey() const { return fBaseKey; }
113 const Key& appliedPathEffectKey() const { return fAppliedPEKey; } 113 const Key& appliedPathEffectKey() const { return fAppliedPEKey; }
114 const Key& appliedFullStyleKey() const { return fAppliedFullKey; } 114 const Key& appliedFullStyleKey() const { return fAppliedFullKey; }
115 const Key& appliedPathEffectThenStrokeKey() const { return fAppliedPEThenStr okeKey; } 115 const Key& appliedPathEffectThenStrokeKey() const { return fAppliedPEThenStr okeKey; }
116 116
117 private: 117 private:
118 static void CheckBounds(skiatest::Reporter* r, const GrShape& shape, const S kRect& bounds) { 118 static void CheckBounds(skiatest::Reporter* r, const GrShape& shape, const S kRect& bounds) {
119 SkPath path; 119 SkPath path;
120 shape.asPath(&path); 120 shape.asPath(&path);
121 // If the bounds are empty, the path ought to be as well. 121 // If the bounds are empty, the path ought to be as well.
122 if (bounds.isEmpty()) { 122 if (bounds.fLeft > bounds.fRight || bounds.fTop > bounds.fBottom) {
123 REPORTER_ASSERT(r, path.isEmpty()); 123 REPORTER_ASSERT(r, path.isEmpty());
124 return; 124 return;
125 } 125 }
126 if (path.isEmpty()) { 126 if (path.isEmpty()) {
127 return; 127 return;
128 } 128 }
129 // The bounds API explicitly calls out that it does not consider inverse ness. 129 // The bounds API explicitly calls out that it does not consider inverse ness.
130 SkPath p = path; 130 SkPath p = path;
131 p.setFillType(SkPath::ConvertToNonInverseFillType(path.getFillType())); 131 p.setFillType(SkPath::ConvertToNonInverseFillType(path.getFillType()));
132 REPORTER_ASSERT(r, test_bounds_by_rasterizing(p, bounds)); 132 REPORTER_ASSERT(r, test_bounds_by_rasterizing(p, bounds));
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 hairline.setStyle(SkPaint::kStroke_Style); 506 hairline.setStyle(SkPaint::kStroke_Style);
507 hairline.setStrokeWidth(0.f); 507 hairline.setStrokeWidth(0.f);
508 TestCase hairlineCase(geo, hairline, reporter); 508 TestCase hairlineCase(geo, hairline, reporter);
509 // Since hairline style doesn't change the SkPath data, it is keyed identica lly to fill. 509 // Since hairline style doesn't change the SkPath data, it is keyed identica lly to fill.
510 hairlineCase.compare(reporter, fillCase, TestCase::kAllSame_ComparisonExpeca tion); 510 hairlineCase.compare(reporter, fillCase, TestCase::kAllSame_ComparisonExpeca tion);
511 REPORTER_ASSERT(reporter, hairlineCase.baseShape().style().isSimpleHairline( )); 511 REPORTER_ASSERT(reporter, hairlineCase.baseShape().style().isSimpleHairline( ));
512 REPORTER_ASSERT(reporter, hairlineCase.appliedFullStyleShape().style().isSim pleHairline()); 512 REPORTER_ASSERT(reporter, hairlineCase.appliedFullStyleShape().style().isSim pleHairline());
513 REPORTER_ASSERT(reporter, hairlineCase.appliedPathEffectShape().style().isSi mpleHairline()); 513 REPORTER_ASSERT(reporter, hairlineCase.appliedPathEffectShape().style().isSi mpleHairline());
514 } 514 }
515 515
516 // Was the shape pre-style geometry stored as something other than a general pat h. This somewhat
517 // relies on knowing the internals of GrShape to know that this combination of t ests is sufficient.
518 static bool is_non_path(const GrShape& shape) {
519 return shape.asRRect(nullptr, nullptr, nullptr, nullptr) || shape.asLine(nul lptr, nullptr) ||
520 shape.isEmpty();
521 }
522
516 template<typename GEO> 523 template<typename GEO>
517 static void test_scale(skiatest::Reporter* reporter, const GEO& geo) { 524 static void test_scale(skiatest::Reporter* reporter, const GEO& geo) {
518 sk_sp<SkPathEffect> dashPE = make_dash(); 525 sk_sp<SkPathEffect> dashPE = make_dash();
519 526
520 static const SkScalar kS1 = 1.f; 527 static const SkScalar kS1 = 1.f;
521 static const SkScalar kS2 = 2.f; 528 static const SkScalar kS2 = 2.f;
522 529
530 // Scale may affect the key for stroked results. However, there are two ways in which that may
531 // not occur. The base shape may instantly recognized that the geo + stroke is equivalent to
532 // a simple filled geometry. An example is a stroked line may become a fille d rrect.
533 // Alternatively, after applying the style the output path may be recognized as a simpler shape
534 // causing the shape with style applied to have a purely geometric key rathe r than a key derived
535 // from the base geometry and the style params (and scale factor).
536 auto wasSimplified = [](const TestCase& c) {
537 return !c.baseShape().style().applies() || is_non_path(c.appliedFullStyl eShape());
538 };
523 SkPaint fill; 539 SkPaint fill;
524 TestCase fillCase1(geo, fill, reporter, kS1); 540 TestCase fillCase1(geo, fill, reporter, kS1);
525 TestCase fillCase2(geo, fill, reporter, kS2); 541 TestCase fillCase2(geo, fill, reporter, kS2);
526 // Scale doesn't affect fills. 542 // Scale doesn't affect fills.
527 fillCase1.compare(reporter, fillCase2, TestCase::kAllSame_ComparisonExpecati on); 543 fillCase1.compare(reporter, fillCase2, TestCase::kAllSame_ComparisonExpecati on);
528 544
529 SkPaint hairline; 545 SkPaint hairline;
530 hairline.setStyle(SkPaint::kStroke_Style); 546 hairline.setStyle(SkPaint::kStroke_Style);
531 hairline.setStrokeWidth(0.f); 547 hairline.setStrokeWidth(0.f);
532 TestCase hairlineCase1(geo, hairline, reporter, kS1); 548 TestCase hairlineCase1(geo, hairline, reporter, kS1);
533 TestCase hairlineCase2(geo, hairline, reporter, kS2); 549 TestCase hairlineCase2(geo, hairline, reporter, kS2);
534 // Scale doesn't affect hairlines. 550 // Scale doesn't affect hairlines.
535 hairlineCase1.compare(reporter, hairlineCase2, TestCase::kAllSame_Comparison Expecation); 551 hairlineCase1.compare(reporter, hairlineCase2, TestCase::kAllSame_Comparison Expecation);
536 552
537 SkPaint stroke; 553 SkPaint stroke;
538 stroke.setStyle(SkPaint::kStroke_Style); 554 stroke.setStyle(SkPaint::kStroke_Style);
539 stroke.setStrokeWidth(2.f); 555 stroke.setStrokeWidth(2.f);
540 TestCase strokeCase1(geo, stroke, reporter, kS1); 556 TestCase strokeCase1(geo, stroke, reporter, kS1);
541 TestCase strokeCase2(geo, stroke, reporter, kS2); 557 TestCase strokeCase2(geo, stroke, reporter, kS2);
542 // Scale affects the stroke. 558 // Scale affects the stroke
543 strokeCase1.compare(reporter, strokeCase2, TestCase::kSameUpToStroke_Compari sonExpecation); 559 if (wasSimplified(strokeCase1)) {
560 REPORTER_ASSERT(reporter, wasSimplified(strokeCase2));
561 strokeCase1.compare(reporter, strokeCase2, TestCase::kAllSame_Comparison Expecation);
562 } else {
563 strokeCase1.compare(reporter, strokeCase2, TestCase::kSameUpToStroke_Com parisonExpecation);
564 }
544 565
545 SkPaint strokeDash = stroke; 566 SkPaint strokeDash = stroke;
546 strokeDash.setPathEffect(make_dash()); 567 strokeDash.setPathEffect(make_dash());
547 TestCase strokeDashCase1(geo, strokeDash, reporter, kS1); 568 TestCase strokeDashCase1(geo, strokeDash, reporter, kS1);
548 TestCase strokeDashCase2(geo, strokeDash, reporter, kS2); 569 TestCase strokeDashCase2(geo, strokeDash, reporter, kS2);
549 // Scale affects the dash and the stroke. 570 // Scale affects the dash and the stroke.
550 strokeDashCase1.compare(reporter, strokeDashCase2, TestCase::kSameUpToPE_Co mparisonExpecation); 571 if (wasSimplified(strokeDashCase1)) {
572 REPORTER_ASSERT(reporter, wasSimplified(strokeDashCase2));
573 strokeDashCase1.compare(reporter, strokeDashCase2,
574 TestCase::kAllSame_ComparisonExpecation);
575 } else {
576 strokeDashCase1.compare(reporter, strokeDashCase2,
577 TestCase::kSameUpToPE_ComparisonExpecation);
578 }
551 579
552 // Stroke and fill cases 580 // Stroke and fill cases
553 SkPaint strokeAndFill = stroke; 581 SkPaint strokeAndFill = stroke;
554 strokeAndFill.setStyle(SkPaint::kStrokeAndFill_Style); 582 strokeAndFill.setStyle(SkPaint::kStrokeAndFill_Style);
555 TestCase strokeAndFillCase1(geo, strokeAndFill, reporter, kS1); 583 TestCase strokeAndFillCase1(geo, strokeAndFill, reporter, kS1);
556 TestCase strokeAndFillCase2(geo, strokeAndFill, reporter, kS2); 584 TestCase strokeAndFillCase2(geo, strokeAndFill, reporter, kS2);
557 SkPaint strokeAndFillDash = strokeDash; 585 SkPaint strokeAndFillDash = strokeDash;
558 strokeAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style); 586 strokeAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style);
559 // Dash is ignored for stroke and fill 587 // Dash is ignored for stroke and fill
560 TestCase strokeAndFillDashCase1(geo, strokeAndFillDash, reporter, kS1); 588 TestCase strokeAndFillDashCase1(geo, strokeAndFillDash, reporter, kS1);
561 TestCase strokeAndFillDashCase2(geo, strokeAndFillDash, reporter, kS2); 589 TestCase strokeAndFillDashCase2(geo, strokeAndFillDash, reporter, kS2);
562 // Scale affects the stroke. Though, this can wind up creating a rect when t he input is a rect. 590 // Scale affects the stroke. Scale affects the stroke, but check to make sur e this didn't
563 // In that case we wind up with a pure geometry key and the geometries are t he same. 591 // become a simpler shape (e.g. stroke-and-filled rect can become a rect), i n which case the
564 SkRRect rrect; 592 // scale shouldn't matter and the geometries should agree.
565 if (strokeAndFillCase1.appliedFullStyleShape().asRRect(&rrect, nullptr, null ptr, nullptr)) { 593 if (wasSimplified(strokeAndFillCase1)) {
566 // We currently only expect to get here in the rect->rect case. 594 REPORTER_ASSERT(reporter, wasSimplified(strokeAndFillCase1));
567 REPORTER_ASSERT(reporter, rrect.isRect()); 595 REPORTER_ASSERT(reporter, wasSimplified(strokeAndFillDashCase1));
568 REPORTER_ASSERT(reporter, 596 REPORTER_ASSERT(reporter, wasSimplified(strokeAndFillDashCase2));
569 strokeAndFillCase1.baseShape().asRRect(&rrect, nullptr, nullptr, nullptr) &&
570 rrect.isRect());
571 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, 597 strokeAndFillCase1.compare(reporter, strokeAndFillCase2,
572 TestCase::kAllSame_ComparisonExpecation); 598 TestCase::kAllSame_ComparisonExpecation);
599 strokeAndFillDashCase1.compare(reporter, strokeAndFillDashCase2,
600 TestCase::kAllSame_ComparisonExpecation);
573 } else { 601 } else {
574 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, 602 strokeAndFillCase1.compare(reporter, strokeAndFillCase2,
575 TestCase::kSameUpToStroke_ComparisonExpecatio n); 603 TestCase::kSameUpToStroke_ComparisonExpecatio n);
576 strokeAndFillDashCase1.compare(reporter, strokeAndFillDashCase2,
577 TestCase::kSameUpToStroke_ComparisonExpec ation);
578 } 604 }
579 strokeAndFillDashCase1.compare(reporter, strokeAndFillCase1, 605 strokeAndFillDashCase1.compare(reporter, strokeAndFillCase1,
580 TestCase::kAllSame_ComparisonExpecation); 606 TestCase::kAllSame_ComparisonExpecation);
581 strokeAndFillDashCase2.compare(reporter, strokeAndFillCase2, 607 strokeAndFillDashCase2.compare(reporter, strokeAndFillCase2,
582 TestCase::kAllSame_ComparisonExpecation); 608 TestCase::kAllSame_ComparisonExpecation);
583 } 609 }
584 610
585 template <typename GEO, typename T> 611 template <typename GEO, typename T>
586 static void test_stroke_param_impl(skiatest::Reporter* reporter, const GEO& geo, 612 static void test_stroke_param_impl(skiatest::Reporter* reporter, const GEO& geo,
587 std::function<void(SkPaint*, T)> setter, T a, T b, 613 std::function<void(SkPaint*, T)> setter, T a, T b,
588 bool paramAffectsStroke, 614 bool paramAffectsStroke,
589 bool paramAffectsDashAndStroke) { 615 bool paramAffectsDashAndStroke) {
590 // Set the stroke width so that we don't get hairline. However, call the set ter afterward so 616 // Set the stroke width so that we don't get hairline. However, call the set ter afterward so
591 // that it can override the stroke width. 617 // that it can override the stroke width.
592 SkPaint strokeA; 618 SkPaint strokeA;
593 strokeA.setStyle(SkPaint::kStroke_Style); 619 strokeA.setStyle(SkPaint::kStroke_Style);
594 strokeA.setStrokeWidth(2.f); 620 strokeA.setStrokeWidth(2.f);
595 setter(&strokeA, a); 621 setter(&strokeA, a);
596 SkPaint strokeB; 622 SkPaint strokeB;
597 strokeB.setStyle(SkPaint::kStroke_Style); 623 strokeB.setStyle(SkPaint::kStroke_Style);
598 strokeB.setStrokeWidth(2.f); 624 strokeB.setStrokeWidth(2.f);
599 setter(&strokeB, b); 625 setter(&strokeB, b);
600 626
601 TestCase strokeACase(geo, strokeA, reporter); 627 TestCase strokeACase(geo, strokeA, reporter);
602 TestCase strokeBCase(geo, strokeB, reporter); 628 TestCase strokeBCase(geo, strokeB, reporter);
603 if (paramAffectsStroke) { 629 if (paramAffectsStroke) {
604 strokeACase.compare(reporter, strokeBCase, TestCase::kSameUpToStroke_Com parisonExpecation); 630 // If stroking is immediately incorporated into a geometric transformati on then the base
631 // shapes will differ.
632 if (strokeACase.baseShape().style().applies()) {
633 strokeACase.compare(reporter, strokeBCase,
634 TestCase::kSameUpToStroke_ComparisonExpecation);
635 } else {
636 strokeACase.compare(reporter, strokeBCase,
637 TestCase::kAllDifferent_ComparisonExpecation);
638 }
605 } else { 639 } else {
606 strokeACase.compare(reporter, strokeBCase, TestCase::kAllSame_Comparison Expecation); 640 strokeACase.compare(reporter, strokeBCase, TestCase::kAllSame_Comparison Expecation);
607 } 641 }
608 642
609 SkPaint strokeAndFillA = strokeA; 643 SkPaint strokeAndFillA = strokeA;
610 SkPaint strokeAndFillB = strokeB; 644 SkPaint strokeAndFillB = strokeB;
611 strokeAndFillA.setStyle(SkPaint::kStrokeAndFill_Style); 645 strokeAndFillA.setStyle(SkPaint::kStrokeAndFill_Style);
612 strokeAndFillB.setStyle(SkPaint::kStrokeAndFill_Style); 646 strokeAndFillB.setStyle(SkPaint::kStrokeAndFill_Style);
613 TestCase strokeAndFillACase(geo, strokeAndFillA, reporter); 647 TestCase strokeAndFillACase(geo, strokeAndFillA, reporter);
614 TestCase strokeAndFillBCase(geo, strokeAndFillB, reporter); 648 TestCase strokeAndFillBCase(geo, strokeAndFillB, reporter);
615 if (paramAffectsStroke) { 649 if (paramAffectsStroke) {
616 strokeAndFillACase.compare(reporter, strokeAndFillBCase, 650 // If stroking is immediately incorporated into a geometric transformati on then the base
617 TestCase::kSameUpToStroke_ComparisonExpecatio n); 651 // shapes will differ.
652 if (strokeAndFillACase.baseShape().style().applies()) {
653 strokeAndFillACase.compare(reporter, strokeAndFillBCase,
654 TestCase::kSameUpToStroke_ComparisonExpecation);
655 } else {
656 strokeAndFillACase.compare(reporter, strokeAndFillBCase,
657 TestCase::kAllDifferent_ComparisonExpecation);
658 }
618 } else { 659 } else {
619 strokeAndFillACase.compare(reporter, strokeAndFillBCase, 660 strokeAndFillACase.compare(reporter, strokeAndFillBCase,
620 TestCase::kAllSame_ComparisonExpecation); 661 TestCase::kAllSame_ComparisonExpecation);
621 } 662 }
622 663
623 // Make sure stroking params don't affect fill style. 664 // Make sure stroking params don't affect fill style.
624 SkPaint fillA = strokeA, fillB = strokeB; 665 SkPaint fillA = strokeA, fillB = strokeB;
625 fillA.setStyle(SkPaint::kFill_Style); 666 fillA.setStyle(SkPaint::kFill_Style);
626 fillB.setStyle(SkPaint::kFill_Style); 667 fillB.setStyle(SkPaint::kFill_Style);
627 TestCase fillACase(geo, fillA, reporter); 668 TestCase fillACase(geo, fillA, reporter);
628 TestCase fillBCase(geo, fillB, reporter); 669 TestCase fillBCase(geo, fillB, reporter);
629 fillACase.compare(reporter, fillBCase, TestCase::kAllSame_ComparisonExpecati on); 670 fillACase.compare(reporter, fillBCase, TestCase::kAllSame_ComparisonExpecati on);
630 671
631 // Make sure just applying the dash but not stroke gives the same key for bo th stroking 672 // Make sure just applying the dash but not stroke gives the same key for bo th stroking
632 // variations. 673 // variations.
633 SkPaint dashA = strokeA, dashB = strokeB; 674 SkPaint dashA = strokeA, dashB = strokeB;
634 dashA.setPathEffect(make_dash()); 675 dashA.setPathEffect(make_dash());
635 dashB.setPathEffect(make_dash()); 676 dashB.setPathEffect(make_dash());
636 TestCase dashACase(geo, dashA, reporter); 677 TestCase dashACase(geo, dashA, reporter);
637 TestCase dashBCase(geo, dashB, reporter); 678 TestCase dashBCase(geo, dashB, reporter);
638 if (paramAffectsDashAndStroke) { 679 if (paramAffectsDashAndStroke) {
639 dashACase.compare(reporter, dashBCase, TestCase::kSameUpToStroke_Compari sonExpecation); 680 // If stroking is immediately incorporated into a geometric transformati on then the base
681 // shapes will differ.
682 if (dashACase.baseShape().style().applies()) {
683 dashACase.compare(reporter, dashBCase, TestCase::kSameUpToStroke_Com parisonExpecation);
684 } else {
685 dashACase.compare(reporter, dashBCase, TestCase::kAllDifferent_Compa risonExpecation);
686 }
640 } else { 687 } else {
641 dashACase.compare(reporter, dashBCase, TestCase::kAllSame_ComparisonExpe cation); 688 dashACase.compare(reporter, dashBCase, TestCase::kAllSame_ComparisonExpe cation);
642 } 689 }
643 } 690 }
644 691
645 template <typename GEO, typename T> 692 template <typename GEO, typename T>
646 static void test_stroke_param(skiatest::Reporter* reporter, const GEO& geo, 693 static void test_stroke_param(skiatest::Reporter* reporter, const GEO& geo,
647 std::function<void(SkPaint*, T)> setter, T a, T b) { 694 std::function<void(SkPaint*, T)> setter, T a, T b) {
648 test_stroke_param_impl(reporter, geo, setter, a, b, true, true); 695 test_stroke_param_impl(reporter, geo, setter, a, b, true, true);
649 }; 696 };
650 697
651 template <typename GEO> 698 template <typename GEO>
652 static void test_stroke_cap(skiatest::Reporter* reporter, const GEO& geo) { 699 static void test_stroke_cap(skiatest::Reporter* reporter, const GEO& geo) {
653 GrShape shape(geo, GrStyle(SkStrokeRec::kHairline_InitStyle)); 700 GrShape shape(geo, GrStyle(SkStrokeRec::kHairline_InitStyle));
654 // The cap should only affect shapes that may be open. 701 // The cap should only affect shapes that may be open.
655 bool affectsStroke = !shape.knownToBeClosed(); 702 bool affectsStroke = !shape.knownToBeClosed();
656 // Dashing adds ends that need caps. 703 // Dashing adds ends that need caps.
657 bool affectsDashAndStroke = true; 704 bool affectsDashAndStroke = true;
658 test_stroke_param_impl<GEO, SkPaint::Cap>( 705 test_stroke_param_impl<GEO, SkPaint::Cap>(
659 reporter, 706 reporter,
660 geo, 707 geo,
661 [](SkPaint* p, SkPaint::Cap c) { p->setStrokeCap(c);}, 708 [](SkPaint* p, SkPaint::Cap c) { p->setStrokeCap(c);},
662 SkPaint::kButt_Cap, SkPaint::kRound_Cap, 709 SkPaint::kButt_Cap, SkPaint::kRound_Cap,
663 affectsStroke, 710 affectsStroke,
664 affectsDashAndStroke); 711 affectsDashAndStroke);
665 }; 712 };
666 713
714 static bool shape_known_not_to_have_joins(const GrShape& shape) {
715 return shape.asLine(nullptr, nullptr) || shape.isEmpty();
716 }
717
718 template <typename GEO>
719 static void test_stroke_join(skiatest::Reporter* reporter, const GEO& geo) {
720 GrShape shape(geo, GrStyle(SkStrokeRec::kHairline_InitStyle));
721 // GrShape recognizes certain types don't have joins and will prevent the jo in type from
722 // affecting the style key.
723 // Dashing doesn't add additional joins. However, GrShape currently loses tr ack of this
724 // after applying the dash.
725 bool affectsStroke = !shape_known_not_to_have_joins(shape);
726 test_stroke_param_impl<GEO, SkPaint::Join>(
727 reporter,
728 geo,
729 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);},
730 SkPaint::kRound_Join, SkPaint::kBevel_Join,
731 affectsStroke, true);
732 };
733
667 template <typename GEO> 734 template <typename GEO>
668 static void test_miter_limit(skiatest::Reporter* reporter, const GEO& geo) { 735 static void test_miter_limit(skiatest::Reporter* reporter, const GEO& geo) {
669 auto setMiterJoinAndLimit = [](SkPaint* p, SkScalar miter) { 736 auto setMiterJoinAndLimit = [](SkPaint* p, SkScalar miter) {
670 p->setStrokeJoin(SkPaint::kMiter_Join); 737 p->setStrokeJoin(SkPaint::kMiter_Join);
671 p->setStrokeMiter(miter); 738 p->setStrokeMiter(miter);
672 }; 739 };
673 740
674 auto setOtherJoinAndLimit = [](SkPaint* p, SkScalar miter) { 741 auto setOtherJoinAndLimit = [](SkPaint* p, SkScalar miter) {
675 p->setStrokeJoin(SkPaint::kRound_Join); 742 p->setStrokeJoin(SkPaint::kRound_Join);
676 p->setStrokeMiter(miter); 743 p->setStrokeMiter(miter);
677 }; 744 };
678 745
746 GrShape shape(geo, GrStyle(SkStrokeRec::kHairline_InitStyle));
747 bool mayHaveJoins = !shape_known_not_to_have_joins(shape);
748
679 // The miter limit should affect stroked and dashed-stroked cases when the j oin type is 749 // The miter limit should affect stroked and dashed-stroked cases when the j oin type is
680 // miter. 750 // miter.
681 test_stroke_param_impl<GEO, SkScalar>( 751 test_stroke_param_impl<GEO, SkScalar>(
682 reporter, 752 reporter,
683 geo, 753 geo,
684 setMiterJoinAndLimit, 754 setMiterJoinAndLimit,
685 0.5f, 0.75f, 755 0.5f, 0.75f,
686 true, 756 mayHaveJoins,
687 true); 757 true);
688 758
689 // The miter limit should not affect stroked and dashed-stroked cases when t he join type is 759 // The miter limit should not affect stroked and dashed-stroked cases when t he join type is
690 // not miter. 760 // not miter.
691 test_stroke_param_impl<GEO, SkScalar>( 761 test_stroke_param_impl<GEO, SkScalar>(
692 reporter, 762 reporter,
693 geo, 763 geo,
694 setOtherJoinAndLimit, 764 setOtherJoinAndLimit,
695 0.5f, 0.75f, 765 0.5f, 0.75f,
696 false, 766 false,
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleKey() == emptyKey) ; 1054 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleKey() == emptyKey) ;
985 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectKey() == emptyKey ); 1055 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectKey() == emptyKey );
986 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectThenStrokeKey() = = emptyKey); 1056 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectThenStrokeKey() = = emptyKey);
987 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectShape().isEmpty() ); 1057 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectShape().isEmpty() );
988 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleShape().isEmpty()) ; 1058 REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleShape().isEmpty()) ;
989 } 1059 }
990 1060
991 template <typename GEO> 1061 template <typename GEO>
992 void test_path_effect_fails(skiatest::Reporter* reporter, const GEO& geo) { 1062 void test_path_effect_fails(skiatest::Reporter* reporter, const GEO& geo) {
993 /** 1063 /**
994 * This path effect returns an empty path. 1064 * This path effect always fails to apply.
995 */ 1065 */
996 class FailurePathEffect : SkPathEffect { 1066 class FailurePathEffect : SkPathEffect {
997 public: 1067 public:
998 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, 1068 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
999 const SkRect* cullR) const override { 1069 const SkRect* cullR) const override {
1000 return false; 1070 return false;
1001 } 1071 }
1002 void computeFastBounds(SkRect* dst, const SkRect& src) const override { 1072 void computeFastBounds(SkRect* dst, const SkRect& src) const override {
1003 *dst = src; 1073 *dst = src;
1004 } 1074 }
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
1454 REPORTER_ASSERT(r, strokeInvAB.baseShape().asLine(pts, &inverted) && inverte d && 1524 REPORTER_ASSERT(r, strokeInvAB.baseShape().asLine(pts, &inverted) && inverte d &&
1455 pts[0] == canonicalPts[0] && pts[1] == canonicalPts[1]); 1525 pts[0] == canonicalPts[0] && pts[1] == canonicalPts[1]);
1456 REPORTER_ASSERT(r, hairlineInvAB.baseShape().asLine(pts, &inverted) && inver ted && 1526 REPORTER_ASSERT(r, hairlineInvAB.baseShape().asLine(pts, &inverted) && inver ted &&
1457 pts[0] == canonicalPts[0] && pts[1] == canonicalPts[1]); 1527 pts[0] == canonicalPts[0] && pts[1] == canonicalPts[1]);
1458 // Dashing ignores inverse. 1528 // Dashing ignores inverse.
1459 REPORTER_ASSERT(r, dashInvAB.baseShape().asLine(pts, &inverted) && !inverted && 1529 REPORTER_ASSERT(r, dashInvAB.baseShape().asLine(pts, &inverted) && !inverted &&
1460 pts[0] == kA && pts[1] == kB); 1530 pts[0] == kA && pts[1] == kB);
1461 1531
1462 } 1532 }
1463 1533
1534 static void test_stroked_lines(skiatest::Reporter* r) {
1535 // Paints to try
1536 SkPaint buttCap;
1537 buttCap.setStyle(SkPaint::kStroke_Style);
1538 buttCap.setStrokeWidth(4);
1539 buttCap.setStrokeCap(SkPaint::kButt_Cap);
1540
1541 SkPaint squareCap = buttCap;
1542 squareCap.setStrokeCap(SkPaint::kSquare_Cap);
1543
1544 SkPaint roundCap = buttCap;
1545 roundCap.setStrokeCap(SkPaint::kRound_Cap);
1546
1547 // vertical
1548 SkPath linePath;
1549 linePath.moveTo(4, 4);
1550 linePath.lineTo(4, 5);
1551
1552 SkPaint fill;
1553
1554 TestCase(linePath, buttCap, r).compare(r, TestCase(SkRect::MakeLTRB(2, 4, 6, 5), fill, r),
1555 TestCase::kAllSame_ComparisonExpecati on);
1556
1557 TestCase(linePath, squareCap, r).compare(r, TestCase(SkRect::MakeLTRB(2, 2, 6, 7), fill, r),
1558 TestCase::kAllSame_ComparisonExpeca tion);
1559
1560 TestCase(linePath, roundCap, r).compare(r,
1561 TestCase(SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 6, 7), 2, 2), fill, r),
1562 TestCase::kAllSame_ComparisonExpecation);
1563
1564 // horizontal
1565 linePath.reset();
1566 linePath.moveTo(4, 4);
1567 linePath.lineTo(5, 4);
1568
1569 TestCase(linePath, buttCap, r).compare(r, TestCase(SkRect::MakeLTRB(4, 2, 5, 6), fill, r),
1570 TestCase::kAllSame_ComparisonExpecati on);
1571 TestCase(linePath, squareCap, r).compare(r, TestCase(SkRect::MakeLTRB(2, 2, 7, 6), fill, r),
1572 TestCase::kAllSame_ComparisonExpeca tion);
1573 TestCase(linePath, roundCap, r).compare(r,
1574 TestCase(SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 7, 6), 2, 2), fill, r),
1575 TestCase::kAllSame_ComparisonExpecation);
1576
1577 // point
1578 linePath.reset();
1579 linePath.moveTo(4, 4);
1580 linePath.lineTo(4, 4);
1581
1582 TestCase(linePath, buttCap, r).compare(r, TestCase(SkRect::MakeEmpty(), fill , r),
1583 TestCase::kAllSame_ComparisonExpecati on);
1584 TestCase(linePath, squareCap, r).compare(r, TestCase(SkRect::MakeLTRB(2, 2, 6, 6), fill, r),
1585 TestCase::kAllSame_ComparisonExpeca tion);
1586 TestCase(linePath, roundCap, r).compare(r,
1587 TestCase(SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 6, 6), 2, 2), fill, r),
1588 TestCase::kAllSame_ComparisonExpecation);
1589 }
1590
1464 DEF_TEST(GrShape, reporter) { 1591 DEF_TEST(GrShape, reporter) {
1465 for (auto r : { SkRect::MakeWH(10, 20), 1592 for (auto r : { SkRect::MakeWH(10, 20),
1466 SkRect::MakeWH(-10, -20), 1593 SkRect::MakeWH(-10, -20),
1467 SkRect::MakeWH(-10, 20), 1594 SkRect::MakeWH(-10, 20),
1468 SkRect::MakeWH(10, -20)}) { 1595 SkRect::MakeWH(10, -20)}) {
1469 test_basic(reporter, r); 1596 test_basic(reporter, r);
1470 test_scale(reporter, r); 1597 test_scale(reporter, r);
1471 test_dash_fill(reporter, r); 1598 test_dash_fill(reporter, r);
1472 test_null_dash(reporter, r); 1599 test_null_dash(reporter, r);
1473 // Test modifying various stroke params. 1600 // Test modifying various stroke params.
1474 test_stroke_param<SkRect, SkScalar>( 1601 test_stroke_param<SkRect, SkScalar>(
1475 reporter, r, 1602 reporter, r,
1476 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, 1603 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);},
1477 SkIntToScalar(2), SkIntToScalar(4)); 1604 SkIntToScalar(2), SkIntToScalar(4));
1478 test_stroke_param<SkRect, SkPaint::Join>( 1605 test_stroke_join(reporter, r);
1479 reporter, r,
1480 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);},
1481 SkPaint::kMiter_Join, SkPaint::kRound_Join);
1482 test_stroke_cap(reporter, r); 1606 test_stroke_cap(reporter, r);
1483 test_miter_limit(reporter, r); 1607 test_miter_limit(reporter, r);
1484 test_path_effect_makes_rrect(reporter, r); 1608 test_path_effect_makes_rrect(reporter, r);
1485 test_unknown_path_effect(reporter, r); 1609 test_unknown_path_effect(reporter, r);
1486 test_path_effect_makes_empty_shape(reporter, r); 1610 test_path_effect_makes_empty_shape(reporter, r);
1487 test_path_effect_fails(reporter, r); 1611 test_path_effect_fails(reporter, r);
1488 test_make_hairline_path_effect(reporter, r, true); 1612 test_make_hairline_path_effect(reporter, r, true);
1489 GrShape shape(r); 1613 GrShape shape(r);
1490 REPORTER_ASSERT(reporter, !shape.asLine(nullptr, nullptr)); 1614 REPORTER_ASSERT(reporter, !shape.asLine(nullptr, nullptr));
1491 } 1615 }
1492 1616
1493 for (auto rr : { SkRRect::MakeRect(SkRect::MakeWH(10, 10)), 1617 for (auto rr : { SkRRect::MakeRect(SkRect::MakeWH(10, 10)),
1494 SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4), 1618 SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4),
1495 SkRRect::MakeOval(SkRect::MakeWH(20, 20))}) { 1619 SkRRect::MakeOval(SkRect::MakeWH(20, 20))}) {
1496 test_basic(reporter, rr); 1620 test_basic(reporter, rr);
1497 test_rrect(reporter, rr); 1621 test_rrect(reporter, rr);
1498 test_scale(reporter, rr); 1622 test_scale(reporter, rr);
1499 test_dash_fill(reporter, rr); 1623 test_dash_fill(reporter, rr);
1500 test_null_dash(reporter, rr); 1624 test_null_dash(reporter, rr);
1501 // Test modifying various stroke params. 1625 // Test modifying various stroke params.
1502 test_stroke_param<SkRRect, SkScalar>( 1626 test_stroke_param<SkRRect, SkScalar>(
1503 reporter, rr, 1627 reporter, rr,
1504 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, 1628 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);},
1505 SkIntToScalar(2), SkIntToScalar(4)); 1629 SkIntToScalar(2), SkIntToScalar(4));
1506 test_stroke_param<SkRRect, SkPaint::Join>( 1630 test_stroke_join(reporter, rr);
1507 reporter, rr,
1508 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j); },
1509 SkPaint::kMiter_Join, SkPaint::kRound_Join);
1510 test_stroke_cap(reporter, rr); 1631 test_stroke_cap(reporter, rr);
1511 test_miter_limit(reporter, rr); 1632 test_miter_limit(reporter, rr);
1512 test_path_effect_makes_rrect(reporter, rr); 1633 test_path_effect_makes_rrect(reporter, rr);
1513 test_unknown_path_effect(reporter, rr); 1634 test_unknown_path_effect(reporter, rr);
1514 test_path_effect_makes_empty_shape(reporter, rr); 1635 test_path_effect_makes_empty_shape(reporter, rr);
1515 test_path_effect_fails(reporter, rr); 1636 test_path_effect_fails(reporter, rr);
1516 test_make_hairline_path_effect(reporter, rr, true); 1637 test_make_hairline_path_effect(reporter, rr, true);
1517 GrShape shape(rr); 1638 GrShape shape(rr);
1518 REPORTER_ASSERT(reporter, !shape.asLine(nullptr, nullptr)); 1639 REPORTER_ASSERT(reporter, !shape.asLine(nullptr, nullptr));
1519 } 1640 }
(...skipping 30 matching lines...) Expand all
1550 paths.emplace_back(openRectPath, true, false, false, SkRRect::MakeRect(SkRec t::MakeWH(10, 10))); 1671 paths.emplace_back(openRectPath, true, false, false, SkRRect::MakeRect(SkRec t::MakeWH(10, 10)));
1551 1672
1552 SkPath quadPath; 1673 SkPath quadPath;
1553 quadPath.quadTo(10, 10, 5, 8); 1674 quadPath.quadTo(10, 10, 5, 8);
1554 paths.emplace_back(quadPath, false, false, false, SkRRect()); 1675 paths.emplace_back(quadPath, false, false, false, SkRRect());
1555 1676
1556 SkPath linePath; 1677 SkPath linePath;
1557 linePath.lineTo(10, 10); 1678 linePath.lineTo(10, 10);
1558 paths.emplace_back(linePath, false, false, true, SkRRect()); 1679 paths.emplace_back(linePath, false, false, true, SkRRect());
1559 1680
1681 // Horizontal and vertical paths become rrects when stroked.
1682 SkPath vLinePath;
1683 vLinePath.lineTo(0, 10);
1684 paths.emplace_back(vLinePath, false, false, true, SkRRect());
1685
1686 SkPath hLinePath;
1687 hLinePath.lineTo(10, 0);
1688 paths.emplace_back(hLinePath, false, false, true, SkRRect());
1689
1560 for (auto testPath : paths) { 1690 for (auto testPath : paths) {
1561 for (bool inverseFill : {false, true}) { 1691 for (bool inverseFill : {false, true}) {
1562 if (inverseFill) { 1692 if (inverseFill) {
1563 if (testPath.fPath.getFillType() == SkPath::kEvenOdd_FillType) { 1693 if (testPath.fPath.getFillType() == SkPath::kEvenOdd_FillType) {
1564 testPath.fPath.setFillType(SkPath::kInverseEvenOdd_FillType) ; 1694 testPath.fPath.setFillType(SkPath::kInverseEvenOdd_FillType) ;
1565 } else { 1695 } else {
1566 SkASSERT(testPath.fPath.getFillType() == SkPath::kWinding_Fi llType); 1696 SkASSERT(testPath.fPath.getFillType() == SkPath::kWinding_Fi llType);
1567 testPath.fPath.setFillType(SkPath::kInverseWinding_FillType) ; 1697 testPath.fPath.setFillType(SkPath::kInverseWinding_FillType) ;
1568 } 1698 }
1569 } 1699 }
(...skipping 10 matching lines...) Expand all
1580 } 1710 }
1581 test_scale(reporter, path); 1711 test_scale(reporter, path);
1582 // This test uses a stroking paint, hence use of fIsRRectForStroke 1712 // This test uses a stroking paint, hence use of fIsRRectForStroke
1583 test_volatile_path(reporter, path, testPath.fIsRRectForStroke || tes tPath.fIsLine); 1713 test_volatile_path(reporter, path, testPath.fIsRRectForStroke || tes tPath.fIsLine);
1584 test_dash_fill(reporter, path); 1714 test_dash_fill(reporter, path);
1585 // Test modifying various stroke params. 1715 // Test modifying various stroke params.
1586 test_stroke_param<SkPath, SkScalar>( 1716 test_stroke_param<SkPath, SkScalar>(
1587 reporter, path, 1717 reporter, path,
1588 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, 1718 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);},
1589 SkIntToScalar(2), SkIntToScalar(4)); 1719 SkIntToScalar(2), SkIntToScalar(4));
1590 test_stroke_param<SkPath, SkPaint::Join>( 1720 test_stroke_join(reporter, path);
1591 reporter, path,
1592 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);},
1593 SkPaint::kMiter_Join, SkPaint::kRound_Join);
1594 test_stroke_cap(reporter, path); 1721 test_stroke_cap(reporter, path);
1595 test_miter_limit(reporter, path); 1722 test_miter_limit(reporter, path);
1596 test_unknown_path_effect(reporter, path); 1723 test_unknown_path_effect(reporter, path);
1597 test_path_effect_makes_empty_shape(reporter, path); 1724 test_path_effect_makes_empty_shape(reporter, path);
1598 test_path_effect_fails(reporter, path); 1725 test_path_effect_fails(reporter, path);
1599 test_make_hairline_path_effect(reporter, path, testPath.fIsRRectForS troke || 1726 test_make_hairline_path_effect(reporter, path, testPath.fIsRRectForS troke ||
1600 testPath.fIsLine); 1727 testPath.fIsLine);
1601 } 1728 }
1602 } 1729 }
1603 1730
(...skipping 10 matching lines...) Expand all
1614 TestCase fillPathCase2(testPath.fPath, fillPaint, reporter); 1741 TestCase fillPathCase2(testPath.fPath, fillPaint, reporter);
1615 REPORTER_ASSERT(reporter, rrect == testPath.fRRect); 1742 REPORTER_ASSERT(reporter, rrect == testPath.fRRect);
1616 TestCase fillRRectCase(rrect, fillPaint, reporter); 1743 TestCase fillRRectCase(rrect, fillPaint, reporter);
1617 fillPathCase2.compare(reporter, fillRRectCase, 1744 fillPathCase2.compare(reporter, fillRRectCase,
1618 TestCase::kAllSame_ComparisonExpecation); 1745 TestCase::kAllSame_ComparisonExpecation);
1619 } 1746 }
1620 SkPaint strokePaint; 1747 SkPaint strokePaint;
1621 strokePaint.setStrokeWidth(3.f); 1748 strokePaint.setStrokeWidth(3.f);
1622 strokePaint.setStyle(SkPaint::kStroke_Style); 1749 strokePaint.setStyle(SkPaint::kStroke_Style);
1623 TestCase strokePathCase(path, strokePaint, reporter); 1750 TestCase strokePathCase(path, strokePaint, reporter);
1624 REPORTER_ASSERT(reporter, testPath.fIsRRectForStroke == 1751 if (testPath.fIsRRectForStroke) {
1625 strokePathCase.baseShape().asRRect(&rrect, nul lptr, nullptr, 1752 REPORTER_ASSERT(reporter, strokePathCase.baseShape().asRRect(&rrect, nullptr, nullptr,
1626 nullptr)); 1753 nullptr ));
1754 }
1755
1627 if (testPath.fIsRRectForStroke) { 1756 if (testPath.fIsRRectForStroke) {
1628 REPORTER_ASSERT(reporter, rrect == testPath.fRRect); 1757 REPORTER_ASSERT(reporter, rrect == testPath.fRRect);
1629 TestCase strokeRRectCase(rrect, strokePaint, reporter); 1758 TestCase strokeRRectCase(rrect, strokePaint, reporter);
1630 strokePathCase.compare(reporter, strokeRRectCase, 1759 strokePathCase.compare(reporter, strokeRRectCase,
1631 TestCase::kAllSame_ComparisonExpecation); 1760 TestCase::kAllSame_ComparisonExpecation);
1632 } 1761 }
1633 } 1762 }
1634 1763
1635 // Test a volatile empty path. 1764 // Test a volatile empty path.
1636 test_volatile_path(reporter, SkPath(), true); 1765 test_volatile_path(reporter, SkPath(), true);
1637 1766
1638 test_empty_shape(reporter); 1767 test_empty_shape(reporter);
1639 1768
1640 test_lines(reporter); 1769 test_lines(reporter);
1770
1771 test_stroked_lines(reporter);
1641 } 1772 }
1642 1773
1643 #endif 1774 #endif
OLDNEW
« no previous file with comments | « tests/DFPathRendererTest.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698