OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "Test.h" | 8 #include "Test.h" |
| 9 #include "SkMatrix.h" |
9 #include "SkRRect.h" | 10 #include "SkRRect.h" |
10 | 11 |
11 static const SkScalar kWidth = 100.0f; | 12 static const SkScalar kWidth = SkFloatToScalar(100.0f); |
12 static const SkScalar kHeight = 100.0f; | 13 static const SkScalar kHeight = SkFloatToScalar(100.0f); |
13 | 14 |
14 static void test_inset(skiatest::Reporter* reporter) { | 15 static void test_inset(skiatest::Reporter* reporter) { |
15 SkRRect rr, rr2; | 16 SkRRect rr, rr2; |
16 SkRect r = { 0, 0, 100, 100 }; | 17 SkRect r = { 0, 0, 100, 100 }; |
17 | 18 |
18 rr.setRect(r); | 19 rr.setRect(r); |
19 rr.inset(-20, -20, &rr2); | 20 rr.inset(-20, -20, &rr2); |
20 REPORTER_ASSERT(reporter, rr2.isRect()); | 21 REPORTER_ASSERT(reporter, rr2.isRect()); |
21 | 22 |
22 rr.inset(20, 20, &rr2); | 23 rr.inset(20, 20, &rr2); |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 test_direction(reporter, rrects[i], 19.5f, 0, 0, 1, kNumSteps, ans
wers[i][1]); // N | 445 test_direction(reporter, rrects[i], 19.5f, 0, 0, 1, kNumSteps, ans
wers[i][1]); // N |
445 test_direction(reporter, rrects[i], 40, -1, 0, 1, kNumSteps, ans
wers[i][2]); // NE | 446 test_direction(reporter, rrects[i], 40, -1, 0, 1, kNumSteps, ans
wers[i][2]); // NE |
446 test_direction(reporter, rrects[i], 40, -1, 19.5f, 0, kNumSteps, ans
wers[i][3]); // E | 447 test_direction(reporter, rrects[i], 40, -1, 19.5f, 0, kNumSteps, ans
wers[i][3]); // E |
447 test_direction(reporter, rrects[i], 40, -1, 40, -1, kNumSteps, ans
wers[i][4]); // SE | 448 test_direction(reporter, rrects[i], 40, -1, 40, -1, kNumSteps, ans
wers[i][4]); // SE |
448 test_direction(reporter, rrects[i], 19.5f, 0, 40, -1, kNumSteps, ans
wers[i][5]); // S | 449 test_direction(reporter, rrects[i], 19.5f, 0, 40, -1, kNumSteps, ans
wers[i][5]); // S |
449 test_direction(reporter, rrects[i], 0, 1, 40, -1, kNumSteps, ans
wers[i][6]); // SW | 450 test_direction(reporter, rrects[i], 0, 1, 40, -1, kNumSteps, ans
wers[i][6]); // SW |
450 test_direction(reporter, rrects[i], 0, 1, 19.5f, 0, kNumSteps, ans
wers[i][7]); // W | 451 test_direction(reporter, rrects[i], 0, 1, 19.5f, 0, kNumSteps, ans
wers[i][7]); // W |
451 } | 452 } |
452 } | 453 } |
453 | 454 |
| 455 // Called for a matrix that should cause SkRRect::transform to fail. |
| 456 static void assert_transform_failure(skiatest::Reporter* reporter, const SkRRect
& orig, |
| 457 const SkMatrix& matrix) { |
| 458 // The test depends on the fact that the original is not empty. |
| 459 SkASSERT(!orig.isEmpty()); |
| 460 SkRRect dst; |
| 461 dst.setEmpty(); |
| 462 |
| 463 const SkRRect copyOfDst = dst; |
| 464 const SkRRect copyOfOrig = orig; |
| 465 bool success = orig.transform(matrix, &dst); |
| 466 // This transform should fail. |
| 467 REPORTER_ASSERT(reporter, !success); |
| 468 // Since the transform failed, dst should be unchanged. |
| 469 REPORTER_ASSERT(reporter, copyOfDst == dst); |
| 470 // original should not be modified. |
| 471 REPORTER_ASSERT(reporter, copyOfOrig == orig); |
| 472 REPORTER_ASSERT(reporter, orig != dst); |
| 473 } |
| 474 |
| 475 #define GET_RADII \ |
| 476 const SkVector& origUL = orig.radii(SkRRect::kUpperLeft_Corner); \ |
| 477 const SkVector& origUR = orig.radii(SkRRect::kUpperRight_Corner); \ |
| 478 const SkVector& origLR = orig.radii(SkRRect::kLowerRight_Corner); \ |
| 479 const SkVector& origLL = orig.radii(SkRRect::kLowerLeft_Corner); \ |
| 480 const SkVector& dstUL = dst.radii(SkRRect::kUpperLeft_Corner); \ |
| 481 const SkVector& dstUR = dst.radii(SkRRect::kUpperRight_Corner); \ |
| 482 const SkVector& dstLR = dst.radii(SkRRect::kLowerRight_Corner); \ |
| 483 const SkVector& dstLL = dst.radii(SkRRect::kLowerLeft_Corner) |
| 484 |
| 485 // Called to test various transforms on a single SkRRect. |
| 486 static void test_transform_helper(skiatest::Reporter* reporter, const SkRRect& o
rig) { |
| 487 SkRRect dst; |
| 488 dst.setEmpty(); |
| 489 |
| 490 // The identity matrix will duplicate the rrect. |
| 491 bool success = orig.transform(SkMatrix::I(), &dst); |
| 492 REPORTER_ASSERT(reporter, success); |
| 493 REPORTER_ASSERT(reporter, orig == dst); |
| 494 |
| 495 // Skew and Perspective make transform fail. |
| 496 SkMatrix matrix; |
| 497 matrix.reset(); |
| 498 matrix.setSkewX(SkIntToScalar(2)); |
| 499 assert_transform_failure(reporter, orig, matrix); |
| 500 |
| 501 matrix.reset(); |
| 502 matrix.setSkewY(SkIntToScalar(3)); |
| 503 assert_transform_failure(reporter, orig, matrix); |
| 504 |
| 505 matrix.reset(); |
| 506 matrix.setPerspX(SkScalarToPersp(SkIntToScalar(4))); |
| 507 assert_transform_failure(reporter, orig, matrix); |
| 508 |
| 509 matrix.reset(); |
| 510 matrix.setPerspY(SkScalarToPersp(SkIntToScalar(5))); |
| 511 assert_transform_failure(reporter, orig, matrix); |
| 512 |
| 513 // Rotation fails. |
| 514 matrix.reset(); |
| 515 matrix.setRotate(SkIntToScalar(90)); |
| 516 assert_transform_failure(reporter, orig, matrix); |
| 517 matrix.setRotate(SkIntToScalar(37)); |
| 518 assert_transform_failure(reporter, orig, matrix); |
| 519 |
| 520 // Translate will keep the rect moved, but otherwise the same. |
| 521 matrix.reset(); |
| 522 SkScalar translateX = SkIntToScalar(32); |
| 523 SkScalar translateY = SkIntToScalar(15); |
| 524 matrix.setTranslateX(translateX); |
| 525 matrix.setTranslateY(translateY); |
| 526 dst.setEmpty(); |
| 527 success = orig.transform(matrix, &dst); |
| 528 REPORTER_ASSERT(reporter, success); |
| 529 for (int i = 0; i < 4; ++i) { |
| 530 REPORTER_ASSERT(reporter, |
| 531 orig.radii((SkRRect::Corner) i) == dst.radii((SkRRect::Corner) i
)); |
| 532 } |
| 533 REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width()); |
| 534 REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height()); |
| 535 REPORTER_ASSERT(reporter, dst.rect().left() == orig.rect().left() + translat
eX); |
| 536 REPORTER_ASSERT(reporter, dst.rect().top() == orig.rect().top() + translateY
); |
| 537 |
| 538 // Keeping the translation, but adding skew will make transform fail. |
| 539 matrix.setSkewY(SkIntToScalar(7)); |
| 540 assert_transform_failure(reporter, orig, matrix); |
| 541 |
| 542 // Scaling in -x will flip the round rect horizontally. |
| 543 matrix.reset(); |
| 544 matrix.setScaleX(SkIntToScalar(-1)); |
| 545 dst.setEmpty(); |
| 546 success = orig.transform(matrix, &dst); |
| 547 REPORTER_ASSERT(reporter, success); |
| 548 { |
| 549 GET_RADII; |
| 550 // Radii have swapped in x. |
| 551 REPORTER_ASSERT(reporter, origUL == dstUR); |
| 552 REPORTER_ASSERT(reporter, origUR == dstUL); |
| 553 REPORTER_ASSERT(reporter, origLR == dstLL); |
| 554 REPORTER_ASSERT(reporter, origLL == dstLR); |
| 555 } |
| 556 // Width and height remain the same. |
| 557 REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width()); |
| 558 REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height()); |
| 559 // Right and left have swapped (sort of) |
| 560 REPORTER_ASSERT(reporter, orig.rect().right() == -dst.rect().left()); |
| 561 // Top has stayed the same. |
| 562 REPORTER_ASSERT(reporter, orig.rect().top() == dst.rect().top()); |
| 563 |
| 564 // Keeping the scale, but adding a persp will make transform fail. |
| 565 matrix.setPerspX(SkScalarToPersp(SkIntToScalar(7))); |
| 566 assert_transform_failure(reporter, orig, matrix); |
| 567 |
| 568 // Scaling in -y will flip the round rect vertically. |
| 569 matrix.reset(); |
| 570 matrix.setScaleY(SkIntToScalar(-1)); |
| 571 dst.setEmpty(); |
| 572 success = orig.transform(matrix, &dst); |
| 573 REPORTER_ASSERT(reporter, success); |
| 574 { |
| 575 GET_RADII; |
| 576 // Radii have swapped in y. |
| 577 REPORTER_ASSERT(reporter, origUL == dstLL); |
| 578 REPORTER_ASSERT(reporter, origUR == dstLR); |
| 579 REPORTER_ASSERT(reporter, origLR == dstUR); |
| 580 REPORTER_ASSERT(reporter, origLL == dstUL); |
| 581 } |
| 582 // Width and height remain the same. |
| 583 REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width()); |
| 584 REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height()); |
| 585 // Top and bottom have swapped (sort of) |
| 586 REPORTER_ASSERT(reporter, orig.rect().top() == -dst.rect().bottom()); |
| 587 // Left has stayed the same. |
| 588 REPORTER_ASSERT(reporter, orig.rect().left() == dst.rect().left()); |
| 589 |
| 590 // Scaling in -x and -y will swap in both directions. |
| 591 matrix.reset(); |
| 592 matrix.setScaleY(SkIntToScalar(-1)); |
| 593 matrix.setScaleX(SkIntToScalar(-1)); |
| 594 dst.setEmpty(); |
| 595 success = orig.transform(matrix, &dst); |
| 596 REPORTER_ASSERT(reporter, success); |
| 597 { |
| 598 GET_RADII; |
| 599 REPORTER_ASSERT(reporter, origUL == dstLR); |
| 600 REPORTER_ASSERT(reporter, origUR == dstLL); |
| 601 REPORTER_ASSERT(reporter, origLR == dstUL); |
| 602 REPORTER_ASSERT(reporter, origLL == dstUR); |
| 603 } |
| 604 // Width and height remain the same. |
| 605 REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width()); |
| 606 REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height()); |
| 607 REPORTER_ASSERT(reporter, orig.rect().top() == -dst.rect().bottom()); |
| 608 REPORTER_ASSERT(reporter, orig.rect().right() == -dst.rect().left()); |
| 609 |
| 610 // Scale in both directions. |
| 611 SkScalar xScale = SkIntToScalar(3); |
| 612 SkScalar yScale = SkFloatToScalar(3.2f); |
| 613 matrix.reset(); |
| 614 matrix.setScaleX(xScale); |
| 615 matrix.setScaleY(yScale); |
| 616 dst.setEmpty(); |
| 617 success = orig.transform(matrix, &dst); |
| 618 REPORTER_ASSERT(reporter, success); |
| 619 // Radii are scaled. |
| 620 for (int i = 0; i < 4; ++i) { |
| 621 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.radii((SkRRect::Corner
) i).fX, |
| 622 SkScalarMul(orig.radii((SkRRect::Corner) i).
fX, xScale))); |
| 623 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.radii((SkRRect::Corner
) i).fY, |
| 624 SkScalarMul(orig.radii((SkRRect::Corner) i).
fY, yScale))); |
| 625 } |
| 626 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().width(), |
| 627 SkScalarMul(orig.rect().width(
), xScale))); |
| 628 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().height(), |
| 629 SkScalarMul(orig.rect().height
(), yScale))); |
| 630 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().left(), |
| 631 SkScalarMul(orig.rect().left()
, xScale))); |
| 632 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().top(), |
| 633 SkScalarMul(orig.rect().top(),
yScale))); |
| 634 } |
| 635 |
| 636 static void test_round_rect_transform(skiatest::Reporter* reporter) { |
| 637 SkRRect rrect; |
| 638 { |
| 639 SkRect r = { 0, 0, kWidth, kHeight }; |
| 640 rrect.setRectXY(r, SkIntToScalar(4), SkIntToScalar(7)); |
| 641 test_transform_helper(reporter, rrect); |
| 642 } |
| 643 { |
| 644 SkRect r = { SkIntToScalar(5), SkIntToScalar(15), |
| 645 SkIntToScalar(27), SkIntToScalar(34) }; |
| 646 SkVector radii[4] = { { 0, SkIntToScalar(1) }, |
| 647 { SkIntToScalar(2), SkIntToScalar(3) }, |
| 648 { SkIntToScalar(4), SkIntToScalar(5) }, |
| 649 { SkIntToScalar(6), SkIntToScalar(7) } }; |
| 650 rrect.setRectRadii(r, radii); |
| 651 test_transform_helper(reporter, rrect); |
| 652 } |
| 653 } |
| 654 |
454 static void TestRoundRect(skiatest::Reporter* reporter) { | 655 static void TestRoundRect(skiatest::Reporter* reporter) { |
455 test_round_rect_basic(reporter); | 656 test_round_rect_basic(reporter); |
456 test_round_rect_rects(reporter); | 657 test_round_rect_rects(reporter); |
457 test_round_rect_ovals(reporter); | 658 test_round_rect_ovals(reporter); |
458 test_round_rect_general(reporter); | 659 test_round_rect_general(reporter); |
459 test_round_rect_iffy_parameters(reporter); | 660 test_round_rect_iffy_parameters(reporter); |
460 test_inset(reporter); | 661 test_inset(reporter); |
461 test_round_rect_contains_rect(reporter); | 662 test_round_rect_contains_rect(reporter); |
| 663 test_round_rect_transform(reporter); |
462 } | 664 } |
463 | 665 |
464 #include "TestClassDef.h" | 666 #include "TestClassDef.h" |
465 DEFINE_TESTCLASS("RoundRect", TestRoundRectClass, TestRoundRect) | 667 DEFINE_TESTCLASS("RoundRect", TestRoundRectClass, TestRoundRect) |
OLD | NEW |