| 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 |  | 
| scroggo@google.com | 20e3cd2 | 2013-11-05 15:54:42 +0000 | [diff] [blame] | 8 | #include "SkMatrix.h" | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 9 | #include "SkRRect.h" | 
| tfarina@chromium.org | 8f6884a | 2014-01-24 20:56:26 +0000 | [diff] [blame] | 10 | #include "Test.h" | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 11 |  | 
| reed | 694b0d1 | 2015-02-13 14:33:02 -0800 | [diff] [blame] | 12 | static void test_tricky_radii_crbug_458522(skiatest::Reporter* reporter) { | 
|  | 13 | SkRRect rr; | 
|  | 14 | const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 }; | 
|  | 15 | const SkScalar rad = 12814; | 
|  | 16 | const SkVector vec[] = { { rad, rad }, { 0, rad }, { rad, rad }, { 0, rad } }; | 
|  | 17 | rr.setRectRadii(bounds, vec); | 
|  | 18 | } | 
|  | 19 |  | 
|  | 20 | static void test_empty_crbug_458524(skiatest::Reporter* reporter) { | 
|  | 21 | SkRRect rr; | 
|  | 22 | const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 }; | 
|  | 23 | const SkScalar rad = 40; | 
|  | 24 | rr.setRectXY(bounds, rad, rad); | 
|  | 25 |  | 
|  | 26 | SkRRect other; | 
|  | 27 | SkMatrix matrix; | 
|  | 28 | matrix.setScale(0, 1); | 
|  | 29 | rr.transform(matrix, &other); | 
|  | 30 | REPORTER_ASSERT(reporter, SkRRect::kEmpty_Type == other.getType()); | 
|  | 31 | } | 
|  | 32 |  | 
| commit-bot@chromium.org | 4b413c8 | 2013-11-25 19:44:07 +0000 | [diff] [blame] | 33 | static const SkScalar kWidth = 100.0f; | 
|  | 34 | static const SkScalar kHeight = 100.0f; | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 35 |  | 
| mike@reedtribe.org | bcbef57 | 2012-12-23 23:11:21 +0000 | [diff] [blame] | 36 | static void test_inset(skiatest::Reporter* reporter) { | 
|  | 37 | SkRRect rr, rr2; | 
|  | 38 | SkRect r = { 0, 0, 100, 100 }; | 
|  | 39 |  | 
|  | 40 | rr.setRect(r); | 
|  | 41 | rr.inset(-20, -20, &rr2); | 
|  | 42 | REPORTER_ASSERT(reporter, rr2.isRect()); | 
|  | 43 |  | 
|  | 44 | rr.inset(20, 20, &rr2); | 
|  | 45 | REPORTER_ASSERT(reporter, rr2.isRect()); | 
| skia.committer@gmail.com | 1a60dab | 2012-12-24 02:01:25 +0000 | [diff] [blame] | 46 |  | 
| mike@reedtribe.org | bcbef57 | 2012-12-23 23:11:21 +0000 | [diff] [blame] | 47 | rr.inset(r.width()/2, r.height()/2, &rr2); | 
|  | 48 | REPORTER_ASSERT(reporter, rr2.isEmpty()); | 
|  | 49 |  | 
|  | 50 | rr.setRectXY(r, 20, 20); | 
|  | 51 | rr.inset(19, 19, &rr2); | 
|  | 52 | REPORTER_ASSERT(reporter, rr2.isSimple()); | 
|  | 53 | rr.inset(20, 20, &rr2); | 
|  | 54 | REPORTER_ASSERT(reporter, rr2.isRect()); | 
|  | 55 | } | 
|  | 56 |  | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 57 | // Test out the basic API entry points | 
|  | 58 | static void test_round_rect_basic(skiatest::Reporter* reporter) { | 
|  | 59 | // Test out initialization methods | 
| reed@google.com | 2b57dc6 | 2013-01-08 13:23:32 +0000 | [diff] [blame] | 60 | SkPoint zeroPt = { 0, 0 }; | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 61 | SkRRect empty; | 
| skia.committer@gmail.com | c3d7d90 | 2012-11-30 02:01:24 +0000 | [diff] [blame] | 62 |  | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 63 | empty.setEmpty(); | 
|  | 64 |  | 
|  | 65 | REPORTER_ASSERT(reporter, SkRRect::kEmpty_Type == empty.type()); | 
|  | 66 | REPORTER_ASSERT(reporter, empty.rect().isEmpty()); | 
|  | 67 |  | 
|  | 68 | for (int i = 0; i < 4; ++i) { | 
|  | 69 | REPORTER_ASSERT(reporter, zeroPt == empty.radii((SkRRect::Corner) i)); | 
|  | 70 | } | 
|  | 71 |  | 
|  | 72 | //---- | 
|  | 73 | SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); | 
|  | 74 |  | 
|  | 75 | SkRRect rr1; | 
|  | 76 | rr1.setRect(rect); | 
|  | 77 |  | 
|  | 78 | REPORTER_ASSERT(reporter, SkRRect::kRect_Type == rr1.type()); | 
|  | 79 | REPORTER_ASSERT(reporter, rr1.rect() == rect); | 
|  | 80 |  | 
|  | 81 | for (int i = 0; i < 4; ++i) { | 
|  | 82 | REPORTER_ASSERT(reporter, zeroPt == rr1.radii((SkRRect::Corner) i)); | 
|  | 83 | } | 
| commit-bot@chromium.org | f338d7c | 2014-03-17 21:17:30 +0000 | [diff] [blame] | 84 | SkRRect rr1_2; // construct the same RR using the most general set function | 
|  | 85 | SkVector rr1_2_radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; | 
|  | 86 | rr1_2.setRectRadii(rect, rr1_2_radii); | 
|  | 87 | REPORTER_ASSERT(reporter, rr1_2 == rr1 && rr1_2.getType() == rr1.getType()); | 
|  | 88 | SkRRect rr1_3;  // construct the same RR using the nine patch set function | 
|  | 89 | rr1_3.setNinePatch(rect, 0, 0, 0, 0); | 
|  | 90 | REPORTER_ASSERT(reporter, rr1_3 == rr1 && rr1_3.getType() == rr1.getType()); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 91 |  | 
|  | 92 | //---- | 
|  | 93 | SkPoint halfPoint = { SkScalarHalf(kWidth), SkScalarHalf(kHeight) }; | 
|  | 94 | SkRRect rr2; | 
|  | 95 | rr2.setOval(rect); | 
|  | 96 |  | 
|  | 97 | REPORTER_ASSERT(reporter, SkRRect::kOval_Type == rr2.type()); | 
|  | 98 | REPORTER_ASSERT(reporter, rr2.rect() == rect); | 
|  | 99 |  | 
|  | 100 | for (int i = 0; i < 4; ++i) { | 
| skia.committer@gmail.com | c3d7d90 | 2012-11-30 02:01:24 +0000 | [diff] [blame] | 101 | REPORTER_ASSERT(reporter, | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 102 | rr2.radii((SkRRect::Corner) i).equalsWithinTolerance(halfPoint)); | 
|  | 103 | } | 
| commit-bot@chromium.org | f338d7c | 2014-03-17 21:17:30 +0000 | [diff] [blame] | 104 | SkRRect rr2_2;  // construct the same RR using the most general set function | 
|  | 105 | SkVector rr2_2_radii[4] = { { halfPoint.fX, halfPoint.fY }, { halfPoint.fX, halfPoint.fY }, | 
|  | 106 | { halfPoint.fX, halfPoint.fY }, { halfPoint.fX, halfPoint.fY } }; | 
|  | 107 | rr2_2.setRectRadii(rect, rr2_2_radii); | 
|  | 108 | REPORTER_ASSERT(reporter, rr2_2 == rr2 && rr2_2.getType() == rr2.getType()); | 
|  | 109 | SkRRect rr2_3;  // construct the same RR using the nine patch set function | 
|  | 110 | rr2_3.setNinePatch(rect, halfPoint.fX, halfPoint.fY, halfPoint.fX, halfPoint.fY); | 
|  | 111 | REPORTER_ASSERT(reporter, rr2_3 == rr2 && rr2_3.getType() == rr2.getType()); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 112 |  | 
|  | 113 | //---- | 
|  | 114 | SkPoint p = { 5, 5 }; | 
|  | 115 | SkRRect rr3; | 
|  | 116 | rr3.setRectXY(rect, p.fX, p.fY); | 
|  | 117 |  | 
|  | 118 | REPORTER_ASSERT(reporter, SkRRect::kSimple_Type == rr3.type()); | 
|  | 119 | REPORTER_ASSERT(reporter, rr3.rect() == rect); | 
|  | 120 |  | 
|  | 121 | for (int i = 0; i < 4; ++i) { | 
|  | 122 | REPORTER_ASSERT(reporter, p == rr3.radii((SkRRect::Corner) i)); | 
|  | 123 | } | 
| commit-bot@chromium.org | f338d7c | 2014-03-17 21:17:30 +0000 | [diff] [blame] | 124 | SkRRect rr3_2; // construct the same RR using the most general set function | 
|  | 125 | SkVector rr3_2_radii[4] = { { 5, 5 }, { 5, 5 }, { 5, 5 }, { 5, 5 } }; | 
|  | 126 | rr3_2.setRectRadii(rect, rr3_2_radii); | 
|  | 127 | REPORTER_ASSERT(reporter, rr3_2 == rr3 && rr3_2.getType() == rr3.getType()); | 
|  | 128 | SkRRect rr3_3;  // construct the same RR using the nine patch set function | 
|  | 129 | rr3_3.setNinePatch(rect, 5, 5, 5, 5); | 
|  | 130 | REPORTER_ASSERT(reporter, rr3_3 == rr3 && rr3_3.getType() == rr3.getType()); | 
| skia.committer@gmail.com | c3d7d90 | 2012-11-30 02:01:24 +0000 | [diff] [blame] | 131 |  | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 132 | //---- | 
| commit-bot@chromium.org | f338d7c | 2014-03-17 21:17:30 +0000 | [diff] [blame] | 133 | SkRect ninePatchRadii = { 10, 9, 8, 7 }; | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 134 |  | 
|  | 135 | SkRRect rr4; | 
| commit-bot@chromium.org | f338d7c | 2014-03-17 21:17:30 +0000 | [diff] [blame] | 136 | rr4.setNinePatch(rect, ninePatchRadii.fLeft, ninePatchRadii.fTop, ninePatchRadii.fRight, | 
|  | 137 | ninePatchRadii.fBottom); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 138 |  | 
| commit-bot@chromium.org | f338d7c | 2014-03-17 21:17:30 +0000 | [diff] [blame] | 139 | REPORTER_ASSERT(reporter, SkRRect::kNinePatch_Type == rr4.type()); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 140 | REPORTER_ASSERT(reporter, rr4.rect() == rect); | 
|  | 141 |  | 
| commit-bot@chromium.org | f338d7c | 2014-03-17 21:17:30 +0000 | [diff] [blame] | 142 | SkPoint rquad[4]; | 
|  | 143 | ninePatchRadii.toQuad(rquad); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 144 | for (int i = 0; i < 4; ++i) { | 
| commit-bot@chromium.org | f338d7c | 2014-03-17 21:17:30 +0000 | [diff] [blame] | 145 | REPORTER_ASSERT(reporter, rquad[i] == rr4.radii((SkRRect::Corner) i)); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 146 | } | 
| commit-bot@chromium.org | f338d7c | 2014-03-17 21:17:30 +0000 | [diff] [blame] | 147 | SkRRect rr4_2; // construct the same RR using the most general set function | 
|  | 148 | SkVector rr4_2_radii[4] = { { 10, 9 }, { 8, 9 }, {8, 7 }, { 10, 7 } }; | 
|  | 149 | rr4_2.setRectRadii(rect, rr4_2_radii); | 
|  | 150 | REPORTER_ASSERT(reporter, rr4_2 == rr4 && rr4_2.getType() == rr4.getType()); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 151 |  | 
|  | 152 | //---- | 
|  | 153 | SkPoint radii2[4] = { { 0, 0 }, { 0, 0 }, { 50, 50 }, { 20, 50 } }; | 
|  | 154 |  | 
|  | 155 | SkRRect rr5; | 
|  | 156 | rr5.setRectRadii(rect, radii2); | 
|  | 157 |  | 
|  | 158 | REPORTER_ASSERT(reporter, SkRRect::kComplex_Type == rr5.type()); | 
|  | 159 | REPORTER_ASSERT(reporter, rr5.rect() == rect); | 
|  | 160 |  | 
|  | 161 | for (int i = 0; i < 4; ++i) { | 
|  | 162 | REPORTER_ASSERT(reporter, radii2[i] == rr5.radii((SkRRect::Corner) i)); | 
|  | 163 | } | 
|  | 164 |  | 
|  | 165 | // Test out == & != | 
|  | 166 | REPORTER_ASSERT(reporter, empty != rr3); | 
| commit-bot@chromium.org | f338d7c | 2014-03-17 21:17:30 +0000 | [diff] [blame] | 167 | REPORTER_ASSERT(reporter, rr3 != rr4); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 168 | REPORTER_ASSERT(reporter, rr4 != rr5); | 
|  | 169 | } | 
|  | 170 |  | 
|  | 171 | // Test out the cases when the RR degenerates to a rect | 
|  | 172 | static void test_round_rect_rects(skiatest::Reporter* reporter) { | 
|  | 173 | SkRect r; | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 174 |  | 
|  | 175 | //---- | 
|  | 176 | SkRRect empty; | 
| skia.committer@gmail.com | c3d7d90 | 2012-11-30 02:01:24 +0000 | [diff] [blame] | 177 |  | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 178 | empty.setEmpty(); | 
|  | 179 |  | 
|  | 180 | REPORTER_ASSERT(reporter, SkRRect::kEmpty_Type == empty.type()); | 
|  | 181 | r = empty.rect(); | 
|  | 182 | REPORTER_ASSERT(reporter, 0 == r.fLeft && 0 == r.fTop && 0 == r.fRight && 0 == r.fBottom); | 
|  | 183 |  | 
|  | 184 | //---- | 
|  | 185 | SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); | 
|  | 186 | SkRRect rr1; | 
|  | 187 | rr1.setRectXY(rect, 0, 0); | 
|  | 188 |  | 
|  | 189 | REPORTER_ASSERT(reporter, SkRRect::kRect_Type == rr1.type()); | 
|  | 190 | r = rr1.rect(); | 
|  | 191 | REPORTER_ASSERT(reporter, rect == r); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 192 |  | 
|  | 193 | //---- | 
|  | 194 | SkPoint radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; | 
|  | 195 |  | 
|  | 196 | SkRRect rr2; | 
|  | 197 | rr2.setRectRadii(rect, radii); | 
|  | 198 |  | 
|  | 199 | REPORTER_ASSERT(reporter, SkRRect::kRect_Type == rr2.type()); | 
|  | 200 | r = rr2.rect(); | 
|  | 201 | REPORTER_ASSERT(reporter, rect == r); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 202 |  | 
|  | 203 | //---- | 
|  | 204 | SkPoint radii2[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } }; | 
|  | 205 |  | 
|  | 206 | SkRRect rr3; | 
|  | 207 | rr3.setRectRadii(rect, radii2); | 
|  | 208 | REPORTER_ASSERT(reporter, SkRRect::kComplex_Type == rr3.type()); | 
|  | 209 | } | 
|  | 210 |  | 
|  | 211 | // Test out the cases when the RR degenerates to an oval | 
|  | 212 | static void test_round_rect_ovals(skiatest::Reporter* reporter) { | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 213 | //---- | 
|  | 214 | SkRect oval; | 
|  | 215 | SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); | 
|  | 216 | SkRRect rr1; | 
|  | 217 | rr1.setRectXY(rect, SkScalarHalf(kWidth), SkScalarHalf(kHeight)); | 
|  | 218 |  | 
|  | 219 | REPORTER_ASSERT(reporter, SkRRect::kOval_Type == rr1.type()); | 
|  | 220 | oval = rr1.rect(); | 
|  | 221 | REPORTER_ASSERT(reporter, oval == rect); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 222 | } | 
|  | 223 |  | 
|  | 224 | // Test out the non-degenerate RR cases | 
|  | 225 | static void test_round_rect_general(skiatest::Reporter* reporter) { | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 226 | //---- | 
|  | 227 | SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); | 
|  | 228 | SkRRect rr1; | 
|  | 229 | rr1.setRectXY(rect, 20, 20); | 
|  | 230 |  | 
|  | 231 | REPORTER_ASSERT(reporter, SkRRect::kSimple_Type == rr1.type()); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 232 |  | 
|  | 233 | //---- | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 234 | SkPoint radii[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } }; | 
|  | 235 |  | 
|  | 236 | SkRRect rr2; | 
|  | 237 | rr2.setRectRadii(rect, radii); | 
|  | 238 |  | 
|  | 239 | REPORTER_ASSERT(reporter, SkRRect::kComplex_Type == rr2.type()); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 240 | } | 
|  | 241 |  | 
|  | 242 | // Test out questionable-parameter handling | 
|  | 243 | static void test_round_rect_iffy_parameters(skiatest::Reporter* reporter) { | 
|  | 244 |  | 
|  | 245 | // When the radii exceed the base rect they are proportionally scaled down | 
|  | 246 | // to fit | 
|  | 247 | SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight); | 
|  | 248 | SkPoint radii[4] = { { 50, 100 }, { 100, 50 }, { 50, 100 }, { 100, 50 } }; | 
|  | 249 |  | 
|  | 250 | SkRRect rr1; | 
|  | 251 | rr1.setRectRadii(rect, radii); | 
|  | 252 |  | 
|  | 253 | REPORTER_ASSERT(reporter, SkRRect::kComplex_Type == rr1.type()); | 
|  | 254 |  | 
|  | 255 | const SkPoint& p = rr1.radii(SkRRect::kUpperLeft_Corner); | 
|  | 256 |  | 
|  | 257 | REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.fX, 33.33333f)); | 
|  | 258 | REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.fY, 66.66666f)); | 
|  | 259 |  | 
|  | 260 | // Negative radii should be capped at zero | 
|  | 261 | SkRRect rr2; | 
|  | 262 | rr2.setRectXY(rect, -10, -20); | 
|  | 263 |  | 
|  | 264 | REPORTER_ASSERT(reporter, SkRRect::kRect_Type == rr2.type()); | 
|  | 265 |  | 
|  | 266 | const SkPoint& p2 = rr2.radii(SkRRect::kUpperLeft_Corner); | 
|  | 267 |  | 
|  | 268 | REPORTER_ASSERT(reporter, 0.0f == p2.fX); | 
|  | 269 | REPORTER_ASSERT(reporter, 0.0f == p2.fY); | 
|  | 270 | } | 
|  | 271 |  | 
| robertphillips@google.com | 32c1b66 | 2013-04-25 12:23:00 +0000 | [diff] [blame] | 272 | // Move a small box from the start position by (stepX, stepY) 'numSteps' times | 
|  | 273 | // testing for containment in 'rr' at each step. | 
|  | 274 | static void test_direction(skiatest::Reporter* reporter, const SkRRect &rr, | 
| skia.committer@gmail.com | 2cf444f | 2013-04-26 07:00:58 +0000 | [diff] [blame] | 275 | SkScalar initX, int stepX, SkScalar initY, int stepY, | 
| robertphillips@google.com | 32c1b66 | 2013-04-25 12:23:00 +0000 | [diff] [blame] | 276 | int numSteps, const bool* contains) { | 
|  | 277 | SkScalar x = initX, y = initY; | 
|  | 278 | for (int i = 0; i < numSteps; ++i) { | 
| skia.committer@gmail.com | 2cf444f | 2013-04-26 07:00:58 +0000 | [diff] [blame] | 279 | SkRect test = SkRect::MakeXYWH(x, y, | 
|  | 280 | stepX ? SkIntToScalar(stepX) : SK_Scalar1, | 
| robertphillips@google.com | 32c1b66 | 2013-04-25 12:23:00 +0000 | [diff] [blame] | 281 | stepY ? SkIntToScalar(stepY) : SK_Scalar1); | 
|  | 282 | test.sort(); | 
|  | 283 |  | 
|  | 284 | REPORTER_ASSERT(reporter, contains[i] == rr.contains(test)); | 
|  | 285 |  | 
|  | 286 | x += stepX; | 
|  | 287 | y += stepY; | 
|  | 288 | } | 
|  | 289 | } | 
|  | 290 |  | 
|  | 291 | // Exercise the RR's contains rect method | 
|  | 292 | static void test_round_rect_contains_rect(skiatest::Reporter* reporter) { | 
|  | 293 |  | 
|  | 294 | static const int kNumRRects = 4; | 
|  | 295 | static const SkVector gRadii[kNumRRects][4] = { | 
|  | 296 | { {  0,  0 }, {  0,  0 }, {  0,  0 }, {  0,  0 } },  // rect | 
|  | 297 | { { 20, 20 }, { 20, 20 }, { 20, 20 }, { 20, 20 } },  // circle | 
|  | 298 | { { 10, 10 }, { 10, 10 }, { 10, 10 }, { 10, 10 } },  // simple | 
|  | 299 | { {  0,  0 }, { 20, 20 }, { 10, 10 }, { 30, 30 } }   // complex | 
|  | 300 | }; | 
|  | 301 |  | 
|  | 302 | SkRRect rrects[kNumRRects]; | 
|  | 303 | for (int i = 0; i < kNumRRects; ++i) { | 
|  | 304 | rrects[i].setRectRadii(SkRect::MakeWH(40, 40), gRadii[i]); | 
|  | 305 | } | 
|  | 306 |  | 
|  | 307 | // First test easy outs - boxes that are obviously out on | 
|  | 308 | // each corner and edge | 
|  | 309 | static const SkRect easyOuts[] = { | 
|  | 310 | { -5, -5,  5,  5 }, // NW | 
|  | 311 | { 15, -5, 20,  5 }, // N | 
|  | 312 | { 35, -5, 45,  5 }, // NE | 
|  | 313 | { 35, 15, 45, 20 }, // E | 
|  | 314 | { 35, 45, 35, 45 }, // SE | 
|  | 315 | { 15, 35, 20, 45 }, // S | 
|  | 316 | { -5, 35,  5, 45 }, // SW | 
|  | 317 | { -5, 15,  5, 20 }  // W | 
|  | 318 | }; | 
| skia.committer@gmail.com | 2cf444f | 2013-04-26 07:00:58 +0000 | [diff] [blame] | 319 |  | 
| robertphillips@google.com | 32c1b66 | 2013-04-25 12:23:00 +0000 | [diff] [blame] | 320 | for (int i = 0; i < kNumRRects; ++i) { | 
|  | 321 | for (size_t j = 0; j < SK_ARRAY_COUNT(easyOuts); ++j) { | 
|  | 322 | REPORTER_ASSERT(reporter, !rrects[i].contains(easyOuts[j])); | 
|  | 323 | } | 
|  | 324 | } | 
|  | 325 |  | 
| skia.committer@gmail.com | 2cf444f | 2013-04-26 07:00:58 +0000 | [diff] [blame] | 326 | // Now test non-trivial containment. For each compass | 
|  | 327 | // point walk a 1x1 rect in from the edge  of the bounding | 
| robertphillips@google.com | 32c1b66 | 2013-04-25 12:23:00 +0000 | [diff] [blame] | 328 | // rect | 
|  | 329 | static const int kNumSteps = 15; | 
|  | 330 | bool answers[kNumRRects][8][kNumSteps] = { | 
|  | 331 | // all the test rects are inside the degenerate rrect | 
|  | 332 | { | 
|  | 333 | // rect | 
|  | 334 | { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 335 | { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 336 | { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 337 | { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 338 | { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 339 | { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 340 | { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 341 | { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 342 | }, | 
|  | 343 | // for the circle we expect 6 blocks to be out on the | 
| skia.committer@gmail.com | 2cf444f | 2013-04-26 07:00:58 +0000 | [diff] [blame] | 344 | // corners (then the rest in) and only the first block | 
|  | 345 | // out on the vertical and horizontal axes (then | 
| robertphillips@google.com | 32c1b66 | 2013-04-25 12:23:00 +0000 | [diff] [blame] | 346 | // the rest in) | 
|  | 347 | { | 
|  | 348 | // circle | 
|  | 349 | { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 350 | { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 351 | { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 352 | { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 353 | { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 354 | { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 355 | { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 356 | { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 357 | }, | 
|  | 358 | // for the simple round rect we expect 3 out on | 
|  | 359 | // the corners (then the rest in) and no blocks out | 
|  | 360 | // on the vertical and horizontal axes | 
|  | 361 | { | 
|  | 362 | // simple RR | 
|  | 363 | { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 364 | { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 365 | { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 366 | { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 367 | { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 368 | { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 369 | { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 370 | { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 371 | }, | 
|  | 372 | // for the complex case the answer is different for each direction | 
|  | 373 | { | 
|  | 374 | // complex RR | 
|  | 375 | // all in for NW (rect) corner (same as rect case) | 
|  | 376 | { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 377 | // only first block out for N (same as circle case) | 
|  | 378 | { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 379 | // first 6 blocks out for NE (same as circle case) | 
|  | 380 | { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 381 | // only first block out for E (same as circle case) | 
|  | 382 | { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 383 | // first 3 blocks out for SE (same as simple case) | 
|  | 384 | { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 385 | // first two blocks out for S | 
|  | 386 | { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 387 | // first 9 blocks out for SW | 
|  | 388 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 }, | 
|  | 389 | // first two blocks out for W (same as S) | 
|  | 390 | { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, | 
|  | 391 | } | 
|  | 392 | }; | 
|  | 393 |  | 
|  | 394 | for (int i = 0; i < kNumRRects; ++i) { | 
|  | 395 | test_direction(reporter, rrects[i],     0,  1,     0,  1, kNumSteps, answers[i][0]); // NW | 
|  | 396 | test_direction(reporter, rrects[i], 19.5f,  0,     0,  1, kNumSteps, answers[i][1]); // N | 
|  | 397 | test_direction(reporter, rrects[i],    40, -1,     0,  1, kNumSteps, answers[i][2]); // NE | 
|  | 398 | test_direction(reporter, rrects[i],    40, -1, 19.5f,  0, kNumSteps, answers[i][3]); // E | 
|  | 399 | test_direction(reporter, rrects[i],    40, -1,    40, -1, kNumSteps, answers[i][4]); // SE | 
|  | 400 | test_direction(reporter, rrects[i], 19.5f,  0,    40, -1, kNumSteps, answers[i][5]); // S | 
|  | 401 | test_direction(reporter, rrects[i],     0,  1,    40, -1, kNumSteps, answers[i][6]); // SW | 
|  | 402 | test_direction(reporter, rrects[i],     0,  1, 19.5f,  0, kNumSteps, answers[i][7]); // W | 
|  | 403 | } | 
|  | 404 | } | 
|  | 405 |  | 
| scroggo@google.com | 20e3cd2 | 2013-11-05 15:54:42 +0000 | [diff] [blame] | 406 | // Called for a matrix that should cause SkRRect::transform to fail. | 
|  | 407 | static void assert_transform_failure(skiatest::Reporter* reporter, const SkRRect& orig, | 
|  | 408 | const SkMatrix& matrix) { | 
|  | 409 | // The test depends on the fact that the original is not empty. | 
|  | 410 | SkASSERT(!orig.isEmpty()); | 
|  | 411 | SkRRect dst; | 
|  | 412 | dst.setEmpty(); | 
|  | 413 |  | 
|  | 414 | const SkRRect copyOfDst = dst; | 
|  | 415 | const SkRRect copyOfOrig = orig; | 
|  | 416 | bool success = orig.transform(matrix, &dst); | 
|  | 417 | // This transform should fail. | 
|  | 418 | REPORTER_ASSERT(reporter, !success); | 
|  | 419 | // Since the transform failed, dst should be unchanged. | 
|  | 420 | REPORTER_ASSERT(reporter, copyOfDst == dst); | 
|  | 421 | // original should not be modified. | 
|  | 422 | REPORTER_ASSERT(reporter, copyOfOrig == orig); | 
|  | 423 | REPORTER_ASSERT(reporter, orig != dst); | 
|  | 424 | } | 
|  | 425 |  | 
|  | 426 | #define GET_RADII                                                       \ | 
|  | 427 | const SkVector& origUL = orig.radii(SkRRect::kUpperLeft_Corner);    \ | 
|  | 428 | const SkVector& origUR = orig.radii(SkRRect::kUpperRight_Corner);   \ | 
|  | 429 | const SkVector& origLR = orig.radii(SkRRect::kLowerRight_Corner);   \ | 
|  | 430 | const SkVector& origLL = orig.radii(SkRRect::kLowerLeft_Corner);    \ | 
|  | 431 | const SkVector& dstUL = dst.radii(SkRRect::kUpperLeft_Corner);      \ | 
|  | 432 | const SkVector& dstUR = dst.radii(SkRRect::kUpperRight_Corner);     \ | 
|  | 433 | const SkVector& dstLR = dst.radii(SkRRect::kLowerRight_Corner);     \ | 
|  | 434 | const SkVector& dstLL = dst.radii(SkRRect::kLowerLeft_Corner) | 
|  | 435 |  | 
|  | 436 | // Called to test various transforms on a single SkRRect. | 
|  | 437 | static void test_transform_helper(skiatest::Reporter* reporter, const SkRRect& orig) { | 
|  | 438 | SkRRect dst; | 
|  | 439 | dst.setEmpty(); | 
|  | 440 |  | 
|  | 441 | // The identity matrix will duplicate the rrect. | 
|  | 442 | bool success = orig.transform(SkMatrix::I(), &dst); | 
|  | 443 | REPORTER_ASSERT(reporter, success); | 
|  | 444 | REPORTER_ASSERT(reporter, orig == dst); | 
|  | 445 |  | 
|  | 446 | // Skew and Perspective make transform fail. | 
|  | 447 | SkMatrix matrix; | 
|  | 448 | matrix.reset(); | 
|  | 449 | matrix.setSkewX(SkIntToScalar(2)); | 
|  | 450 | assert_transform_failure(reporter, orig, matrix); | 
|  | 451 |  | 
|  | 452 | matrix.reset(); | 
|  | 453 | matrix.setSkewY(SkIntToScalar(3)); | 
|  | 454 | assert_transform_failure(reporter, orig, matrix); | 
|  | 455 |  | 
|  | 456 | matrix.reset(); | 
| reed | 3f43f8a | 2015-01-20 19:58:36 -0800 | [diff] [blame] | 457 | matrix.setPerspX(4); | 
| scroggo@google.com | 20e3cd2 | 2013-11-05 15:54:42 +0000 | [diff] [blame] | 458 | assert_transform_failure(reporter, orig, matrix); | 
|  | 459 |  | 
|  | 460 | matrix.reset(); | 
| reed | 3f43f8a | 2015-01-20 19:58:36 -0800 | [diff] [blame] | 461 | matrix.setPerspY(5); | 
| scroggo@google.com | 20e3cd2 | 2013-11-05 15:54:42 +0000 | [diff] [blame] | 462 | assert_transform_failure(reporter, orig, matrix); | 
|  | 463 |  | 
|  | 464 | // Rotation fails. | 
|  | 465 | matrix.reset(); | 
|  | 466 | matrix.setRotate(SkIntToScalar(90)); | 
|  | 467 | assert_transform_failure(reporter, orig, matrix); | 
|  | 468 | matrix.setRotate(SkIntToScalar(37)); | 
|  | 469 | assert_transform_failure(reporter, orig, matrix); | 
|  | 470 |  | 
|  | 471 | // Translate will keep the rect moved, but otherwise the same. | 
|  | 472 | matrix.reset(); | 
|  | 473 | SkScalar translateX = SkIntToScalar(32); | 
|  | 474 | SkScalar translateY = SkIntToScalar(15); | 
|  | 475 | matrix.setTranslateX(translateX); | 
|  | 476 | matrix.setTranslateY(translateY); | 
|  | 477 | dst.setEmpty(); | 
|  | 478 | success = orig.transform(matrix, &dst); | 
|  | 479 | REPORTER_ASSERT(reporter, success); | 
|  | 480 | for (int i = 0; i < 4; ++i) { | 
|  | 481 | REPORTER_ASSERT(reporter, | 
|  | 482 | orig.radii((SkRRect::Corner) i) == dst.radii((SkRRect::Corner) i)); | 
|  | 483 | } | 
|  | 484 | REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width()); | 
|  | 485 | REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height()); | 
|  | 486 | REPORTER_ASSERT(reporter, dst.rect().left() == orig.rect().left() + translateX); | 
|  | 487 | REPORTER_ASSERT(reporter, dst.rect().top() == orig.rect().top() + translateY); | 
|  | 488 |  | 
|  | 489 | // Keeping the translation, but adding skew will make transform fail. | 
|  | 490 | matrix.setSkewY(SkIntToScalar(7)); | 
|  | 491 | assert_transform_failure(reporter, orig, matrix); | 
|  | 492 |  | 
|  | 493 | // Scaling in -x will flip the round rect horizontally. | 
|  | 494 | matrix.reset(); | 
|  | 495 | matrix.setScaleX(SkIntToScalar(-1)); | 
|  | 496 | dst.setEmpty(); | 
|  | 497 | success = orig.transform(matrix, &dst); | 
|  | 498 | REPORTER_ASSERT(reporter, success); | 
|  | 499 | { | 
|  | 500 | GET_RADII; | 
|  | 501 | // Radii have swapped in x. | 
|  | 502 | REPORTER_ASSERT(reporter, origUL == dstUR); | 
|  | 503 | REPORTER_ASSERT(reporter, origUR == dstUL); | 
|  | 504 | REPORTER_ASSERT(reporter, origLR == dstLL); | 
|  | 505 | REPORTER_ASSERT(reporter, origLL == dstLR); | 
|  | 506 | } | 
|  | 507 | // Width and height remain the same. | 
|  | 508 | REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width()); | 
|  | 509 | REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height()); | 
|  | 510 | // Right and left have swapped (sort of) | 
|  | 511 | REPORTER_ASSERT(reporter, orig.rect().right() == -dst.rect().left()); | 
|  | 512 | // Top has stayed the same. | 
|  | 513 | REPORTER_ASSERT(reporter, orig.rect().top() == dst.rect().top()); | 
|  | 514 |  | 
|  | 515 | // Keeping the scale, but adding a persp will make transform fail. | 
| reed | 3f43f8a | 2015-01-20 19:58:36 -0800 | [diff] [blame] | 516 | matrix.setPerspX(7); | 
| scroggo@google.com | 20e3cd2 | 2013-11-05 15:54:42 +0000 | [diff] [blame] | 517 | assert_transform_failure(reporter, orig, matrix); | 
|  | 518 |  | 
|  | 519 | // Scaling in -y will flip the round rect vertically. | 
|  | 520 | matrix.reset(); | 
|  | 521 | matrix.setScaleY(SkIntToScalar(-1)); | 
|  | 522 | dst.setEmpty(); | 
|  | 523 | success = orig.transform(matrix, &dst); | 
|  | 524 | REPORTER_ASSERT(reporter, success); | 
|  | 525 | { | 
|  | 526 | GET_RADII; | 
|  | 527 | // Radii have swapped in y. | 
|  | 528 | REPORTER_ASSERT(reporter, origUL == dstLL); | 
|  | 529 | REPORTER_ASSERT(reporter, origUR == dstLR); | 
|  | 530 | REPORTER_ASSERT(reporter, origLR == dstUR); | 
|  | 531 | REPORTER_ASSERT(reporter, origLL == dstUL); | 
|  | 532 | } | 
|  | 533 | // Width and height remain the same. | 
|  | 534 | REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width()); | 
|  | 535 | REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height()); | 
|  | 536 | // Top and bottom have swapped (sort of) | 
|  | 537 | REPORTER_ASSERT(reporter, orig.rect().top() == -dst.rect().bottom()); | 
|  | 538 | // Left has stayed the same. | 
|  | 539 | REPORTER_ASSERT(reporter, orig.rect().left() == dst.rect().left()); | 
|  | 540 |  | 
|  | 541 | // Scaling in -x and -y will swap in both directions. | 
|  | 542 | matrix.reset(); | 
|  | 543 | matrix.setScaleY(SkIntToScalar(-1)); | 
|  | 544 | matrix.setScaleX(SkIntToScalar(-1)); | 
|  | 545 | dst.setEmpty(); | 
|  | 546 | success = orig.transform(matrix, &dst); | 
|  | 547 | REPORTER_ASSERT(reporter, success); | 
|  | 548 | { | 
|  | 549 | GET_RADII; | 
|  | 550 | REPORTER_ASSERT(reporter, origUL == dstLR); | 
|  | 551 | REPORTER_ASSERT(reporter, origUR == dstLL); | 
|  | 552 | REPORTER_ASSERT(reporter, origLR == dstUL); | 
|  | 553 | REPORTER_ASSERT(reporter, origLL == dstUR); | 
|  | 554 | } | 
|  | 555 | // Width and height remain the same. | 
|  | 556 | REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width()); | 
|  | 557 | REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height()); | 
|  | 558 | REPORTER_ASSERT(reporter, orig.rect().top() == -dst.rect().bottom()); | 
|  | 559 | REPORTER_ASSERT(reporter, orig.rect().right() == -dst.rect().left()); | 
|  | 560 |  | 
|  | 561 | // Scale in both directions. | 
|  | 562 | SkScalar xScale = SkIntToScalar(3); | 
| commit-bot@chromium.org | 4b413c8 | 2013-11-25 19:44:07 +0000 | [diff] [blame] | 563 | SkScalar yScale = 3.2f; | 
| scroggo@google.com | 20e3cd2 | 2013-11-05 15:54:42 +0000 | [diff] [blame] | 564 | matrix.reset(); | 
|  | 565 | matrix.setScaleX(xScale); | 
|  | 566 | matrix.setScaleY(yScale); | 
|  | 567 | dst.setEmpty(); | 
|  | 568 | success = orig.transform(matrix, &dst); | 
|  | 569 | REPORTER_ASSERT(reporter, success); | 
|  | 570 | // Radii are scaled. | 
|  | 571 | for (int i = 0; i < 4; ++i) { | 
|  | 572 | REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.radii((SkRRect::Corner) i).fX, | 
|  | 573 | SkScalarMul(orig.radii((SkRRect::Corner) i).fX, xScale))); | 
|  | 574 | REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.radii((SkRRect::Corner) i).fY, | 
|  | 575 | SkScalarMul(orig.radii((SkRRect::Corner) i).fY, yScale))); | 
|  | 576 | } | 
|  | 577 | REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().width(), | 
|  | 578 | SkScalarMul(orig.rect().width(), xScale))); | 
|  | 579 | REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().height(), | 
|  | 580 | SkScalarMul(orig.rect().height(), yScale))); | 
|  | 581 | REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().left(), | 
|  | 582 | SkScalarMul(orig.rect().left(), xScale))); | 
|  | 583 | REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().top(), | 
|  | 584 | SkScalarMul(orig.rect().top(), yScale))); | 
|  | 585 | } | 
|  | 586 |  | 
|  | 587 | static void test_round_rect_transform(skiatest::Reporter* reporter) { | 
|  | 588 | SkRRect rrect; | 
|  | 589 | { | 
|  | 590 | SkRect r = { 0, 0, kWidth, kHeight }; | 
|  | 591 | rrect.setRectXY(r, SkIntToScalar(4), SkIntToScalar(7)); | 
|  | 592 | test_transform_helper(reporter, rrect); | 
|  | 593 | } | 
|  | 594 | { | 
|  | 595 | SkRect r = { SkIntToScalar(5), SkIntToScalar(15), | 
|  | 596 | SkIntToScalar(27), SkIntToScalar(34) }; | 
|  | 597 | SkVector radii[4] = { { 0, SkIntToScalar(1) }, | 
|  | 598 | { SkIntToScalar(2), SkIntToScalar(3) }, | 
|  | 599 | { SkIntToScalar(4), SkIntToScalar(5) }, | 
|  | 600 | { SkIntToScalar(6), SkIntToScalar(7) } }; | 
|  | 601 | rrect.setRectRadii(r, radii); | 
|  | 602 | test_transform_helper(reporter, rrect); | 
|  | 603 | } | 
|  | 604 | } | 
|  | 605 |  | 
| robertphillips | e5c1e3c | 2014-06-27 08:59:26 -0700 | [diff] [blame] | 606 | // Test out the case where an oval already off in space is translated/scaled | 
|  | 607 | // further off into space - yielding numerical issues when the rect & radii | 
|  | 608 | // are transformed separatly | 
|  | 609 | // BUG=skia:2696 | 
|  | 610 | static void test_issue_2696(skiatest::Reporter* reporter) { | 
|  | 611 | SkRRect rrect; | 
|  | 612 | SkRect r = { 28443.8594f, 53.1428604f, 28446.7148f, 56.0000038f }; | 
|  | 613 | rrect.setOval(r); | 
|  | 614 |  | 
|  | 615 | SkMatrix xform; | 
|  | 616 | xform.setAll(2.44f,  0.0f, 485411.7f, | 
|  | 617 | 0.0f,  2.44f,   -438.7f, | 
|  | 618 | 0.0f,   0.0f,      1.0f); | 
|  | 619 | SkRRect dst; | 
|  | 620 |  | 
|  | 621 | bool success = rrect.transform(xform, &dst); | 
|  | 622 | REPORTER_ASSERT(reporter, success); | 
|  | 623 |  | 
|  | 624 | SkScalar halfWidth = SkScalarHalf(dst.width()); | 
|  | 625 | SkScalar halfHeight = SkScalarHalf(dst.height()); | 
|  | 626 |  | 
|  | 627 | for (int i = 0; i < 4; ++i) { | 
|  | 628 | REPORTER_ASSERT(reporter, | 
|  | 629 | SkScalarNearlyEqual(dst.radii((SkRRect::Corner)i).fX, halfWidth)); | 
|  | 630 | REPORTER_ASSERT(reporter, | 
|  | 631 | SkScalarNearlyEqual(dst.radii((SkRRect::Corner)i).fY, halfHeight)); | 
|  | 632 | } | 
|  | 633 | } | 
|  | 634 |  | 
| tfarina@chromium.org | e4fafb1 | 2013-12-12 21:11:12 +0000 | [diff] [blame] | 635 | DEF_TEST(RoundRect, reporter) { | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 636 | test_round_rect_basic(reporter); | 
|  | 637 | test_round_rect_rects(reporter); | 
|  | 638 | test_round_rect_ovals(reporter); | 
|  | 639 | test_round_rect_general(reporter); | 
|  | 640 | test_round_rect_iffy_parameters(reporter); | 
| mike@reedtribe.org | bcbef57 | 2012-12-23 23:11:21 +0000 | [diff] [blame] | 641 | test_inset(reporter); | 
| robertphillips@google.com | 32c1b66 | 2013-04-25 12:23:00 +0000 | [diff] [blame] | 642 | test_round_rect_contains_rect(reporter); | 
| scroggo@google.com | 20e3cd2 | 2013-11-05 15:54:42 +0000 | [diff] [blame] | 643 | test_round_rect_transform(reporter); | 
| robertphillips | e5c1e3c | 2014-06-27 08:59:26 -0700 | [diff] [blame] | 644 | test_issue_2696(reporter); | 
| reed | 694b0d1 | 2015-02-13 14:33:02 -0800 | [diff] [blame] | 645 | test_tricky_radii_crbug_458522(reporter); | 
|  | 646 | test_empty_crbug_458524(reporter); | 
| robertphillips@google.com | 5985e7c | 2012-11-29 13:24:55 +0000 | [diff] [blame] | 647 | } |