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

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: update 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
« src/gpu/GrShape.cpp ('K') | « 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
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
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
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
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
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
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
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
OLDNEW
« src/gpu/GrShape.cpp ('K') | « src/gpu/GrShape.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698