robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2012 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | #include "Test.h" |
| 9 | #include "SkRRect.h" |
| 10 | |
| 11 | static const SkScalar kWidth = 100.0f; |
| 12 | static const SkScalar kHeight = 100.0f; |
| 13 | |
| 14 | // Test out the basic API entry points |
| 15 | static void test_round_rect_basic(skiatest::Reporter* reporter) { |
| 16 | // Test out initialization methods |
| 17 | SkPoint zeroPt = { 0.0, 0.0 }; |
| 18 | SkRRect empty; |
skia.committer@gmail.com | c3d7d90 | 2012-11-30 02:01:24 +0000 | [diff] [blame] | 19 | |
robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 20 | empty.setEmpty(); |
| 21 | |
| 22 | REPORTER_ASSERT(reporter, SkRRect::kEmpty_Type == empty.type()); |
| 23 | REPORTER_ASSERT(reporter, empty.rect().isEmpty()); |
| 24 | |
| 25 | for (int i = 0; i < 4; ++i) { |
| 26 | REPORTER_ASSERT(reporter, zeroPt == empty.radii((SkRRect::Corner) i)); |
| 27 | } |
| 28 | |
| 29 | //---- |
| 30 | SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); |
| 31 | |
| 32 | SkRRect rr1; |
| 33 | rr1.setRect(rect); |
| 34 | |
| 35 | REPORTER_ASSERT(reporter, SkRRect::kRect_Type == rr1.type()); |
| 36 | REPORTER_ASSERT(reporter, rr1.rect() == rect); |
| 37 | |
| 38 | for (int i = 0; i < 4; ++i) { |
| 39 | REPORTER_ASSERT(reporter, zeroPt == rr1.radii((SkRRect::Corner) i)); |
| 40 | } |
| 41 | |
| 42 | //---- |
| 43 | SkPoint halfPoint = { SkScalarHalf(kWidth), SkScalarHalf(kHeight) }; |
| 44 | SkRRect rr2; |
| 45 | rr2.setOval(rect); |
| 46 | |
| 47 | REPORTER_ASSERT(reporter, SkRRect::kOval_Type == rr2.type()); |
| 48 | REPORTER_ASSERT(reporter, rr2.rect() == rect); |
| 49 | |
| 50 | for (int i = 0; i < 4; ++i) { |
skia.committer@gmail.com | c3d7d90 | 2012-11-30 02:01:24 +0000 | [diff] [blame] | 51 | REPORTER_ASSERT(reporter, |
robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 52 | rr2.radii((SkRRect::Corner) i).equalsWithinTolerance(halfPoint)); |
| 53 | } |
| 54 | |
| 55 | //---- |
| 56 | SkPoint p = { 5, 5 }; |
| 57 | SkRRect rr3; |
| 58 | rr3.setRectXY(rect, p.fX, p.fY); |
| 59 | |
| 60 | REPORTER_ASSERT(reporter, SkRRect::kSimple_Type == rr3.type()); |
| 61 | REPORTER_ASSERT(reporter, rr3.rect() == rect); |
| 62 | |
| 63 | for (int i = 0; i < 4; ++i) { |
| 64 | REPORTER_ASSERT(reporter, p == rr3.radii((SkRRect::Corner) i)); |
| 65 | } |
skia.committer@gmail.com | c3d7d90 | 2012-11-30 02:01:24 +0000 | [diff] [blame] | 66 | |
robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 67 | //---- |
| 68 | SkPoint radii[4] = { { 5, 5 }, { 5, 5 }, { 5, 5 }, { 5, 5 } }; |
| 69 | |
| 70 | SkRRect rr4; |
| 71 | rr4.setRectRadii(rect, radii); |
| 72 | |
| 73 | REPORTER_ASSERT(reporter, SkRRect::kSimple_Type == rr4.type()); |
| 74 | REPORTER_ASSERT(reporter, rr4.rect() == rect); |
| 75 | |
| 76 | for (int i = 0; i < 4; ++i) { |
| 77 | REPORTER_ASSERT(reporter, radii[i] == rr4.radii((SkRRect::Corner) i)); |
| 78 | } |
| 79 | |
| 80 | //---- |
| 81 | SkPoint radii2[4] = { { 0, 0 }, { 0, 0 }, { 50, 50 }, { 20, 50 } }; |
| 82 | |
| 83 | SkRRect rr5; |
| 84 | rr5.setRectRadii(rect, radii2); |
| 85 | |
| 86 | REPORTER_ASSERT(reporter, SkRRect::kComplex_Type == rr5.type()); |
| 87 | REPORTER_ASSERT(reporter, rr5.rect() == rect); |
| 88 | |
| 89 | for (int i = 0; i < 4; ++i) { |
| 90 | REPORTER_ASSERT(reporter, radii2[i] == rr5.radii((SkRRect::Corner) i)); |
| 91 | } |
| 92 | |
| 93 | // Test out == & != |
| 94 | REPORTER_ASSERT(reporter, empty != rr3); |
| 95 | REPORTER_ASSERT(reporter, rr3 == rr4); |
| 96 | REPORTER_ASSERT(reporter, rr4 != rr5); |
| 97 | } |
| 98 | |
| 99 | // Test out the cases when the RR degenerates to a rect |
| 100 | static void test_round_rect_rects(skiatest::Reporter* reporter) { |
| 101 | SkRect r; |
skia.committer@gmail.com | c3d7d90 | 2012-11-30 02:01:24 +0000 | [diff] [blame] | 102 | static const SkPoint pts[] = { |
robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 103 | // Upper Left |
| 104 | { -SK_Scalar1, -SK_Scalar1 }, // out |
| 105 | { SK_Scalar1, SK_Scalar1 }, // in |
| 106 | // Upper Right |
| 107 | { SkIntToScalar(101), -SK_Scalar1}, // out |
| 108 | { SkIntToScalar(99), SK_Scalar1 }, // in |
| 109 | // Lower Right |
| 110 | { SkIntToScalar(101), SkIntToScalar(101) }, // out |
| 111 | { SkIntToScalar(99), SkIntToScalar(99) }, // in |
| 112 | // Lower Left |
| 113 | { -SK_Scalar1, SkIntToScalar(101) }, // out |
| 114 | { SK_Scalar1, SkIntToScalar(99) }, // in |
| 115 | // Middle |
| 116 | { SkIntToScalar(50), SkIntToScalar(50) } // in |
| 117 | }; |
| 118 | static const bool isIn[] = { false, true, false, true, false, true, false, true, true }; |
| 119 | |
| 120 | SkASSERT(SK_ARRAY_COUNT(pts) == SK_ARRAY_COUNT(isIn)); |
| 121 | |
| 122 | //---- |
| 123 | SkRRect empty; |
skia.committer@gmail.com | c3d7d90 | 2012-11-30 02:01:24 +0000 | [diff] [blame] | 124 | |
robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 125 | empty.setEmpty(); |
| 126 | |
| 127 | REPORTER_ASSERT(reporter, SkRRect::kEmpty_Type == empty.type()); |
| 128 | r = empty.rect(); |
| 129 | REPORTER_ASSERT(reporter, 0 == r.fLeft && 0 == r.fTop && 0 == r.fRight && 0 == r.fBottom); |
| 130 | |
| 131 | //---- |
| 132 | SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); |
| 133 | SkRRect rr1; |
| 134 | rr1.setRectXY(rect, 0, 0); |
| 135 | |
| 136 | REPORTER_ASSERT(reporter, SkRRect::kRect_Type == rr1.type()); |
| 137 | r = rr1.rect(); |
| 138 | REPORTER_ASSERT(reporter, rect == r); |
| 139 | for (int i = 0; i < SK_ARRAY_COUNT(pts); ++i) { |
| 140 | REPORTER_ASSERT(reporter, isIn[i] == rr1.contains(pts[i].fX, pts[i].fY)); |
| 141 | } |
| 142 | |
| 143 | //---- |
| 144 | SkPoint radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; |
| 145 | |
| 146 | SkRRect rr2; |
| 147 | rr2.setRectRadii(rect, radii); |
| 148 | |
| 149 | REPORTER_ASSERT(reporter, SkRRect::kRect_Type == rr2.type()); |
| 150 | r = rr2.rect(); |
| 151 | REPORTER_ASSERT(reporter, rect == r); |
| 152 | for (int i = 0; i < SK_ARRAY_COUNT(pts); ++i) { |
| 153 | REPORTER_ASSERT(reporter, isIn[i] == rr2.contains(pts[i].fX, pts[i].fY)); |
| 154 | } |
| 155 | |
| 156 | //---- |
| 157 | SkPoint radii2[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } }; |
| 158 | |
| 159 | SkRRect rr3; |
| 160 | rr3.setRectRadii(rect, radii2); |
| 161 | REPORTER_ASSERT(reporter, SkRRect::kComplex_Type == rr3.type()); |
| 162 | } |
| 163 | |
| 164 | // Test out the cases when the RR degenerates to an oval |
| 165 | static void test_round_rect_ovals(skiatest::Reporter* reporter) { |
| 166 | static const SkScalar kEps = 0.1f; |
| 167 | static const SkScalar kWidthTol = SkScalarHalf(kWidth) * (SK_Scalar1 - SK_ScalarRoot2Over2); |
| 168 | static const SkScalar kHeightTol = SkScalarHalf(kHeight) * (SK_Scalar1 - SK_ScalarRoot2Over2); |
skia.committer@gmail.com | c3d7d90 | 2012-11-30 02:01:24 +0000 | [diff] [blame] | 169 | static const SkPoint pts[] = { |
robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 170 | // Upper Left |
| 171 | { kWidthTol - kEps, kHeightTol - kEps }, // out |
| 172 | { kWidthTol + kEps, kHeightTol + kEps }, // in |
| 173 | // Upper Right |
| 174 | { kWidth + kEps - kWidthTol, kHeightTol - kEps }, // out |
| 175 | { kWidth - kEps - kWidthTol, kHeightTol + kEps }, // in |
| 176 | // Lower Right |
| 177 | { kWidth + kEps - kWidthTol, kHeight + kEps - kHeightTol }, // out |
| 178 | { kWidth - kEps - kWidthTol, kHeight - kEps - kHeightTol }, // in |
| 179 | // Lower Left |
| 180 | { kWidthTol - kEps, kHeight + kEps - kHeightTol }, //out |
| 181 | { kWidthTol + kEps, kHeight - kEps - kHeightTol }, // in |
| 182 | // Middle |
| 183 | { SkIntToScalar(50), SkIntToScalar(50) } // in |
| 184 | }; |
| 185 | static const bool isIn[] = { false, true, false, true, false, true, false, true, true }; |
| 186 | |
| 187 | SkASSERT(SK_ARRAY_COUNT(pts) == SK_ARRAY_COUNT(isIn)); |
| 188 | |
| 189 | //---- |
| 190 | SkRect oval; |
| 191 | SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); |
| 192 | SkRRect rr1; |
| 193 | rr1.setRectXY(rect, SkScalarHalf(kWidth), SkScalarHalf(kHeight)); |
| 194 | |
| 195 | REPORTER_ASSERT(reporter, SkRRect::kOval_Type == rr1.type()); |
| 196 | oval = rr1.rect(); |
| 197 | REPORTER_ASSERT(reporter, oval == rect); |
| 198 | for (int i = 0; i < SK_ARRAY_COUNT(pts); ++i) { |
| 199 | REPORTER_ASSERT(reporter, isIn[i] == rr1.contains(pts[i].fX, pts[i].fY)); |
| 200 | } |
| 201 | } |
| 202 | |
| 203 | // Test out the non-degenerate RR cases |
| 204 | static void test_round_rect_general(skiatest::Reporter* reporter) { |
| 205 | static const SkScalar kEps = 0.1f; |
| 206 | static const SkScalar kDist20 = 20 * (SK_Scalar1 - SK_ScalarRoot2Over2); |
skia.committer@gmail.com | c3d7d90 | 2012-11-30 02:01:24 +0000 | [diff] [blame] | 207 | static const SkPoint pts[] = { |
robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 208 | // Upper Left |
| 209 | { kDist20 - kEps, kDist20 - kEps }, // out |
| 210 | { kDist20 + kEps, kDist20 + kEps }, // in |
| 211 | // Upper Right |
| 212 | { kWidth + kEps - kDist20, kDist20 - kEps }, // out |
| 213 | { kWidth - kEps - kDist20, kDist20 + kEps }, // in |
| 214 | // Lower Right |
| 215 | { kWidth + kEps - kDist20, kHeight + kEps - kDist20 }, // out |
| 216 | { kWidth - kEps - kDist20, kHeight - kEps - kDist20 }, // in |
| 217 | // Lower Left |
| 218 | { kDist20 - kEps, kHeight + kEps - kDist20 }, //out |
| 219 | { kDist20 + kEps, kHeight - kEps - kDist20 }, // in |
| 220 | // Middle |
| 221 | { SkIntToScalar(50), SkIntToScalar(50) } // in |
| 222 | }; |
| 223 | static const bool isIn[] = { false, true, false, true, false, true, false, true, true }; |
| 224 | |
| 225 | SkASSERT(SK_ARRAY_COUNT(pts) == SK_ARRAY_COUNT(isIn)); |
| 226 | |
| 227 | //---- |
| 228 | SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); |
| 229 | SkRRect rr1; |
| 230 | rr1.setRectXY(rect, 20, 20); |
| 231 | |
| 232 | REPORTER_ASSERT(reporter, SkRRect::kSimple_Type == rr1.type()); |
| 233 | for (int i = 0; i < SK_ARRAY_COUNT(pts); ++i) { |
| 234 | REPORTER_ASSERT(reporter, isIn[i] == rr1.contains(pts[i].fX, pts[i].fY)); |
| 235 | } |
| 236 | |
| 237 | //---- |
| 238 | static const SkScalar kDist50 = 50*(SK_Scalar1 - SK_ScalarRoot2Over2); |
skia.committer@gmail.com | c3d7d90 | 2012-11-30 02:01:24 +0000 | [diff] [blame] | 239 | static const SkPoint pts2[] = { |
robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 240 | // Upper Left |
| 241 | { -SK_Scalar1, -SK_Scalar1 }, // out |
| 242 | { SK_Scalar1, SK_Scalar1 }, // in |
| 243 | // Upper Right |
| 244 | { kWidth + kEps - kDist20, kDist20 - kEps }, // out |
| 245 | { kWidth - kEps - kDist20, kDist20 + kEps }, // in |
| 246 | // Lower Right |
| 247 | { kWidth + kEps - kDist50, kHeight + kEps - kDist50 }, // out |
| 248 | { kWidth - kEps - kDist50, kHeight - kEps - kDist50 }, // in |
| 249 | // Lower Left |
| 250 | { kDist20 - kEps, kHeight + kEps - kDist50 }, // out |
| 251 | { kDist20 + kEps, kHeight - kEps - kDist50 }, // in |
| 252 | // Middle |
| 253 | { SkIntToScalar(50), SkIntToScalar(50) } // in |
| 254 | }; |
| 255 | |
| 256 | SkASSERT(SK_ARRAY_COUNT(pts2) == SK_ARRAY_COUNT(isIn)); |
| 257 | |
| 258 | SkPoint radii[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } }; |
| 259 | |
| 260 | SkRRect rr2; |
| 261 | rr2.setRectRadii(rect, radii); |
| 262 | |
| 263 | REPORTER_ASSERT(reporter, SkRRect::kComplex_Type == rr2.type()); |
| 264 | for (int i = 0; i < SK_ARRAY_COUNT(pts); ++i) { |
| 265 | REPORTER_ASSERT(reporter, isIn[i] == rr2.contains(pts2[i].fX, pts2[i].fY)); |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | // Test out questionable-parameter handling |
| 270 | static void test_round_rect_iffy_parameters(skiatest::Reporter* reporter) { |
| 271 | |
| 272 | // When the radii exceed the base rect they are proportionally scaled down |
| 273 | // to fit |
| 274 | SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); |
| 275 | SkPoint radii[4] = { { 50, 100 }, { 100, 50 }, { 50, 100 }, { 100, 50 } }; |
| 276 | |
| 277 | SkRRect rr1; |
| 278 | rr1.setRectRadii(rect, radii); |
| 279 | |
| 280 | REPORTER_ASSERT(reporter, SkRRect::kComplex_Type == rr1.type()); |
| 281 | |
| 282 | const SkPoint& p = rr1.radii(SkRRect::kUpperLeft_Corner); |
| 283 | |
| 284 | REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.fX, 33.33333f)); |
| 285 | REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.fY, 66.66666f)); |
| 286 | |
| 287 | // Negative radii should be capped at zero |
| 288 | SkRRect rr2; |
| 289 | rr2.setRectXY(rect, -10, -20); |
| 290 | |
| 291 | REPORTER_ASSERT(reporter, SkRRect::kRect_Type == rr2.type()); |
| 292 | |
| 293 | const SkPoint& p2 = rr2.radii(SkRRect::kUpperLeft_Corner); |
| 294 | |
| 295 | REPORTER_ASSERT(reporter, 0.0f == p2.fX); |
| 296 | REPORTER_ASSERT(reporter, 0.0f == p2.fY); |
| 297 | } |
| 298 | |
| 299 | static void TestRoundRect(skiatest::Reporter* reporter) { |
| 300 | test_round_rect_basic(reporter); |
| 301 | test_round_rect_rects(reporter); |
| 302 | test_round_rect_ovals(reporter); |
| 303 | test_round_rect_general(reporter); |
| 304 | test_round_rect_iffy_parameters(reporter); |
| 305 | } |
| 306 | |
| 307 | #include "TestClassDef.h" |
| 308 | DEFINE_TESTCLASS("RoundRect", TestRoundRectClass, TestRoundRect) |