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