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

Side by Side Diff: tests/RoundRectTest.cpp

Issue 52703003: Add SkRRect::transform. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Fix negative scaling bug and add a test. Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « src/core/SkRRect.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 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
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) {
robertphillips 2013/10/31 18:25:26 This comment seems to contradict the code.
scroggo 2013/10/31 19:20:10 Fixed.
458 // The test depends on the fact that the original is 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 // x radii have swapped.
551 REPORTER_ASSERT(reporter, origUL.fX == dstUR.fX);
552 REPORTER_ASSERT(reporter, origUR.fX == dstUL.fX);
553 REPORTER_ASSERT(reporter, origLR.fX == dstLL.fX);
554 REPORTER_ASSERT(reporter, origLL.fX == dstLR.fX);
robertphillips 2013/10/31 18:25:26 Don't think this is right.
scroggo 2013/10/31 19:20:10 The behavior and test have been fixed.
555 // y radii are the same.
556 REPORTER_ASSERT(reporter, origUL.fY == dstUL.fY);
557 REPORTER_ASSERT(reporter, origUR.fY == dstUR.fY);
558 REPORTER_ASSERT(reporter, origLR.fY == dstLR.fY);
559 REPORTER_ASSERT(reporter, origLL.fY == dstLL.fY);
560 }
561 // Width and height remain the same.
562 REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width());
563 REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height());
564 // Right and left have swapped (sort of)
565 REPORTER_ASSERT(reporter, orig.rect().right() == -dst.rect().left());
566 // Top has stayed the same.
567 REPORTER_ASSERT(reporter, orig.rect().top() == dst.rect().top());
568
569 // Keeping the scale, but adding a persp will make transform fail.
570 matrix.setPerspX(SkScalarToPersp(SkIntToScalar(7)));
571 assert_transform_failure(reporter, orig, matrix);
572
573 // Scaling in -y will flip the round rect vertically.
574 matrix.reset();
575 matrix.setScaleY(SkIntToScalar(-1));
576 dst.setEmpty();
577 success = orig.transform(matrix, &dst);
578 REPORTER_ASSERT(reporter, success);
579 {
580 GET_RADII;
robertphillips 2013/10/31 18:25:26 Don't think this is right.
scroggo 2013/10/31 19:20:10 The behavior and test have been fixed.
581 // x radii are the same.
582 REPORTER_ASSERT(reporter, origUL.fX == dstUL.fX);
583 REPORTER_ASSERT(reporter, origUR.fX == dstUR.fX);
584 REPORTER_ASSERT(reporter, origLR.fX == dstLR.fX);
585 REPORTER_ASSERT(reporter, origLL.fX == dstLL.fX);
586 // y radii have swapped.
587 REPORTER_ASSERT(reporter, origUL.fY == dstLL.fY);
588 REPORTER_ASSERT(reporter, origUR.fY == dstLR.fY);
589 REPORTER_ASSERT(reporter, origLR.fY == dstUR.fY);
590 REPORTER_ASSERT(reporter, origLL.fY == dstUL.fY);
591 }
592 // Width and height remain the same.
593 REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width());
594 REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height());
595 // Top and bottom have swapped (sort of)
596 REPORTER_ASSERT(reporter, orig.rect().top() == -dst.rect().bottom());
597 // Left has stayed the same.
598 REPORTER_ASSERT(reporter, orig.rect().left() == dst.rect().left());
599
robertphillips 2013/10/31 18:25:26 Should test simultaneous -x & -y scales.
scroggo 2013/10/31 19:20:10 Done.
600 // Scale in both directions.
601 SkScalar xScale = SkIntToScalar(3);
602 SkScalar yScale = SkFloatToScalar(3.2f);
603 matrix.reset();
604 matrix.setScaleX(xScale);
605 matrix.setScaleY(yScale);
606 dst.setEmpty();
607 success = orig.transform(matrix, &dst);
608 REPORTER_ASSERT(reporter, success);
609 // Radii are scaled.
610 for (int i = 0; i < 4; ++i) {
611 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.radii((SkRRect::Corner ) i).fX,
612 SkScalarMul(orig.radii((SkRRect::Corner) i). fX, xScale)));
613 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.radii((SkRRect::Corner ) i).fY,
614 SkScalarMul(orig.radii((SkRRect::Corner) i). fY, yScale)));
615 }
616 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().width(), SkScalarMu l(orig.rect().width(), xScale)));
617 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().height(), SkScalarM ul(orig.rect().height(), yScale)));
618 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().left(), SkScalarMul (orig.rect().left(), xScale)));
619 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().top(), SkScalarMul( orig.rect().top(), yScale)));
620 }
621
622 static void test_round_rect_transform(skiatest::Reporter* reporter) {
623 SkRRect rrect;
624 {
625 SkRect r = { 0, 0, kWidth, kHeight };
626 rrect.setRectXY(r, SkIntToScalar(4), SkIntToScalar(7));
627 test_transform_helper(reporter, rrect);
628 }
629 {
robertphillips 2013/10/31 18:25:26 This is an awfully short RRect (1 pixel high)?
scroggo 2013/10/31 19:20:10 Taller now.
630 SkRect r = { SkIntToScalar(5), SkIntToScalar(15),
631 SkIntToScalar(27), SkIntToScalar(16) };
632 SkVector radii[4] = { { 0, SkIntToScalar(1) },
633 { SkIntToScalar(2), SkIntToScalar(3) },
634 { SkIntToScalar(4), SkIntToScalar(5) },
635 { SkIntToScalar(6), SkIntToScalar(7) } };
636 rrect.setRectRadii(r, radii);
637 test_transform_helper(reporter, rrect);
638 }
639 }
640
454 static void TestRoundRect(skiatest::Reporter* reporter) { 641 static void TestRoundRect(skiatest::Reporter* reporter) {
455 test_round_rect_basic(reporter); 642 test_round_rect_basic(reporter);
456 test_round_rect_rects(reporter); 643 test_round_rect_rects(reporter);
457 test_round_rect_ovals(reporter); 644 test_round_rect_ovals(reporter);
458 test_round_rect_general(reporter); 645 test_round_rect_general(reporter);
459 test_round_rect_iffy_parameters(reporter); 646 test_round_rect_iffy_parameters(reporter);
460 test_inset(reporter); 647 test_inset(reporter);
461 test_round_rect_contains_rect(reporter); 648 test_round_rect_contains_rect(reporter);
649 test_round_rect_transform(reporter);
462 } 650 }
463 651
464 #include "TestClassDef.h" 652 #include "TestClassDef.h"
465 DEFINE_TESTCLASS("RoundRect", TestRoundRectClass, TestRoundRect) 653 DEFINE_TESTCLASS("RoundRect", TestRoundRectClass, TestRoundRect)
OLDNEW
« no previous file with comments | « src/core/SkRRect.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698