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

Side by Side Diff: tests/GrShapeTest.cpp

Issue 2157013003: Consolidate special case shape transformation logic in GrShapeTest. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Address comments 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 | « src/gpu/GrShape.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 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 static const SkScalar kIntervals[] = { 0.25, 3.f, 0.5, 2.f }; 426 static const SkScalar kIntervals[] = { 0.25, 3.f, 0.5, 2.f };
427 static const SkScalar kPhase = 0.75; 427 static const SkScalar kPhase = 0.75;
428 return SkDashPathEffect::Make(kIntervals, SK_ARRAY_COUNT(kIntervals), kPhase ); 428 return SkDashPathEffect::Make(kIntervals, SK_ARRAY_COUNT(kIntervals), kPhase );
429 } 429 }
430 430
431 static sk_sp<SkPathEffect> make_null_dash() { 431 static sk_sp<SkPathEffect> make_null_dash() {
432 static const SkScalar kNullIntervals[] = {0, 0, 0, 0, 0, 0}; 432 static const SkScalar kNullIntervals[] = {0, 0, 0, 0, 0, 0};
433 return SkDashPathEffect::Make(kNullIntervals, SK_ARRAY_COUNT(kNullIntervals) , 0.f); 433 return SkDashPathEffect::Make(kNullIntervals, SK_ARRAY_COUNT(kNullIntervals) , 0.f);
434 } 434 }
435 435
436 //////////////////////////////////////////////////////////////////////////////
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
436 template<typename GEO> 506 template<typename GEO>
437 static void test_basic(skiatest::Reporter* reporter, const GEO& geo) { 507 static void test_basic(skiatest::Reporter* reporter, const GEO& geo) {
438 sk_sp<SkPathEffect> dashPE = make_dash(); 508 sk_sp<SkPathEffect> dashPE = make_dash();
439 509
440 TestCase::SelfExpectations expectations; 510 TestCase::SelfExpectations expectations;
441 SkPaint fill; 511 SkPaint fill;
442 512
443 TestCase fillCase(geo, fill, reporter); 513 TestCase fillCase(geo, fill, reporter);
444 expectations.fPEHasEffect = false; 514 expectations.fPEHasEffect = false;
445 expectations.fPEHasValidKey = false; 515 expectations.fPEHasValidKey = false;
446 expectations.fStrokeApplies = false; 516 expectations.fStrokeApplies = false;
447 fillCase.testExpectations(reporter, expectations); 517 fillCase.testExpectations(reporter, expectations);
448 // Test that another GrShape instance built from the same primitive is the s ame. 518 // Test that another GrShape instance built from the same primitive is the s ame.
449 TestCase(geo, fill, reporter).compare(reporter, fillCase, 519 TestCase(geo, fill, reporter).compare(reporter, fillCase,
450 TestCase::kAllSame_ComparisonExpecatio n); 520 TestCase::kAllSame_ComparisonExpecatio n);
451 521
452 SkPaint stroke2RoundBevel; 522 SkPaint stroke2RoundBevel;
453 stroke2RoundBevel.setStyle(SkPaint::kStroke_Style); 523 stroke2RoundBevel.setStyle(SkPaint::kStroke_Style);
454 stroke2RoundBevel.setStrokeCap(SkPaint::kRound_Cap); 524 stroke2RoundBevel.setStrokeCap(SkPaint::kRound_Cap);
455 stroke2RoundBevel.setStrokeJoin(SkPaint::kBevel_Join); 525 stroke2RoundBevel.setStrokeJoin(SkPaint::kBevel_Join);
456 stroke2RoundBevel.setStrokeWidth(2.f); 526 stroke2RoundBevel.setStrokeWidth(2.f);
457 TestCase stroke2RoundBevelCase(geo, stroke2RoundBevel, reporter); 527 TestCase stroke2RoundBevelCase(geo, stroke2RoundBevel, reporter);
458 expectations.fPEHasValidKey = true; 528 expectations.fPEHasValidKey = true;
459 expectations.fPEHasEffect = false; 529 expectations.fPEHasEffect = false;
460 expectations.fStrokeApplies = true; 530 expectations.fStrokeApplies = !stroke_is_converted_to_fill(geo);
461 stroke2RoundBevelCase.testExpectations(reporter, expectations); 531 stroke2RoundBevelCase.testExpectations(reporter, expectations);
462 TestCase(geo, stroke2RoundBevel, reporter).compare(reporter, stroke2RoundBev elCase, 532 TestCase(geo, stroke2RoundBevel, reporter).compare(reporter, stroke2RoundBev elCase,
463 TestCase::kAllSame_Compar isonExpecation); 533 TestCase::kAllSame_Compar isonExpecation);
464 534
465 SkPaint stroke2RoundBevelDash = stroke2RoundBevel; 535 SkPaint stroke2RoundBevelDash = stroke2RoundBevel;
466 stroke2RoundBevelDash.setPathEffect(make_dash()); 536 stroke2RoundBevelDash.setPathEffect(make_dash());
467 TestCase stroke2RoundBevelDashCase(geo, stroke2RoundBevelDash, reporter); 537 TestCase stroke2RoundBevelDashCase(geo, stroke2RoundBevelDash, reporter);
468 expectations.fPEHasValidKey = true; 538 expectations.fPEHasValidKey = true;
469 expectations.fPEHasEffect = true; 539 expectations.fPEHasEffect = true;
470 expectations.fStrokeApplies = true; 540 expectations.fStrokeApplies = true;
471 stroke2RoundBevelDashCase.testExpectations(reporter, expectations); 541 stroke2RoundBevelDashCase.testExpectations(reporter, expectations);
472 TestCase(geo, stroke2RoundBevelDash, reporter).compare(reporter, stroke2Roun dBevelDashCase, 542 TestCase(geo, stroke2RoundBevelDash, reporter).compare(reporter, stroke2Roun dBevelDashCase,
473 TestCase::kAllSame_Co mparisonExpecation); 543 TestCase::kAllSame_Co mparisonExpecation);
474 544
475 fillCase.compare(reporter, stroke2RoundBevelCase, 545 if (fill_changes_geom(geo) || stroke_is_converted_to_fill(geo)) {
476 TestCase::kSameUpToStroke_ComparisonExpecation); 546 fillCase.compare(reporter, stroke2RoundBevelCase,
477 fillCase.compare(reporter, stroke2RoundBevelDashCase, 547 TestCase::kAllDifferent_ComparisonExpecation);
478 TestCase::kSameUpToPE_ComparisonExpecation); 548 fillCase.compare(reporter, stroke2RoundBevelDashCase,
479 stroke2RoundBevelCase.compare(reporter, stroke2RoundBevelDashCase, 549 TestCase::kAllDifferent_ComparisonExpecation);
480 TestCase::kSameUpToPE_ComparisonExpecation); 550 } else {
551 fillCase.compare(reporter, stroke2RoundBevelCase,
552 TestCase::kSameUpToStroke_ComparisonExpecation);
553 fillCase.compare(reporter, stroke2RoundBevelDashCase,
554 TestCase::kSameUpToPE_ComparisonExpecation);
555 }
556 if (stroke_is_converted_to_fill(geo)) {
557 stroke2RoundBevelCase.compare(reporter, stroke2RoundBevelDashCase,
558 TestCase::kAllDifferent_ComparisonExpecati on);
559 } else {
560 stroke2RoundBevelCase.compare(reporter, stroke2RoundBevelDashCase,
561 TestCase::kSameUpToPE_ComparisonExpecation );
562 }
481 563
482 // Stroke and fill cases 564 // Stroke and fill cases
483 SkPaint stroke2RoundBevelAndFill = stroke2RoundBevel; 565 SkPaint stroke2RoundBevelAndFill = stroke2RoundBevel;
484 stroke2RoundBevelAndFill.setStyle(SkPaint::kStrokeAndFill_Style); 566 stroke2RoundBevelAndFill.setStyle(SkPaint::kStrokeAndFill_Style);
485 TestCase stroke2RoundBevelAndFillCase(geo, stroke2RoundBevelAndFill, reporte r); 567 TestCase stroke2RoundBevelAndFillCase(geo, stroke2RoundBevelAndFill, reporte r);
486 expectations.fPEHasValidKey = true; 568 expectations.fPEHasValidKey = true;
487 expectations.fPEHasEffect = false; 569 expectations.fPEHasEffect = false;
488 expectations.fStrokeApplies = true; 570 expectations.fStrokeApplies = !stroke_is_converted_to_fill(geo);
489 stroke2RoundBevelAndFillCase.testExpectations(reporter, expectations); 571 stroke2RoundBevelAndFillCase.testExpectations(reporter, expectations);
490 TestCase(geo, stroke2RoundBevelAndFill, reporter).compare(reporter, 572 TestCase(geo, stroke2RoundBevelAndFill, reporter).compare(reporter,
491 stroke2RoundBevelAndFillCase, TestCase::kAllSame_ComparisonExpecatio n); 573 stroke2RoundBevelAndFillCase, TestCase::kAllSame_ComparisonExpecatio n);
492 574
493 SkPaint stroke2RoundBevelAndFillDash = stroke2RoundBevelDash; 575 SkPaint stroke2RoundBevelAndFillDash = stroke2RoundBevelDash;
494 stroke2RoundBevelAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style); 576 stroke2RoundBevelAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style);
495 TestCase stroke2RoundBevelAndFillDashCase(geo, stroke2RoundBevelAndFillDash, reporter); 577 TestCase stroke2RoundBevelAndFillDashCase(geo, stroke2RoundBevelAndFillDash, reporter);
496 expectations.fPEHasValidKey = true; 578 expectations.fPEHasValidKey = true;
497 expectations.fPEHasEffect = false; 579 expectations.fPEHasEffect = false;
498 expectations.fStrokeApplies = true; 580 expectations.fStrokeApplies = !stroke_is_converted_to_fill(geo);
499 stroke2RoundBevelAndFillDashCase.testExpectations(reporter, expectations); 581 stroke2RoundBevelAndFillDashCase.testExpectations(reporter, expectations);
500 TestCase(geo, stroke2RoundBevelAndFillDash, reporter).compare( 582 TestCase(geo, stroke2RoundBevelAndFillDash, reporter).compare(
501 reporter, stroke2RoundBevelAndFillDashCase, TestCase::kAllSame_Compariso nExpecation); 583 reporter, stroke2RoundBevelAndFillDashCase, TestCase::kAllSame_Compariso nExpecation);
502 stroke2RoundBevelAndFillDashCase.compare(reporter, stroke2RoundBevelAndFillC ase, 584 stroke2RoundBevelAndFillDashCase.compare(reporter, stroke2RoundBevelAndFillC ase,
503 TestCase::kAllSame_ComparisonExpeca tion); 585 TestCase::kAllSame_ComparisonExpeca tion);
504 586
505 SkPaint hairline; 587 SkPaint hairline;
506 hairline.setStyle(SkPaint::kStroke_Style); 588 hairline.setStyle(SkPaint::kStroke_Style);
507 hairline.setStrokeWidth(0.f); 589 hairline.setStrokeWidth(0.f);
508 TestCase hairlineCase(geo, hairline, reporter); 590 TestCase hairlineCase(geo, hairline, reporter);
509 // Since hairline style doesn't change the SkPath data, it is keyed identica lly to fill. 591 // Since hairline style doesn't change the SkPath data, it is keyed identica lly to fill (except
510 hairlineCase.compare(reporter, fillCase, TestCase::kAllSame_ComparisonExpeca tion); 592 // in the line and unclosed rect cases).
593 if (fill_changes_geom(geo)) {
594 hairlineCase.compare(reporter, fillCase, TestCase::kAllDifferent_Compari sonExpecation);
595 } else {
596 hairlineCase.compare(reporter, fillCase, TestCase::kAllSame_ComparisonEx pecation);
597 }
511 REPORTER_ASSERT(reporter, hairlineCase.baseShape().style().isSimpleHairline( )); 598 REPORTER_ASSERT(reporter, hairlineCase.baseShape().style().isSimpleHairline( ));
512 REPORTER_ASSERT(reporter, hairlineCase.appliedFullStyleShape().style().isSim pleHairline()); 599 REPORTER_ASSERT(reporter, hairlineCase.appliedFullStyleShape().style().isSim pleHairline());
513 REPORTER_ASSERT(reporter, hairlineCase.appliedPathEffectShape().style().isSi mpleHairline()); 600 REPORTER_ASSERT(reporter, hairlineCase.appliedPathEffectShape().style().isSi mpleHairline());
514 }
515 601
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 } 602 }
522 603
523 template<typename GEO> 604 template<typename GEO>
524 static void test_scale(skiatest::Reporter* reporter, const GEO& geo) { 605 static void test_scale(skiatest::Reporter* reporter, const GEO& geo) {
525 sk_sp<SkPathEffect> dashPE = make_dash(); 606 sk_sp<SkPathEffect> dashPE = make_dash();
526 607
527 static const SkScalar kS1 = 1.f; 608 static const SkScalar kS1 = 1.f;
528 static const SkScalar kS2 = 2.f; 609 static const SkScalar kS2 = 2.f;
529 610
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 };
539 SkPaint fill; 611 SkPaint fill;
540 TestCase fillCase1(geo, fill, reporter, kS1); 612 TestCase fillCase1(geo, fill, reporter, kS1);
541 TestCase fillCase2(geo, fill, reporter, kS2); 613 TestCase fillCase2(geo, fill, reporter, kS2);
542 // Scale doesn't affect fills. 614 // Scale doesn't affect fills.
543 fillCase1.compare(reporter, fillCase2, TestCase::kAllSame_ComparisonExpecati on); 615 fillCase1.compare(reporter, fillCase2, TestCase::kAllSame_ComparisonExpecati on);
544 616
545 SkPaint hairline; 617 SkPaint hairline;
546 hairline.setStyle(SkPaint::kStroke_Style); 618 hairline.setStyle(SkPaint::kStroke_Style);
547 hairline.setStrokeWidth(0.f); 619 hairline.setStrokeWidth(0.f);
548 TestCase hairlineCase1(geo, hairline, reporter, kS1); 620 TestCase hairlineCase1(geo, hairline, reporter, kS1);
549 TestCase hairlineCase2(geo, hairline, reporter, kS2); 621 TestCase hairlineCase2(geo, hairline, reporter, kS2);
550 // Scale doesn't affect hairlines. 622 // Scale doesn't affect hairlines.
551 hairlineCase1.compare(reporter, hairlineCase2, TestCase::kAllSame_Comparison Expecation); 623 hairlineCase1.compare(reporter, hairlineCase2, TestCase::kAllSame_Comparison Expecation);
552 624
553 SkPaint stroke; 625 SkPaint stroke;
554 stroke.setStyle(SkPaint::kStroke_Style); 626 stroke.setStyle(SkPaint::kStroke_Style);
555 stroke.setStrokeWidth(2.f); 627 stroke.setStrokeWidth(2.f);
556 TestCase strokeCase1(geo, stroke, reporter, kS1); 628 TestCase strokeCase1(geo, stroke, reporter, kS1);
557 TestCase strokeCase2(geo, stroke, reporter, kS2); 629 TestCase strokeCase2(geo, stroke, reporter, kS2);
558 // Scale affects the stroke 630 // Scale affects the stroke
559 if (wasSimplified(strokeCase1)) { 631 if (stroke_is_converted_to_fill(geo)) {
560 REPORTER_ASSERT(reporter, wasSimplified(strokeCase2)); 632 REPORTER_ASSERT(reporter, !strokeCase1.baseShape().style().applies());
561 strokeCase1.compare(reporter, strokeCase2, TestCase::kAllSame_Comparison Expecation); 633 strokeCase1.compare(reporter, strokeCase2, TestCase::kAllSame_Comparison Expecation);
562 } else { 634 } else {
563 strokeCase1.compare(reporter, strokeCase2, TestCase::kSameUpToStroke_Com parisonExpecation); 635 strokeCase1.compare(reporter, strokeCase2, TestCase::kSameUpToStroke_Com parisonExpecation);
564 } 636 }
565 637
566 SkPaint strokeDash = stroke; 638 SkPaint strokeDash = stroke;
567 strokeDash.setPathEffect(make_dash()); 639 strokeDash.setPathEffect(make_dash());
568 TestCase strokeDashCase1(geo, strokeDash, reporter, kS1); 640 TestCase strokeDashCase1(geo, strokeDash, reporter, kS1);
569 TestCase strokeDashCase2(geo, strokeDash, reporter, kS2); 641 TestCase strokeDashCase2(geo, strokeDash, reporter, kS2);
570 // Scale affects the dash and the stroke. 642 // Scale affects the dash and the stroke.
571 if (wasSimplified(strokeDashCase1)) { 643 strokeDashCase1.compare(reporter, strokeDashCase2,
572 REPORTER_ASSERT(reporter, wasSimplified(strokeDashCase2)); 644 TestCase::kSameUpToPE_ComparisonExpecation);
573 strokeDashCase1.compare(reporter, strokeDashCase2,
574 TestCase::kAllSame_ComparisonExpecation);
575 } else {
576 strokeDashCase1.compare(reporter, strokeDashCase2,
577 TestCase::kSameUpToPE_ComparisonExpecation);
578 }
579 645
580 // Stroke and fill cases 646 // Stroke and fill cases
581 SkPaint strokeAndFill = stroke; 647 SkPaint strokeAndFill = stroke;
582 strokeAndFill.setStyle(SkPaint::kStrokeAndFill_Style); 648 strokeAndFill.setStyle(SkPaint::kStrokeAndFill_Style);
583 TestCase strokeAndFillCase1(geo, strokeAndFill, reporter, kS1); 649 TestCase strokeAndFillCase1(geo, strokeAndFill, reporter, kS1);
584 TestCase strokeAndFillCase2(geo, strokeAndFill, reporter, kS2); 650 TestCase strokeAndFillCase2(geo, strokeAndFill, reporter, kS2);
585 SkPaint strokeAndFillDash = strokeDash; 651 SkPaint strokeAndFillDash = strokeDash;
586 strokeAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style); 652 strokeAndFillDash.setStyle(SkPaint::kStrokeAndFill_Style);
587 // Dash is ignored for stroke and fill 653 // Dash is ignored for stroke and fill
588 TestCase strokeAndFillDashCase1(geo, strokeAndFillDash, reporter, kS1); 654 TestCase strokeAndFillDashCase1(geo, strokeAndFillDash, reporter, kS1);
589 TestCase strokeAndFillDashCase2(geo, strokeAndFillDash, reporter, kS2); 655 TestCase strokeAndFillDashCase2(geo, strokeAndFillDash, reporter, kS2);
590 // Scale affects the stroke. Scale affects the stroke, but check to make sur e this didn't 656 // Scale affects the stroke, but check to make sure this didn't become a sim pler shape (e.g.
591 // become a simpler shape (e.g. stroke-and-filled rect can become a rect), i n which case the 657 // stroke-and-filled rect can become a rect), in which case the scale should n't matter and the
592 // scale shouldn't matter and the geometries should agree. 658 // geometries should agree.
593 if (wasSimplified(strokeAndFillCase1)) { 659 if (stroke_and_fill_is_converted_to_fill(geo, strokeAndFillDash)) {
594 REPORTER_ASSERT(reporter, wasSimplified(strokeAndFillCase1)); 660 REPORTER_ASSERT(reporter, !strokeAndFillCase1.baseShape().style().applie s());
595 REPORTER_ASSERT(reporter, wasSimplified(strokeAndFillDashCase1));
596 REPORTER_ASSERT(reporter, wasSimplified(strokeAndFillDashCase2));
597 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, 661 strokeAndFillCase1.compare(reporter, strokeAndFillCase2,
598 TestCase::kAllSame_ComparisonExpecation); 662 TestCase::kAllSame_ComparisonExpecation);
599 strokeAndFillDashCase1.compare(reporter, strokeAndFillDashCase2, 663 strokeAndFillDashCase1.compare(reporter, strokeAndFillDashCase2,
600 TestCase::kAllSame_ComparisonExpecation); 664 TestCase::kAllSame_ComparisonExpecation);
601 } else { 665 } else {
602 strokeAndFillCase1.compare(reporter, strokeAndFillCase2, 666 strokeAndFillCase1.compare(reporter, strokeAndFillCase2,
603 TestCase::kSameUpToStroke_ComparisonExpecatio n); 667 TestCase::kSameUpToStroke_ComparisonExpecatio n);
604 } 668 }
605 strokeAndFillDashCase1.compare(reporter, strokeAndFillCase1, 669 strokeAndFillDashCase1.compare(reporter, strokeAndFillCase1,
606 TestCase::kAllSame_ComparisonExpecation); 670 TestCase::kAllSame_ComparisonExpecation);
(...skipping 15 matching lines...) Expand all
622 SkPaint strokeB; 686 SkPaint strokeB;
623 strokeB.setStyle(SkPaint::kStroke_Style); 687 strokeB.setStyle(SkPaint::kStroke_Style);
624 strokeB.setStrokeWidth(2.f); 688 strokeB.setStrokeWidth(2.f);
625 setter(&strokeB, b); 689 setter(&strokeB, b);
626 690
627 TestCase strokeACase(geo, strokeA, reporter); 691 TestCase strokeACase(geo, strokeA, reporter);
628 TestCase strokeBCase(geo, strokeB, reporter); 692 TestCase strokeBCase(geo, strokeB, reporter);
629 if (paramAffectsStroke) { 693 if (paramAffectsStroke) {
630 // If stroking is immediately incorporated into a geometric transformati on then the base 694 // If stroking is immediately incorporated into a geometric transformati on then the base
631 // shapes will differ. 695 // shapes will differ.
632 if (strokeACase.baseShape().style().applies()) { 696 if (stroke_is_converted_to_fill(geo)) {
697 strokeACase.compare(reporter, strokeBCase,
698 TestCase::kAllDifferent_ComparisonExpecation);
699 } else {
633 strokeACase.compare(reporter, strokeBCase, 700 strokeACase.compare(reporter, strokeBCase,
634 TestCase::kSameUpToStroke_ComparisonExpecation); 701 TestCase::kSameUpToStroke_ComparisonExpecation);
635 } else {
636 strokeACase.compare(reporter, strokeBCase,
637 TestCase::kAllDifferent_ComparisonExpecation);
638 } 702 }
639 } else { 703 } else {
640 strokeACase.compare(reporter, strokeBCase, TestCase::kAllSame_Comparison Expecation); 704 strokeACase.compare(reporter, strokeBCase, TestCase::kAllSame_Comparison Expecation);
641 } 705 }
642 706
643 SkPaint strokeAndFillA = strokeA; 707 SkPaint strokeAndFillA = strokeA;
644 SkPaint strokeAndFillB = strokeB; 708 SkPaint strokeAndFillB = strokeB;
645 strokeAndFillA.setStyle(SkPaint::kStrokeAndFill_Style); 709 strokeAndFillA.setStyle(SkPaint::kStrokeAndFill_Style);
646 strokeAndFillB.setStyle(SkPaint::kStrokeAndFill_Style); 710 strokeAndFillB.setStyle(SkPaint::kStrokeAndFill_Style);
647 TestCase strokeAndFillACase(geo, strokeAndFillA, reporter); 711 TestCase strokeAndFillACase(geo, strokeAndFillA, reporter);
648 TestCase strokeAndFillBCase(geo, strokeAndFillB, reporter); 712 TestCase strokeAndFillBCase(geo, strokeAndFillB, reporter);
649 if (paramAffectsStroke) { 713 if (paramAffectsStroke) {
650 // If stroking is immediately incorporated into a geometric transformati on then the base 714 // If stroking is immediately incorporated into a geometric transformati on then the base
651 // shapes will differ. 715 // shapes will differ.
652 if (strokeAndFillACase.baseShape().style().applies()) { 716 if (stroke_and_fill_is_converted_to_fill(geo, strokeAndFillA) ||
717 stroke_and_fill_is_converted_to_fill(geo, strokeAndFillB)) {
653 strokeAndFillACase.compare(reporter, strokeAndFillBCase, 718 strokeAndFillACase.compare(reporter, strokeAndFillBCase,
654 TestCase::kSameUpToStroke_ComparisonExpecation); 719 TestCase::kAllDifferent_ComparisonExpecat ion);
655 } else { 720 } else {
656 strokeAndFillACase.compare(reporter, strokeAndFillBCase, 721 strokeAndFillACase.compare(reporter, strokeAndFillBCase,
657 TestCase::kAllDifferent_ComparisonExpecation); 722 TestCase::kSameUpToStroke_ComparisonExpec ation);
658 } 723 }
659 } else { 724 } else {
660 strokeAndFillACase.compare(reporter, strokeAndFillBCase, 725 strokeAndFillACase.compare(reporter, strokeAndFillBCase,
661 TestCase::kAllSame_ComparisonExpecation); 726 TestCase::kAllSame_ComparisonExpecation);
662 } 727 }
663 728
664 // Make sure stroking params don't affect fill style. 729 // Make sure stroking params don't affect fill style.
665 SkPaint fillA = strokeA, fillB = strokeB; 730 SkPaint fillA = strokeA, fillB = strokeB;
666 fillA.setStyle(SkPaint::kFill_Style); 731 fillA.setStyle(SkPaint::kFill_Style);
667 fillB.setStyle(SkPaint::kFill_Style); 732 fillB.setStyle(SkPaint::kFill_Style);
668 TestCase fillACase(geo, fillA, reporter); 733 TestCase fillACase(geo, fillA, reporter);
669 TestCase fillBCase(geo, fillB, reporter); 734 TestCase fillBCase(geo, fillB, reporter);
670 fillACase.compare(reporter, fillBCase, TestCase::kAllSame_ComparisonExpecati on); 735 fillACase.compare(reporter, fillBCase, TestCase::kAllSame_ComparisonExpecati on);
671 736
672 // Make sure just applying the dash but not stroke gives the same key for bo th stroking 737 // Make sure just applying the dash but not stroke gives the same key for bo th stroking
673 // variations. 738 // variations.
674 SkPaint dashA = strokeA, dashB = strokeB; 739 SkPaint dashA = strokeA, dashB = strokeB;
675 dashA.setPathEffect(make_dash()); 740 dashA.setPathEffect(make_dash());
676 dashB.setPathEffect(make_dash()); 741 dashB.setPathEffect(make_dash());
677 TestCase dashACase(geo, dashA, reporter); 742 TestCase dashACase(geo, dashA, reporter);
678 TestCase dashBCase(geo, dashB, reporter); 743 TestCase dashBCase(geo, dashB, reporter);
679 if (paramAffectsDashAndStroke) { 744 if (paramAffectsDashAndStroke) {
680 // If stroking is immediately incorporated into a geometric transformati on then the base 745 dashACase.compare(reporter, dashBCase, TestCase::kSameUpToStroke_Compari sonExpecation);
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 }
687 } else { 746 } else {
688 dashACase.compare(reporter, dashBCase, TestCase::kAllSame_ComparisonExpe cation); 747 dashACase.compare(reporter, dashBCase, TestCase::kAllSame_ComparisonExpe cation);
689 } 748 }
690 } 749 }
691 750
692 template <typename GEO, typename T> 751 template <typename GEO, typename T>
693 static void test_stroke_param(skiatest::Reporter* reporter, const GEO& geo, 752 static void test_stroke_param(skiatest::Reporter* reporter, const GEO& geo,
694 std::function<void(SkPaint*, T)> setter, T a, T b) { 753 std::function<void(SkPaint*, T)> setter, T a, T b) {
695 test_stroke_param_impl(reporter, geo, setter, a, b, true, true); 754 test_stroke_param_impl(reporter, geo, setter, a, b, true, true);
696 }; 755 };
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 SkPaint nullDash; 853 SkPaint nullDash;
795 nullDash.setStyle(SkPaint::kStroke_Style); 854 nullDash.setStyle(SkPaint::kStroke_Style);
796 nullDash.setStrokeWidth(1.f); 855 nullDash.setStrokeWidth(1.f);
797 nullDash.setPathEffect(make_null_dash()); 856 nullDash.setPathEffect(make_null_dash());
798 857
799 TestCase fillCase(geo, fill, reporter); 858 TestCase fillCase(geo, fill, reporter);
800 TestCase strokeCase(geo, stroke, reporter); 859 TestCase strokeCase(geo, stroke, reporter);
801 TestCase dashCase(geo, dash, reporter); 860 TestCase dashCase(geo, dash, reporter);
802 TestCase nullDashCase(geo, nullDash, reporter); 861 TestCase nullDashCase(geo, nullDash, reporter);
803 862
804 nullDashCase.compare(reporter, fillCase, TestCase::kSameUpToStroke_Compariso nExpecation); 863 // We expect the null dash to be ignored so nullDashCase should match stroke Case, always.
805 nullDashCase.compare(reporter, strokeCase, TestCase::kAllSame_ComparisonExpe cation); 864 nullDashCase.compare(reporter, strokeCase, TestCase::kAllSame_ComparisonExpe cation);
806 nullDashCase.compare(reporter, dashCase, TestCase::kSameUpToPE_ComparisonExp ecation); 865 // 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.
867 if (fill_changes_geom(geo) || stroke_is_converted_to_fill(geo)) {
868 nullDashCase.compare(reporter, fillCase, TestCase::kAllDifferent_Compari sonExpecation);
869 } else {
870 nullDashCase.compare(reporter, fillCase, TestCase::kSameUpToStroke_Compa risonExpecation);
871 }
872 // 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)) {
874 nullDashCase.compare(reporter, dashCase, TestCase::kAllDifferent_Compari sonExpecation);
875 } else {
876 nullDashCase.compare(reporter, dashCase, TestCase::kSameUpToPE_Compariso nExpecation);
877 }
807 } 878 }
808 879
809 template <typename GEO> 880 template <typename GEO>
810 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) {
811 /** 882 /**
812 * This path effect takes any input path and turns it into a rrect. It passe s through stroke 883 * This path effect takes any input path and turns it into a rrect. It passe s through stroke
813 * info. 884 * info.
814 */ 885 */
815 class RRectPathEffect : SkPathEffect { 886 class RRectPathEffect : SkPathEffect {
816 public: 887 public:
(...skipping 24 matching lines...) Expand all
841 SkPaint pe; 912 SkPaint pe;
842 pe.setPathEffect(RRectPathEffect::Make()); 913 pe.setPathEffect(RRectPathEffect::Make());
843 TestCase geoPECase(geo, pe, reporter); 914 TestCase geoPECase(geo, pe, reporter);
844 915
845 SkPaint peStroke; 916 SkPaint peStroke;
846 peStroke.setPathEffect(RRectPathEffect::Make()); 917 peStroke.setPathEffect(RRectPathEffect::Make());
847 peStroke.setStrokeWidth(2.f); 918 peStroke.setStrokeWidth(2.f);
848 peStroke.setStyle(SkPaint::kStroke_Style); 919 peStroke.setStyle(SkPaint::kStroke_Style);
849 TestCase geoPEStrokeCase(geo, peStroke, reporter); 920 TestCase geoPEStrokeCase(geo, peStroke, reporter);
850 921
851 fillGeoCase.compare(reporter, geoPECase, TestCase::kSameUpToPE_ComparisonExp ecation); 922 // Check whether constructing the filled case would cause the base shape to have a different
852 fillGeoCase.compare(reporter, geoPEStrokeCase, TestCase::kSameUpToPE_Compari sonExpecation); 923 // geometry (because of a geometric transformation upon initial GrShape cons truction).
924 if (fill_changes_geom(geo)) {
925 fillGeoCase.compare(reporter, geoPECase, TestCase::kAllDifferent_Compari sonExpecation);
926 fillGeoCase.compare(reporter, geoPEStrokeCase,
927 TestCase::kAllDifferent_ComparisonExpecation);
928 } else {
929 fillGeoCase.compare(reporter, geoPECase, TestCase::kSameUpToPE_Compariso nExpecation);
930 fillGeoCase.compare(reporter, geoPEStrokeCase, TestCase::kSameUpToPE_Com parisonExpecation);
931 }
853 geoPECase.compare(reporter, geoPEStrokeCase, 932 geoPECase.compare(reporter, geoPEStrokeCase,
854 TestCase::kSameUpToStroke_ComparisonExpecation); 933 TestCase::kSameUpToStroke_ComparisonExpecation);
855 934
856 TestCase rrectFillCase(RRectPathEffect::RRect(), fill, reporter); 935 TestCase rrectFillCase(RRectPathEffect::RRect(), fill, reporter);
857 SkPaint stroke = peStroke; 936 SkPaint stroke = peStroke;
858 stroke.setPathEffect(nullptr); 937 stroke.setPathEffect(nullptr);
859 TestCase rrectStrokeCase(RRectPathEffect::RRect(), stroke, reporter); 938 TestCase rrectStrokeCase(RRectPathEffect::RRect(), stroke, reporter);
860 939
861 SkRRect rrect; 940 SkRRect rrect;
862 // Applying the path effect should make a SkRRect shape. There is no further stroking in the 941 // Applying the path effect should make a SkRRect shape. There is no further stroking in the
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 kStrokeAndFill 1269 kStrokeAndFill
1191 }; 1270 };
1192 1271
1193 // SkStrokeRec has no default cons., so init with kFill before calling the s etters below. 1272 // SkStrokeRec has no default cons., so init with kFill before calling the s etters below.
1194 SkStrokeRec strokeRecs[4] { SkStrokeRec::kFill_InitStyle, SkStrokeRec::kFill _InitStyle, 1273 SkStrokeRec strokeRecs[4] { SkStrokeRec::kFill_InitStyle, SkStrokeRec::kFill _InitStyle,
1195 SkStrokeRec::kFill_InitStyle, SkStrokeRec::kFill _InitStyle}; 1274 SkStrokeRec::kFill_InitStyle, SkStrokeRec::kFill _InitStyle};
1196 strokeRecs[kFill].setFillStyle(); 1275 strokeRecs[kFill].setFillStyle();
1197 strokeRecs[kStroke].setStrokeStyle(2.f); 1276 strokeRecs[kStroke].setStrokeStyle(2.f);
1198 strokeRecs[kHairline].setHairlineStyle(); 1277 strokeRecs[kHairline].setHairlineStyle();
1199 strokeRecs[kStrokeAndFill].setStrokeStyle(3.f, true); 1278 strokeRecs[kStrokeAndFill].setStrokeStyle(3.f, true);
1279 // Use a bevel join to avoid complications of stroke+filled rects becoming f illed rects before
1280 // applyStyle() is called.
1281 strokeRecs[kStrokeAndFill].setStrokeParams(SkPaint::kButt_Cap, SkPaint::kBev el_Join, 1.f);
1200 sk_sp<SkPathEffect> dashEffect = make_dash(); 1282 sk_sp<SkPathEffect> dashEffect = make_dash();
1201 1283
1202 static constexpr Style kStyleCnt = static_cast<Style>(SK_ARRAY_COUNT(strokeR ecs)); 1284 static constexpr Style kStyleCnt = static_cast<Style>(SK_ARRAY_COUNT(strokeR ecs));
1203 1285
1204 auto index = [](bool inverted, 1286 auto index = [](bool inverted,
1205 SkPath::Direction dir, 1287 SkPath::Direction dir,
1206 unsigned start, 1288 unsigned start,
1207 Style style, 1289 Style style,
1208 bool dash) -> int { 1290 bool dash) -> int {
1209 return inverted * (2 * 8 * kStyleCnt * 2) + 1291 return inverted * (2 * 8 * kStyleCnt * 2) +
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
1691 for (bool inverseFill : {false, true}) { 1773 for (bool inverseFill : {false, true}) {
1692 if (inverseFill) { 1774 if (inverseFill) {
1693 if (testPath.fPath.getFillType() == SkPath::kEvenOdd_FillType) { 1775 if (testPath.fPath.getFillType() == SkPath::kEvenOdd_FillType) {
1694 testPath.fPath.setFillType(SkPath::kInverseEvenOdd_FillType) ; 1776 testPath.fPath.setFillType(SkPath::kInverseEvenOdd_FillType) ;
1695 } else { 1777 } else {
1696 SkASSERT(testPath.fPath.getFillType() == SkPath::kWinding_Fi llType); 1778 SkASSERT(testPath.fPath.getFillType() == SkPath::kWinding_Fi llType);
1697 testPath.fPath.setFillType(SkPath::kInverseWinding_FillType) ; 1779 testPath.fPath.setFillType(SkPath::kInverseWinding_FillType) ;
1698 } 1780 }
1699 } 1781 }
1700 const SkPath& path = testPath.fPath; 1782 const SkPath& path = testPath.fPath;
1701 // These tests all assume that the original GrShape for fill and str oke will be the 1783 test_basic(reporter, path);
1702 // same. 1784 test_null_dash(reporter, path);
1703 // However, that is not the case in special cases (e.g. an unclosed rect becomes a RRect 1785 test_path_effect_makes_rrect(reporter, path);
1704 // GrShape with a fill style but becomes a Path GrShape when stroked ). Similarly, a path
1705 // that is a line becomes empty when filled but is special-cased as a line when stroked.
1706 if (testPath.fIsRRectForFill == testPath.fIsRRectForStroke && !testP ath.fIsLine) {
1707 test_basic(reporter, path);
1708 test_null_dash(reporter, path);
1709 test_path_effect_makes_rrect(reporter, path);
1710 }
1711 test_scale(reporter, path); 1786 test_scale(reporter, path);
1712 // This test uses a stroking paint, hence use of fIsRRectForStroke 1787 // This test uses a stroking paint, hence use of fIsRRectForStroke
1713 test_volatile_path(reporter, path, testPath.fIsRRectForStroke || tes tPath.fIsLine); 1788 test_volatile_path(reporter, path, testPath.fIsRRectForStroke || tes tPath.fIsLine);
1714 test_dash_fill(reporter, path); 1789 test_dash_fill(reporter, path);
1715 // Test modifying various stroke params. 1790 // Test modifying various stroke params.
1716 test_stroke_param<SkPath, SkScalar>( 1791 test_stroke_param<SkPath, SkScalar>(
1717 reporter, path, 1792 reporter, path,
1718 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, 1793 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);},
1719 SkIntToScalar(2), SkIntToScalar(4)); 1794 SkIntToScalar(2), SkIntToScalar(4));
1720 test_stroke_join(reporter, path); 1795 test_stroke_join(reporter, path);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1765 test_volatile_path(reporter, SkPath(), true); 1840 test_volatile_path(reporter, SkPath(), true);
1766 1841
1767 test_empty_shape(reporter); 1842 test_empty_shape(reporter);
1768 1843
1769 test_lines(reporter); 1844 test_lines(reporter);
1770 1845
1771 test_stroked_lines(reporter); 1846 test_stroked_lines(reporter);
1772 } 1847 }
1773 1848
1774 #endif 1849 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrShape.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698