Index: tests/RoundRectTest.cpp |
diff --git a/tests/RoundRectTest.cpp b/tests/RoundRectTest.cpp |
index 93f5e7d20fdca268efd320352b24f10b8024afac..bd533de23cf2fecd6bbd9893a2db46fc6edd7260 100644 |
--- a/tests/RoundRectTest.cpp |
+++ b/tests/RoundRectTest.cpp |
@@ -6,10 +6,11 @@ |
*/ |
#include "Test.h" |
+#include "SkMatrix.h" |
#include "SkRRect.h" |
-static const SkScalar kWidth = 100.0f; |
-static const SkScalar kHeight = 100.0f; |
+static const SkScalar kWidth = SkFloatToScalar(100.0f); |
+static const SkScalar kHeight = SkFloatToScalar(100.0f); |
static void test_inset(skiatest::Reporter* reporter) { |
SkRRect rr, rr2; |
@@ -451,6 +452,192 @@ static void test_round_rect_contains_rect(skiatest::Reporter* reporter) { |
} |
} |
+// Called for a matrix that should cause SkRRect::transform to fail. |
+static void assert_transform_failure(skiatest::Reporter* reporter, const SkRRect& orig, |
+ 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.
|
+ // The test depends on the fact that the original is empty. |
+ SkASSERT(!orig.isEmpty()); |
+ SkRRect dst; |
+ dst.setEmpty(); |
+ |
+ const SkRRect copyOfDst = dst; |
+ const SkRRect copyOfOrig = orig; |
+ bool success = orig.transform(matrix, &dst); |
+ // This transform should fail. |
+ REPORTER_ASSERT(reporter, !success); |
+ // Since the transform failed, dst should be unchanged. |
+ REPORTER_ASSERT(reporter, copyOfDst == dst); |
+ // original should not be modified. |
+ REPORTER_ASSERT(reporter, copyOfOrig == orig); |
+ REPORTER_ASSERT(reporter, orig != dst); |
+} |
+ |
+#define GET_RADII \ |
+ const SkVector& origUL = orig.radii(SkRRect::kUpperLeft_Corner); \ |
+ const SkVector& origUR = orig.radii(SkRRect::kUpperRight_Corner); \ |
+ const SkVector& origLR = orig.radii(SkRRect::kLowerRight_Corner); \ |
+ const SkVector& origLL = orig.radii(SkRRect::kLowerLeft_Corner); \ |
+ const SkVector& dstUL = dst.radii(SkRRect::kUpperLeft_Corner); \ |
+ const SkVector& dstUR = dst.radii(SkRRect::kUpperRight_Corner); \ |
+ const SkVector& dstLR = dst.radii(SkRRect::kLowerRight_Corner); \ |
+ const SkVector& dstLL = dst.radii(SkRRect::kLowerLeft_Corner) |
+ |
+// Called to test various transforms on a single SkRRect. |
+static void test_transform_helper(skiatest::Reporter* reporter, const SkRRect& orig) { |
+ SkRRect dst; |
+ dst.setEmpty(); |
+ |
+ // The identity matrix will duplicate the rrect. |
+ bool success = orig.transform(SkMatrix::I(), &dst); |
+ REPORTER_ASSERT(reporter, success); |
+ REPORTER_ASSERT(reporter, orig == dst); |
+ |
+ // Skew and Perspective make transform fail. |
+ SkMatrix matrix; |
+ matrix.reset(); |
+ matrix.setSkewX(SkIntToScalar(2)); |
+ assert_transform_failure(reporter, orig, matrix); |
+ |
+ matrix.reset(); |
+ matrix.setSkewY(SkIntToScalar(3)); |
+ assert_transform_failure(reporter, orig, matrix); |
+ |
+ matrix.reset(); |
+ matrix.setPerspX(SkScalarToPersp(SkIntToScalar(4))); |
+ assert_transform_failure(reporter, orig, matrix); |
+ |
+ matrix.reset(); |
+ matrix.setPerspY(SkScalarToPersp(SkIntToScalar(5))); |
+ assert_transform_failure(reporter, orig, matrix); |
+ |
+ // Rotation fails. |
+ matrix.reset(); |
+ matrix.setRotate(SkIntToScalar(90)); |
+ assert_transform_failure(reporter, orig, matrix); |
+ matrix.setRotate(SkIntToScalar(37)); |
+ assert_transform_failure(reporter, orig, matrix); |
+ |
+ // Translate will keep the rect moved, but otherwise the same. |
+ matrix.reset(); |
+ SkScalar translateX = SkIntToScalar(32); |
+ SkScalar translateY = SkIntToScalar(15); |
+ matrix.setTranslateX(translateX); |
+ matrix.setTranslateY(translateY); |
+ dst.setEmpty(); |
+ success = orig.transform(matrix, &dst); |
+ REPORTER_ASSERT(reporter, success); |
+ for (int i = 0; i < 4; ++i) { |
+ REPORTER_ASSERT(reporter, |
+ orig.radii((SkRRect::Corner) i) == dst.radii((SkRRect::Corner) i)); |
+ } |
+ REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width()); |
+ REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height()); |
+ REPORTER_ASSERT(reporter, dst.rect().left() == orig.rect().left() + translateX); |
+ REPORTER_ASSERT(reporter, dst.rect().top() == orig.rect().top() + translateY); |
+ |
+ // Keeping the translation, but adding skew will make transform fail. |
+ matrix.setSkewY(SkIntToScalar(7)); |
+ assert_transform_failure(reporter, orig, matrix); |
+ |
+ // Scaling in -x will flip the round rect horizontally. |
+ matrix.reset(); |
+ matrix.setScaleX(SkIntToScalar(-1)); |
+ dst.setEmpty(); |
+ success = orig.transform(matrix, &dst); |
+ REPORTER_ASSERT(reporter, success); |
+ { |
+ GET_RADII; |
+ // x radii have swapped. |
+ REPORTER_ASSERT(reporter, origUL.fX == dstUR.fX); |
+ REPORTER_ASSERT(reporter, origUR.fX == dstUL.fX); |
+ REPORTER_ASSERT(reporter, origLR.fX == dstLL.fX); |
+ 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.
|
+ // y radii are the same. |
+ REPORTER_ASSERT(reporter, origUL.fY == dstUL.fY); |
+ REPORTER_ASSERT(reporter, origUR.fY == dstUR.fY); |
+ REPORTER_ASSERT(reporter, origLR.fY == dstLR.fY); |
+ REPORTER_ASSERT(reporter, origLL.fY == dstLL.fY); |
+ } |
+ // Width and height remain the same. |
+ REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width()); |
+ REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height()); |
+ // Right and left have swapped (sort of) |
+ REPORTER_ASSERT(reporter, orig.rect().right() == -dst.rect().left()); |
+ // Top has stayed the same. |
+ REPORTER_ASSERT(reporter, orig.rect().top() == dst.rect().top()); |
+ |
+ // Keeping the scale, but adding a persp will make transform fail. |
+ matrix.setPerspX(SkScalarToPersp(SkIntToScalar(7))); |
+ assert_transform_failure(reporter, orig, matrix); |
+ |
+ // Scaling in -y will flip the round rect vertically. |
+ matrix.reset(); |
+ matrix.setScaleY(SkIntToScalar(-1)); |
+ dst.setEmpty(); |
+ success = orig.transform(matrix, &dst); |
+ REPORTER_ASSERT(reporter, success); |
+ { |
+ 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.
|
+ // x radii are the same. |
+ REPORTER_ASSERT(reporter, origUL.fX == dstUL.fX); |
+ REPORTER_ASSERT(reporter, origUR.fX == dstUR.fX); |
+ REPORTER_ASSERT(reporter, origLR.fX == dstLR.fX); |
+ REPORTER_ASSERT(reporter, origLL.fX == dstLL.fX); |
+ // y radii have swapped. |
+ REPORTER_ASSERT(reporter, origUL.fY == dstLL.fY); |
+ REPORTER_ASSERT(reporter, origUR.fY == dstLR.fY); |
+ REPORTER_ASSERT(reporter, origLR.fY == dstUR.fY); |
+ REPORTER_ASSERT(reporter, origLL.fY == dstUL.fY); |
+ } |
+ // Width and height remain the same. |
+ REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width()); |
+ REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height()); |
+ // Top and bottom have swapped (sort of) |
+ REPORTER_ASSERT(reporter, orig.rect().top() == -dst.rect().bottom()); |
+ // Left has stayed the same. |
+ REPORTER_ASSERT(reporter, orig.rect().left() == dst.rect().left()); |
+ |
robertphillips
2013/10/31 18:25:26
Should test simultaneous -x & -y scales.
scroggo
2013/10/31 19:20:10
Done.
|
+ // Scale in both directions. |
+ SkScalar xScale = SkIntToScalar(3); |
+ SkScalar yScale = SkFloatToScalar(3.2f); |
+ matrix.reset(); |
+ matrix.setScaleX(xScale); |
+ matrix.setScaleY(yScale); |
+ dst.setEmpty(); |
+ success = orig.transform(matrix, &dst); |
+ REPORTER_ASSERT(reporter, success); |
+ // Radii are scaled. |
+ for (int i = 0; i < 4; ++i) { |
+ REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.radii((SkRRect::Corner) i).fX, |
+ SkScalarMul(orig.radii((SkRRect::Corner) i).fX, xScale))); |
+ REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.radii((SkRRect::Corner) i).fY, |
+ SkScalarMul(orig.radii((SkRRect::Corner) i).fY, yScale))); |
+ } |
+ REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().width(), SkScalarMul(orig.rect().width(), xScale))); |
+ REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().height(), SkScalarMul(orig.rect().height(), yScale))); |
+ REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().left(), SkScalarMul(orig.rect().left(), xScale))); |
+ REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().top(), SkScalarMul(orig.rect().top(), yScale))); |
+} |
+ |
+static void test_round_rect_transform(skiatest::Reporter* reporter) { |
+ SkRRect rrect; |
+ { |
+ SkRect r = { 0, 0, kWidth, kHeight }; |
+ rrect.setRectXY(r, SkIntToScalar(4), SkIntToScalar(7)); |
+ test_transform_helper(reporter, rrect); |
+ } |
+ { |
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.
|
+ SkRect r = { SkIntToScalar(5), SkIntToScalar(15), |
+ SkIntToScalar(27), SkIntToScalar(16) }; |
+ SkVector radii[4] = { { 0, SkIntToScalar(1) }, |
+ { SkIntToScalar(2), SkIntToScalar(3) }, |
+ { SkIntToScalar(4), SkIntToScalar(5) }, |
+ { SkIntToScalar(6), SkIntToScalar(7) } }; |
+ rrect.setRectRadii(r, radii); |
+ test_transform_helper(reporter, rrect); |
+ } |
+} |
+ |
static void TestRoundRect(skiatest::Reporter* reporter) { |
test_round_rect_basic(reporter); |
test_round_rect_rects(reporter); |
@@ -459,6 +646,7 @@ static void TestRoundRect(skiatest::Reporter* reporter) { |
test_round_rect_iffy_parameters(reporter); |
test_inset(reporter); |
test_round_rect_contains_rect(reporter); |
+ test_round_rect_transform(reporter); |
} |
#include "TestClassDef.h" |