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

Side by Side Diff: tests/PathTest.cpp

Issue 65493004: increase coverage of SkPath.cpp, remove unused code (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: add test for contains; remove unused code 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/SkPathRef.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 2011 Google Inc. 2 * Copyright 2011 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 "SkCanvas.h" 9 #include "SkCanvas.h"
10 #include "SkPaint.h" 10 #include "SkPaint.h"
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 SkPath copy(original); 136 SkPath copy(original);
137 REPORTER_ASSERT(reporter, copy.getGenerationID() == original.getGenerationID ()); 137 REPORTER_ASSERT(reporter, copy.getGenerationID() == original.getGenerationID ());
138 REPORTER_ASSERT(reporter, copy.getSourcePath() == original.getSourcePath()); 138 REPORTER_ASSERT(reporter, copy.getSourcePath() == original.getSourcePath());
139 139
140 // Test assigment operator. Change generation ID, copy source path. 140 // Test assigment operator. Change generation ID, copy source path.
141 SkPath assign; 141 SkPath assign;
142 assignID = assign.getGenerationID(); 142 assignID = assign.getGenerationID();
143 assign = original; 143 assign = original;
144 REPORTER_ASSERT(reporter, assign.getGenerationID() != assignID); 144 REPORTER_ASSERT(reporter, assign.getGenerationID() != assignID);
145 REPORTER_ASSERT(reporter, assign.getSourcePath() == original.getSourcePath() ); 145 REPORTER_ASSERT(reporter, assign.getSourcePath() == original.getSourcePath() );
146 // exercise self-assignment test in SkPath::operator=
147 assignID = assign.getGenerationID();
bsalomon 2013/11/14 01:28:54 alignment?
caryclark 2013/11/14 15:29:35 I failed to realize that this entire block is an A
148 assign = assign;
149 REPORTER_ASSERT(reporter, assign.getGenerationID() == assignID);
146 150
147 // Test rewind. Change generation ID, don't touch source path. 151 // Test rewind. Change generation ID, don't touch source path.
148 copyID = copy.getGenerationID(); 152 copyID = copy.getGenerationID();
149 copy.rewind(); 153 copy.rewind();
150 REPORTER_ASSERT(reporter, copy.getGenerationID() != copyID); 154 REPORTER_ASSERT(reporter, copy.getGenerationID() != copyID);
151 REPORTER_ASSERT(reporter, copy.getSourcePath() == original.getSourcePath()); 155 REPORTER_ASSERT(reporter, copy.getSourcePath() == original.getSourcePath());
152 156
153 // Test reset. Change generation ID, don't touch source path. 157 // Test reset. Change generation ID, don't touch source path.
154 assignID = assign.getGenerationID(); 158 assignID = assign.getGenerationID();
155 assign.reset(); 159 assign.reset();
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 808
805 #ifdef SK_SCALAR_IS_FLOAT 809 #ifdef SK_SCALAR_IS_FLOAT
806 // triangle with one point really far from the origin. 810 // triangle with one point really far from the origin.
807 path.reset(); 811 path.reset();
808 // the first point is roughly 1.05e10, 1.05e10 812 // the first point is roughly 1.05e10, 1.05e10
809 path.moveTo(SkFloatToScalar(SkBits2Float(0x501c7652)), SkFloatToScalar(SkBit s2Float(0x501c7652))); 813 path.moveTo(SkFloatToScalar(SkBits2Float(0x501c7652)), SkFloatToScalar(SkBit s2Float(0x501c7652)));
810 path.lineTo(110 * SK_Scalar1, -10 * SK_Scalar1); 814 path.lineTo(110 * SK_Scalar1, -10 * SK_Scalar1);
811 path.lineTo(-10 * SK_Scalar1, 60 * SK_Scalar1); 815 path.lineTo(-10 * SK_Scalar1, 60 * SK_Scalar1);
812 check_direction(reporter, path, SkPath::kCCW_Direction); 816 check_direction(reporter, path, SkPath::kCCW_Direction);
813 #endif 817 #endif
818
819 path.reset();
820 path.conicTo(20, 0, 20, 20, 0.5f);
821 path.close();
822 check_direction(reporter, path, SkPath::kCW_Direction);
823
824 path.reset();
825 path.lineTo(1, 1e7f);
826 path.lineTo(1e7f, 2e7f);
827 path.close();
828 REPORTER_ASSERT(reporter, SkPath::kConvex_Convexity == path.getConvexity());
829 check_direction(reporter, path, SkPath::kCCW_Direction);
814 } 830 }
815 831
816 static void add_rect(SkPath* path, const SkRect& r) { 832 static void add_rect(SkPath* path, const SkRect& r) {
817 path->moveTo(r.fLeft, r.fTop); 833 path->moveTo(r.fLeft, r.fTop);
818 path->lineTo(r.fRight, r.fTop); 834 path->lineTo(r.fRight, r.fTop);
819 path->lineTo(r.fRight, r.fBottom); 835 path->lineTo(r.fRight, r.fBottom);
820 path->lineTo(r.fLeft, r.fBottom); 836 path->lineTo(r.fLeft, r.fBottom);
821 path->close(); 837 path->close();
822 } 838 }
823 839
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 { "0 0 10 10 10 0", SkPath::kConvex_Convexity, SkPath::kCCW_Direction }, 1155 { "0 0 10 10 10 0", SkPath::kConvex_Convexity, SkPath::kCCW_Direction },
1140 { "0 0 10 10 10 0 0 10", SkPath::kConcave_Convexity, kDontCheckDir }, 1156 { "0 0 10 10 10 0 0 10", SkPath::kConcave_Convexity, kDontCheckDir },
1141 { "0 0 10 0 0 10 -10 -10", SkPath::kConcave_Convexity, SkPath::kCW_Direc tion }, 1157 { "0 0 10 0 0 10 -10 -10", SkPath::kConcave_Convexity, SkPath::kCW_Direc tion },
1142 }; 1158 };
1143 1159
1144 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { 1160 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
1145 SkPath path; 1161 SkPath path;
1146 setFromString(&path, gRec[i].fPathStr); 1162 setFromString(&path, gRec[i].fPathStr);
1147 check_convexity(reporter, path, gRec[i].fExpectedConvexity); 1163 check_convexity(reporter, path, gRec[i].fExpectedConvexity);
1148 check_direction(reporter, path, gRec[i].fExpectedDirection); 1164 check_direction(reporter, path, gRec[i].fExpectedDirection);
1165 // check after setting the initial convex and direction
1166 if (kDontCheckDir != gRec[i].fExpectedDirection) {
1167 SkPath copy(path);
1168 SkPath::Direction dir;
1169 bool foundDir = copy.cheapComputeDirection(&dir);
1170 REPORTER_ASSERT(reporter, (gRec[i].fExpectedDirection == SkPath::kUn known_Direction)
1171 ^ foundDir);
1172 REPORTER_ASSERT(reporter, !foundDir || gRec[i].fExpectedDirection == dir);
1173 check_convexity(reporter, copy, gRec[i].fExpectedConvexity);
1174 }
1175 REPORTER_ASSERT(reporter, gRec[i].fExpectedConvexity == path.getConvexit y());
1176 check_direction(reporter, path, gRec[i].fExpectedDirection);
1149 } 1177 }
1150 } 1178 }
1151 1179
1152 static void test_isLine(skiatest::Reporter* reporter) { 1180 static void test_isLine(skiatest::Reporter* reporter) {
1153 SkPath path; 1181 SkPath path;
1154 SkPoint pts[2]; 1182 SkPoint pts[2];
1155 const SkScalar value = SkIntToScalar(5); 1183 const SkScalar value = SkIntToScalar(5);
1156 1184
1157 REPORTER_ASSERT(reporter, !path.isLine(NULL)); 1185 REPORTER_ASSERT(reporter, !path.isLine(NULL));
1158 1186
1159 // set some non-zero values 1187 // set some non-zero values
1160 pts[0].set(value, value); 1188 pts[0].set(value, value);
1161 pts[1].set(value, value); 1189 pts[1].set(value, value);
1162 REPORTER_ASSERT(reporter, !path.isLine(pts)); 1190 REPORTER_ASSERT(reporter, !path.isLine(pts));
1163 // check that pts was untouched 1191 // check that pts was untouched
1164 REPORTER_ASSERT(reporter, pts[0].equals(value, value)); 1192 REPORTER_ASSERT(reporter, pts[0].equals(value, value));
1165 REPORTER_ASSERT(reporter, pts[1].equals(value, value)); 1193 REPORTER_ASSERT(reporter, pts[1].equals(value, value));
1166 1194
1167 const SkScalar moveX = SkIntToScalar(1); 1195 const SkScalar moveX = SkIntToScalar(1);
1168 const SkScalar moveY = SkIntToScalar(2); 1196 const SkScalar moveY = SkIntToScalar(2);
1169 SkASSERT(value != moveX && value != moveY); 1197 REPORTER_ASSERT(reporter, value != moveX && value != moveY);
1170 1198
1171 path.moveTo(moveX, moveY); 1199 path.moveTo(moveX, moveY);
1172 REPORTER_ASSERT(reporter, !path.isLine(NULL)); 1200 REPORTER_ASSERT(reporter, !path.isLine(NULL));
1173 REPORTER_ASSERT(reporter, !path.isLine(pts)); 1201 REPORTER_ASSERT(reporter, !path.isLine(pts));
1174 // check that pts was untouched 1202 // check that pts was untouched
1175 REPORTER_ASSERT(reporter, pts[0].equals(value, value)); 1203 REPORTER_ASSERT(reporter, pts[0].equals(value, value));
1176 REPORTER_ASSERT(reporter, pts[1].equals(value, value)); 1204 REPORTER_ASSERT(reporter, pts[1].equals(value, value));
1177 1205
1178 const SkScalar lineX = SkIntToScalar(2); 1206 const SkScalar lineX = SkIntToScalar(2);
1179 const SkScalar lineY = SkIntToScalar(2); 1207 const SkScalar lineY = SkIntToScalar(2);
1180 SkASSERT(value != lineX && value != lineY); 1208 REPORTER_ASSERT(reporter, value != lineX && value != lineY);
1181 1209
1182 path.lineTo(lineX, lineY); 1210 path.lineTo(lineX, lineY);
1183 REPORTER_ASSERT(reporter, path.isLine(NULL)); 1211 REPORTER_ASSERT(reporter, path.isLine(NULL));
1184 1212
1185 REPORTER_ASSERT(reporter, !pts[0].equals(moveX, moveY)); 1213 REPORTER_ASSERT(reporter, !pts[0].equals(moveX, moveY));
1186 REPORTER_ASSERT(reporter, !pts[1].equals(lineX, lineY)); 1214 REPORTER_ASSERT(reporter, !pts[1].equals(lineX, lineY));
1187 REPORTER_ASSERT(reporter, path.isLine(pts)); 1215 REPORTER_ASSERT(reporter, path.isLine(pts));
1188 REPORTER_ASSERT(reporter, pts[0].equals(moveX, moveY)); 1216 REPORTER_ASSERT(reporter, pts[0].equals(moveX, moveY));
1189 REPORTER_ASSERT(reporter, pts[1].equals(lineX, lineY)); 1217 REPORTER_ASSERT(reporter, pts[1].equals(lineX, lineY));
1190 1218
1191 path.lineTo(0, 0); // too many points/verbs 1219 path.lineTo(0, 0); // too many points/verbs
1192 REPORTER_ASSERT(reporter, !path.isLine(NULL)); 1220 REPORTER_ASSERT(reporter, !path.isLine(NULL));
1193 REPORTER_ASSERT(reporter, !path.isLine(pts)); 1221 REPORTER_ASSERT(reporter, !path.isLine(pts));
1194 REPORTER_ASSERT(reporter, pts[0].equals(moveX, moveY)); 1222 REPORTER_ASSERT(reporter, pts[0].equals(moveX, moveY));
1195 REPORTER_ASSERT(reporter, pts[1].equals(lineX, lineY)); 1223 REPORTER_ASSERT(reporter, pts[1].equals(lineX, lineY));
1196 } 1224 }
1197 1225
1198 static void test_conservativelyContains(skiatest::Reporter* reporter) { 1226 static void test_conservativelyContains(skiatest::Reporter* reporter) {
1199 SkPath path; 1227 SkPath path;
1200 1228
1201 // kBaseRect is used to construct most our test paths: a rect, a circle, and a round-rect. 1229 // kBaseRect is used to construct most our test paths: a rect, a circle, and a round-rect.
1202 static const SkRect kBaseRect = SkRect::MakeWH(SkIntToScalar(100), SkIntToSc alar(100)); 1230 static const SkRect kBaseRect = SkRect::MakeWH(SkIntToScalar(100), SkIntToSc alar(100));
1203 1231
1204 // A circle that bounds kBaseRect (with a significant amount of slop) 1232 // A circle that bounds kBaseRect (with a significant amount of slop)
1205 SkScalar circleR = SkMaxScalar(kBaseRect.width(), kBaseRect.height()); 1233 SkScalar circleR = SkMaxScalar(kBaseRect.width(), kBaseRect.height());
1206 circleR = SkScalarMul(circleR, SkFloatToScalar(1.75f)) / 2; 1234 circleR = SkScalarMul(circleR, 1.75f) / 2;
1207 static const SkPoint kCircleC = {kBaseRect.centerX(), kBaseRect.centerY()}; 1235 static const SkPoint kCircleC = {kBaseRect.centerX(), kBaseRect.centerY()};
1208 1236
1209 // round-rect radii 1237 // round-rect radii
1210 static const SkScalar kRRRadii[] = {SkIntToScalar(5), SkIntToScalar(3)}; 1238 static const SkScalar kRRRadii[] = {SkIntToScalar(5), SkIntToScalar(3)};
1211 1239
1212 static const struct SUPPRESS_VISIBILITY_WARNING { 1240 static const struct SUPPRESS_VISIBILITY_WARNING {
1213 SkRect fQueryRect; 1241 SkRect fQueryRect;
1214 bool fInRect; 1242 bool fInRect;
1215 bool fInCircle; 1243 bool fInCircle;
1216 bool fInRR; 1244 bool fInRR;
1245 bool fInCubicRR;
1217 } kQueries[] = { 1246 } kQueries[] = {
1218 {kBaseRect, true, true, false}, 1247 {kBaseRect, true, true, false, false},
1219 1248
1220 // rect well inside of kBaseRect 1249 // rect well inside of kBaseRect
1221 {SkRect::MakeLTRB(kBaseRect.fLeft + SkFloatToScalar(0.25f)*kBaseRect.wid th(), 1250 {SkRect::MakeLTRB(kBaseRect.fLeft + SkFloatToScalar(0.25f)*kBaseRect.wid th(),
1222 kBaseRect.fTop + SkFloatToScalar(0.25f)*kBaseRect.heig ht(), 1251 kBaseRect.fTop + SkFloatToScalar(0.25f)*kBaseRect.heig ht(),
1223 kBaseRect.fRight - SkFloatToScalar(0.25f)*kBaseRect.wi dth(), 1252 kBaseRect.fRight - SkFloatToScalar(0.25f)*kBaseRect.wi dth(),
1224 kBaseRect.fBottom - SkFloatToScalar(0.25f)*kBaseRect.h eight()), 1253 kBaseRect.fBottom - SkFloatToScalar(0.25f)*kBaseRect.h eight()),
1225 true, true, true}, 1254 true, true, true, true},
1226 1255
1227 // rects with edges off by one from kBaseRect's edges 1256 // rects with edges off by one from kBaseRect's edges
1228 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop, 1257 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop,
1229 kBaseRect.width(), kBaseRect.height() + 1), 1258 kBaseRect.width(), kBaseRect.height() + 1),
1230 false, true, false}, 1259 false, true, false, false},
1231 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop, 1260 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop,
1232 kBaseRect.width() + 1, kBaseRect.height()), 1261 kBaseRect.width() + 1, kBaseRect.height()),
1233 false, true, false}, 1262 false, true, false, false},
1234 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop, 1263 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop,
1235 kBaseRect.width() + 1, kBaseRect.height() + 1), 1264 kBaseRect.width() + 1, kBaseRect.height() + 1),
1236 false, true, false}, 1265 false, true, false, false},
1237 {SkRect::MakeXYWH(kBaseRect.fLeft - 1, kBaseRect.fTop, 1266 {SkRect::MakeXYWH(kBaseRect.fLeft - 1, kBaseRect.fTop,
1238 kBaseRect.width(), kBaseRect.height()), 1267 kBaseRect.width(), kBaseRect.height()),
1239 false, true, false}, 1268 false, true, false, false},
1240 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop - 1, 1269 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop - 1,
1241 kBaseRect.width(), kBaseRect.height()), 1270 kBaseRect.width(), kBaseRect.height()),
1242 false, true, false}, 1271 false, true, false, false},
1243 {SkRect::MakeXYWH(kBaseRect.fLeft - 1, kBaseRect.fTop, 1272 {SkRect::MakeXYWH(kBaseRect.fLeft - 1, kBaseRect.fTop,
1244 kBaseRect.width() + 2, kBaseRect.height()), 1273 kBaseRect.width() + 2, kBaseRect.height()),
1245 false, true, false}, 1274 false, true, false, false},
1246 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop - 1, 1275 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop - 1,
1247 kBaseRect.width() + 2, kBaseRect.height()), 1276 kBaseRect.width() + 2, kBaseRect.height()),
1248 false, true, false}, 1277 false, true, false, false},
1249 1278
1250 // zero-w/h rects at each corner of kBaseRect 1279 // zero-w/h rects at each corner of kBaseRect
1251 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop, 0, 0), true, true, fa lse}, 1280 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop, 0, 0), true, true, fa lse, false},
1252 {SkRect::MakeXYWH(kBaseRect.fRight, kBaseRect.fTop, 0, 0), true, true, f alse}, 1281 {SkRect::MakeXYWH(kBaseRect.fRight, kBaseRect.fTop, 0, 0), true, true, f alse, true},
1253 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fBottom, 0, 0), true, true, false}, 1282 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fBottom, 0, 0), true, true, false, true},
1254 {SkRect::MakeXYWH(kBaseRect.fRight, kBaseRect.fBottom, 0, 0), true, true , false}, 1283 {SkRect::MakeXYWH(kBaseRect.fRight, kBaseRect.fBottom, 0, 0), true, true , false, true},
1255 1284
1256 // far away rect 1285 // far away rect
1257 {SkRect::MakeXYWH(10 * kBaseRect.fRight, 10 * kBaseRect.fBottom, 1286 {SkRect::MakeXYWH(10 * kBaseRect.fRight, 10 * kBaseRect.fBottom,
1258 SkIntToScalar(10), SkIntToScalar(10)), 1287 SkIntToScalar(10), SkIntToScalar(10)),
1259 false, false, false}, 1288 false, false, false, false},
1260 1289
1261 // very large rect containing kBaseRect 1290 // very large rect containing kBaseRect
1262 {SkRect::MakeXYWH(kBaseRect.fLeft - 5 * kBaseRect.width(), 1291 {SkRect::MakeXYWH(kBaseRect.fLeft - 5 * kBaseRect.width(),
1263 kBaseRect.fTop - 5 * kBaseRect.height(), 1292 kBaseRect.fTop - 5 * kBaseRect.height(),
1264 11 * kBaseRect.width(), 11 * kBaseRect.height()), 1293 11 * kBaseRect.width(), 11 * kBaseRect.height()),
1265 false, false, false}, 1294 false, false, false, false},
1266 1295
1267 // skinny rect that spans same y-range as kBaseRect 1296 // skinny rect that spans same y-range as kBaseRect
1268 {SkRect::MakeXYWH(kBaseRect.centerX(), kBaseRect.fTop, 1297 {SkRect::MakeXYWH(kBaseRect.centerX(), kBaseRect.fTop,
1269 SkIntToScalar(1), kBaseRect.height()), 1298 SkIntToScalar(1), kBaseRect.height()),
1270 true, true, true}, 1299 true, true, true, true},
1271 1300
1272 // short rect that spans same x-range as kBaseRect 1301 // short rect that spans same x-range as kBaseRect
1273 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.centerY(), kBaseRect.width( ), SkScalar(1)), 1302 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.centerY(), kBaseRect.width( ), SkScalar(1)),
1274 true, true, true}, 1303 true, true, true, true},
1275 1304
1276 // skinny rect that spans slightly larger y-range than kBaseRect 1305 // skinny rect that spans slightly larger y-range than kBaseRect
1277 {SkRect::MakeXYWH(kBaseRect.centerX(), kBaseRect.fTop, 1306 {SkRect::MakeXYWH(kBaseRect.centerX(), kBaseRect.fTop,
1278 SkIntToScalar(1), kBaseRect.height() + 1), 1307 SkIntToScalar(1), kBaseRect.height() + 1),
1279 false, true, false}, 1308 false, true, false, false},
1280 1309
1281 // short rect that spans slightly larger x-range than kBaseRect 1310 // short rect that spans slightly larger x-range than kBaseRect
1282 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.centerY(), 1311 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.centerY(),
1283 kBaseRect.width() + 1, SkScalar(1)), 1312 kBaseRect.width() + 1, SkScalar(1)),
1284 false, true, false}, 1313 false, true, false, false},
1285 }; 1314 };
1286 1315
1287 for (int inv = 0; inv < 4; ++inv) { 1316 for (int inv = 0; inv < 4; ++inv) {
1288 for (size_t q = 0; q < SK_ARRAY_COUNT(kQueries); ++q) { 1317 for (size_t q = 0; q < SK_ARRAY_COUNT(kQueries); ++q) {
1289 SkRect qRect = kQueries[q].fQueryRect; 1318 SkRect qRect = kQueries[q].fQueryRect;
1290 if (inv & 0x1) { 1319 if (inv & 0x1) {
1291 SkTSwap(qRect.fLeft, qRect.fRight); 1320 SkTSwap(qRect.fLeft, qRect.fRight);
1292 } 1321 }
1293 if (inv & 0x2) { 1322 if (inv & 0x2) {
1294 SkTSwap(qRect.fTop, qRect.fBottom); 1323 SkTSwap(qRect.fTop, qRect.fBottom);
1295 } 1324 }
1296 for (int d = 0; d < 2; ++d) { 1325 for (int d = 0; d < 2; ++d) {
1297 SkPath::Direction dir = d ? SkPath::kCCW_Direction : SkPath::kCW _Direction; 1326 SkPath::Direction dir = d ? SkPath::kCCW_Direction : SkPath::kCW _Direction;
1298 path.reset(); 1327 path.reset();
1299 path.addRect(kBaseRect, dir); 1328 path.addRect(kBaseRect, dir);
1300 REPORTER_ASSERT(reporter, kQueries[q].fInRect == 1329 REPORTER_ASSERT(reporter, kQueries[q].fInRect ==
1301 path.conservativelyContainsRect(qRect) ); 1330 path.conservativelyContainsRect(qRect) );
1302 1331
1303 path.reset(); 1332 path.reset();
1304 path.addCircle(kCircleC.fX, kCircleC.fY, circleR, dir); 1333 path.addCircle(kCircleC.fX, kCircleC.fY, circleR, dir);
1305 REPORTER_ASSERT(reporter, kQueries[q].fInCircle == 1334 REPORTER_ASSERT(reporter, kQueries[q].fInCircle ==
1306 path.conservativelyContainsRect(qRect) ); 1335 path.conservativelyContainsRect(qRect) );
1307 1336
1308 path.reset(); 1337 path.reset();
1309 path.addRoundRect(kBaseRect, kRRRadii[0], kRRRadii[1], dir); 1338 path.addRoundRect(kBaseRect, kRRRadii[0], kRRRadii[1], dir);
1310 REPORTER_ASSERT(reporter, kQueries[q].fInRR == 1339 REPORTER_ASSERT(reporter, kQueries[q].fInRR ==
1311 path.conservativelyContainsRect(qRect) ); 1340 path.conservativelyContainsRect(qRect) );
1341
1342 path.reset();
1343 path.moveTo(kBaseRect.fLeft + kRRRadii[0], kBaseRect.fTop);
1344 path.cubicTo(kBaseRect.fLeft + kRRRadii[0] / 2, kBaseRect.fTop,
1345 kBaseRect.fLeft, kBaseRect.fTop + kRRRadii[1] / 2,
1346 kBaseRect.fLeft, kBaseRect.fTop + kRRRadii[1]);
1347 path.lineTo(kBaseRect.fLeft, kBaseRect.fBottom);
1348 path.lineTo(kBaseRect.fRight, kBaseRect.fBottom);
1349 path.lineTo(kBaseRect.fRight, kBaseRect.fTop);
1350 path.close();
1351 REPORTER_ASSERT(reporter, kQueries[q].fInCubicRR ==
1352 path.conservativelyContainsRect(qRect) );
1353
1312 } 1354 }
1313 // Slightly non-convex shape, shouldn't contain any rects. 1355 // Slightly non-convex shape, shouldn't contain any rects.
1314 path.reset(); 1356 path.reset();
1315 path.moveTo(0, 0); 1357 path.moveTo(0, 0);
1316 path.lineTo(SkIntToScalar(50), SkFloatToScalar(0.05f)); 1358 path.lineTo(SkIntToScalar(50), SkFloatToScalar(0.05f));
1317 path.lineTo(SkIntToScalar(100), 0); 1359 path.lineTo(SkIntToScalar(100), 0);
1318 path.lineTo(SkIntToScalar(100), SkIntToScalar(100)); 1360 path.lineTo(SkIntToScalar(100), SkIntToScalar(100));
1319 path.lineTo(0, SkIntToScalar(100)); 1361 path.lineTo(0, SkIntToScalar(100));
1320 path.close(); 1362 path.close();
1321 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(qRect)); 1363 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(qRect));
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
1829 SkRect rect = SkRect::MakeWH(10, 10); 1871 SkRect rect = SkRect::MakeWH(10, 10);
1830 oval.addOval(rect); 1872 oval.addOval(rect);
1831 1873
1832 write_and_read_back(reporter, oval); 1874 write_and_read_back(reporter, oval);
1833 } 1875 }
1834 } 1876 }
1835 1877
1836 static void test_transform(skiatest::Reporter* reporter) { 1878 static void test_transform(skiatest::Reporter* reporter) {
1837 SkPath p, p1; 1879 SkPath p, p1;
1838 1880
1881 #define CONIC_PERSPECTIVE_BUG_FIXED 0
1839 static const SkPoint pts[] = { 1882 static const SkPoint pts[] = {
1840 { 0, 0 }, 1883 { 0, 0 }, // move
1841 { SkIntToScalar(10), SkIntToScalar(10) }, 1884 { SkIntToScalar(10), SkIntToScalar(10) }, // line
1842 { SkIntToScalar(20), SkIntToScalar(10) }, { SkIntToScalar(20), 0 }, 1885 { SkIntToScalar(20), SkIntToScalar(10) }, { SkIntToScalar(20), 0 }, // quad
1843 { 0, 0 }, { 0, SkIntToScalar(10) }, { SkIntToScalar(1), SkIntToScalar(10 ) } 1886 { 0, 0 }, { 0, SkIntToScalar(10) }, { SkIntToScalar(1), SkIntToScalar(10 ) }, // cubic
1887 #if CONIC_PERSPECTIVE_BUG_FIXED
1888 { 0, 0 }, { SkIntToScalar(20), SkIntToScalar(10) }, // conic
1889 #endif
1844 }; 1890 };
1891 const int kPtCount = SK_ARRAY_COUNT(pts);
1845 p.moveTo(pts[0]); 1892 p.moveTo(pts[0]);
1846 p.lineTo(pts[1]); 1893 p.lineTo(pts[1]);
1847 p.quadTo(pts[2], pts[3]); 1894 p.quadTo(pts[2], pts[3]);
1848 p.cubicTo(pts[4], pts[5], pts[6]); 1895 p.cubicTo(pts[4], pts[5], pts[6]);
1849 1896 #if CONIC_PERSPECTIVE_BUG_FIXED
1897 p.conicTo(pts[4], pts[5], 0.5f);
1898 #endif
1899 p.close();
1850 SkMatrix matrix; 1900 SkMatrix matrix;
1851 matrix.reset(); 1901 matrix.reset();
1852 p.transform(matrix, &p1); 1902 p.transform(matrix, &p1);
1853 REPORTER_ASSERT(reporter, p == p1); 1903 REPORTER_ASSERT(reporter, p == p1);
1854 1904
1855 matrix.setScale(SK_Scalar1 * 2, SK_Scalar1 * 3); 1905 matrix.setScale(SK_Scalar1 * 2, SK_Scalar1 * 3);
1856 p.transform(matrix, &p1); 1906 p.transform(matrix, &p1);
1857 SkPoint pts1[7]; 1907 SkPoint pts1[kPtCount];
1858 int count = p1.getPoints(pts1, 7); 1908 int count = p1.getPoints(pts1, kPtCount);
1859 REPORTER_ASSERT(reporter, 7 == count); 1909 REPORTER_ASSERT(reporter, kPtCount == count);
1860 for (int i = 0; i < count; ++i) { 1910 for (int i = 0; i < count; ++i) {
1861 SkPoint newPt = SkPoint::Make(pts[i].fX * 2, pts[i].fY * 3); 1911 SkPoint newPt = SkPoint::Make(pts[i].fX * 2, pts[i].fY * 3);
1862 REPORTER_ASSERT(reporter, newPt == pts1[i]); 1912 REPORTER_ASSERT(reporter, newPt == pts1[i]);
1863 } 1913 }
1914 matrix.reset();
1915 matrix.setPerspX(SkScalarToPersp(4));
1916 p.transform(matrix, &p1);
1917 REPORTER_ASSERT(reporter, matrix.invert(&matrix));
1918 p1.transform(matrix, NULL);
1919 SkRect pBounds = p.getBounds();
1920 SkRect p1Bounds = p1.getBounds();
1921 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(pBounds.fLeft, p1Bounds.fLeft) );
1922 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(pBounds.fTop, p1Bounds.fTop));
1923 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(pBounds.fRight, p1Bounds.fRigh t));
1924 REPORTER_ASSERT(reporter, SkScalarNearlyEqual(pBounds.fBottom, p1Bounds.fBot tom));
1925
1926 matrix.reset();
1927 p.reset();
1928 p.addCircle(0, 0, 1, SkPath::kCW_Direction);
1929 p.transform(matrix, &p1);
1930 REPORTER_ASSERT(reporter, p1.cheapIsDirection(SkPath::kCW_Direction));
1931 matrix.setScaleX(-1);
1932 p.transform(matrix, &p1);
1933 REPORTER_ASSERT(reporter, p1.cheapIsDirection(SkPath::kCCW_Direction));
1934 matrix.setAll(1, 1, 0, 1, 1, 0, 0, 0, 1);
1935 p.transform(matrix, &p1);
1936 REPORTER_ASSERT(reporter, p1.cheapIsDirection(SkPath::kUnknown_Direction));
1864 } 1937 }
1865 1938
1866 static void test_zero_length_paths(skiatest::Reporter* reporter) { 1939 static void test_zero_length_paths(skiatest::Reporter* reporter) {
1867 SkPath p; 1940 SkPath p;
1868 uint8_t verbs[32]; 1941 uint8_t verbs[32];
1869 1942
1870 struct SUPPRESS_VISIBILITY_WARNING zeroPathTestData { 1943 struct SUPPRESS_VISIBILITY_WARNING zeroPathTestData {
1871 const char* testPath; 1944 const char* testPath;
1872 const size_t numResultPts; 1945 const size_t numResultPts;
1873 const SkRect resultBound; 1946 const SkRect resultBound;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
2057 int j = 0, l = 0; 2130 int j = 0, l = 0;
2058 do { 2131 do {
2059 REPORTER_ASSERT(reporter, iter.next(pts, gIterTests[i].consumeDegene rates) == gIterTests[i].resultVerbs[j]); 2132 REPORTER_ASSERT(reporter, iter.next(pts, gIterTests[i].consumeDegene rates) == gIterTests[i].resultVerbs[j]);
2060 for (int k = 0; k < (int)gIterTests[i].numResultPtsPerVerb[j]; ++k) { 2133 for (int k = 0; k < (int)gIterTests[i].numResultPtsPerVerb[j]; ++k) {
2061 REPORTER_ASSERT(reporter, pts[k] == gIterTests[i].resultPts[l++] ); 2134 REPORTER_ASSERT(reporter, pts[k] == gIterTests[i].resultPts[l++] );
2062 } 2135 }
2063 } while (gIterTests[i].resultVerbs[j++] != SkPath::kDone_Verb); 2136 } while (gIterTests[i].resultVerbs[j++] != SkPath::kDone_Verb);
2064 REPORTER_ASSERT(reporter, j == (int)gIterTests[i].numResultVerbs); 2137 REPORTER_ASSERT(reporter, j == (int)gIterTests[i].numResultVerbs);
2065 } 2138 }
2066 2139
2140 p.reset();
2141 iter.setPath(p, false);
2142 REPORTER_ASSERT(reporter, !iter.isClosedContour());
2143 p.lineTo(1, 1);
2144 p.close();
2145 iter.setPath(p, false);
2146 REPORTER_ASSERT(reporter, iter.isClosedContour());
2147 p.reset();
2148 iter.setPath(p, true);
2149 REPORTER_ASSERT(reporter, !iter.isClosedContour());
2150 p.lineTo(1, 1);
2151 iter.setPath(p, true);
2152 REPORTER_ASSERT(reporter, iter.isClosedContour());
2153 p.moveTo(0, 0);
2154 p.lineTo(2, 2);
2155 iter.setPath(p, false);
2156 REPORTER_ASSERT(reporter, !iter.isClosedContour());
2157
2158 // this checks to see if the NaN logic is executed in SkPath::autoClose(), b ut does not
2159 // check to see if the result is correct.
2160 for (int setNaN = 0; setNaN < 4; ++setNaN) {
2161 p.reset();
2162 p.moveTo(setNaN == 0 ? SK_ScalarNaN : 0, setNaN == 1 ? SK_ScalarNaN : 0) ;
2163 p.lineTo(setNaN == 2 ? SK_ScalarNaN : 1, setNaN == 3 ? SK_ScalarNaN : 1) ;
2164 iter.setPath(p, true);
2165 iter.next(pts, false);
2166 iter.next(pts, false);
2167 REPORTER_ASSERT(reporter, SkPath::kClose_Verb == iter.next(pts, false));
2168 }
2169
2170 p.reset();
2171 p.quadTo(0, 0, 0, 0);
2172 iter.setPath(p, false);
2173 iter.next(pts, false);
2174 REPORTER_ASSERT(reporter, SkPath::kQuad_Verb == iter.next(pts, false));
2175 iter.setPath(p, false);
2176 iter.next(pts, false);
2177 REPORTER_ASSERT(reporter, SkPath::kDone_Verb == iter.next(pts, true));
2178
2179 p.reset();
2180 p.cubicTo(0, 0, 0, 0, 0, 0);
2181 iter.setPath(p, false);
2182 iter.next(pts, false);
2183 REPORTER_ASSERT(reporter, SkPath::kCubic_Verb == iter.next(pts, false));
2184 iter.setPath(p, false);
2185 iter.next(pts, false);
2186 REPORTER_ASSERT(reporter, SkPath::kDone_Verb == iter.next(pts, true));
2187
2067 // The GM degeneratesegments.cpp test is more extensive 2188 // The GM degeneratesegments.cpp test is more extensive
2068 } 2189 }
2069 2190
2070 static void test_raw_iter(skiatest::Reporter* reporter) { 2191 static void test_raw_iter(skiatest::Reporter* reporter) {
2071 SkPath p; 2192 SkPath p;
2072 SkPoint pts[4]; 2193 SkPoint pts[4];
2073 2194
2074 // Test an iterator with no path 2195 // Test an iterator with no path
2075 SkPath::RawIter noPathIter; 2196 SkPath::RawIter noPathIter;
2076 REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb); 2197 REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
2316 SkPath::Direction dir) { 2437 SkPath::Direction dir) {
2317 SkPath tmp; 2438 SkPath tmp;
2318 2439
2319 SkMatrix m; 2440 SkMatrix m;
2320 m.setSkew(SkIntToScalar(3), SkIntToScalar(5)); 2441 m.setSkew(SkIntToScalar(3), SkIntToScalar(5));
2321 path.transform(m, &tmp); 2442 path.transform(m, &tmp);
2322 // this matrix reverses the direction. 2443 // this matrix reverses the direction.
2323 if (SkPath::kCCW_Direction == dir) { 2444 if (SkPath::kCCW_Direction == dir) {
2324 dir = SkPath::kCW_Direction; 2445 dir = SkPath::kCW_Direction;
2325 } else { 2446 } else {
2326 SkASSERT(SkPath::kCW_Direction == dir); 2447 REPORTER_ASSERT(reporter, SkPath::kCW_Direction == dir);
2327 dir = SkPath::kCCW_Direction; 2448 dir = SkPath::kCCW_Direction;
2328 } 2449 }
2329 check_for_circle(reporter, tmp, false, dir); 2450 check_for_circle(reporter, tmp, false, dir);
2330 } 2451 }
2331 2452
2332 static void test_circle_translate(skiatest::Reporter* reporter, 2453 static void test_circle_translate(skiatest::Reporter* reporter,
2333 const SkPath& path, 2454 const SkPath& path,
2334 SkPath::Direction dir) { 2455 SkPath::Direction dir) {
2335 SkPath tmp; 2456 SkPath tmp;
2336 2457
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2374 SkPath::Direction dir) { 2495 SkPath::Direction dir) {
2375 SkPath tmp; 2496 SkPath tmp;
2376 SkMatrix m; 2497 SkMatrix m;
2377 m.reset(); 2498 m.reset();
2378 m.setScaleX(-SK_Scalar1); 2499 m.setScaleX(-SK_Scalar1);
2379 path.transform(m, &tmp); 2500 path.transform(m, &tmp);
2380 2501
2381 if (SkPath::kCW_Direction == dir) { 2502 if (SkPath::kCW_Direction == dir) {
2382 dir = SkPath::kCCW_Direction; 2503 dir = SkPath::kCCW_Direction;
2383 } else { 2504 } else {
2384 SkASSERT(SkPath::kCCW_Direction == dir); 2505 REPORTER_ASSERT(reporter, SkPath::kCCW_Direction == dir);
2385 dir = SkPath::kCW_Direction; 2506 dir = SkPath::kCW_Direction;
2386 } 2507 }
2387 2508
2388 check_for_circle(reporter, tmp, true, dir); 2509 check_for_circle(reporter, tmp, true, dir);
2389 } 2510 }
2390 2511
2391 static void test_circle_mirror_y(skiatest::Reporter* reporter, 2512 static void test_circle_mirror_y(skiatest::Reporter* reporter,
2392 const SkPath& path, 2513 const SkPath& path,
2393 SkPath::Direction dir) { 2514 SkPath::Direction dir) {
2394 SkPath tmp; 2515 SkPath tmp;
2395 SkMatrix m; 2516 SkMatrix m;
2396 m.reset(); 2517 m.reset();
2397 m.setScaleY(-SK_Scalar1); 2518 m.setScaleY(-SK_Scalar1);
2398 path.transform(m, &tmp); 2519 path.transform(m, &tmp);
2399 2520
2400 if (SkPath::kCW_Direction == dir) { 2521 if (SkPath::kCW_Direction == dir) {
2401 dir = SkPath::kCCW_Direction; 2522 dir = SkPath::kCCW_Direction;
2402 } else { 2523 } else {
2403 SkASSERT(SkPath::kCCW_Direction == dir); 2524 REPORTER_ASSERT(reporter, SkPath::kCCW_Direction == dir);
2404 dir = SkPath::kCW_Direction; 2525 dir = SkPath::kCW_Direction;
2405 } 2526 }
2406 2527
2407 check_for_circle(reporter, tmp, true, dir); 2528 check_for_circle(reporter, tmp, true, dir);
2408 } 2529 }
2409 2530
2410 static void test_circle_mirror_xy(skiatest::Reporter* reporter, 2531 static void test_circle_mirror_xy(skiatest::Reporter* reporter,
2411 const SkPath& path, 2532 const SkPath& path,
2412 SkPath::Direction dir) { 2533 SkPath::Direction dir) {
2413 SkPath tmp; 2534 SkPath tmp;
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
2566 REPORTER_ASSERT(reporter, 0 == p.countPoints()); 2687 REPORTER_ASSERT(reporter, 0 == p.countPoints());
2567 REPORTER_ASSERT(reporter, 0 == p.countVerbs()); 2688 REPORTER_ASSERT(reporter, 0 == p.countVerbs());
2568 REPORTER_ASSERT(reporter, 0 == p.getSegmentMasks()); 2689 REPORTER_ASSERT(reporter, 0 == p.getSegmentMasks());
2569 REPORTER_ASSERT(reporter, p.isConvex()); 2690 REPORTER_ASSERT(reporter, p.isConvex());
2570 REPORTER_ASSERT(reporter, p.getFillType() == SkPath::kWinding_FillType); 2691 REPORTER_ASSERT(reporter, p.getFillType() == SkPath::kWinding_FillType);
2571 REPORTER_ASSERT(reporter, !p.isInverseFillType()); 2692 REPORTER_ASSERT(reporter, !p.isInverseFillType());
2572 REPORTER_ASSERT(reporter, p == empty); 2693 REPORTER_ASSERT(reporter, p == empty);
2573 REPORTER_ASSERT(reporter, !(p != empty)); 2694 REPORTER_ASSERT(reporter, !(p != empty));
2574 } 2695 }
2575 2696
2576 static void test_rrect_is_convex(skiatest::Reporter* reporter, SkPath* path) { 2697 static void test_rrect_is_convex(skiatest::Reporter* reporter, SkPath* path,
2698 SkPath::Direction dir) {
2577 REPORTER_ASSERT(reporter, path->isConvex()); 2699 REPORTER_ASSERT(reporter, path->isConvex());
2700 REPORTER_ASSERT(reporter, path->cheapIsDirection(dir));
2578 path->setConvexity(SkPath::kUnknown_Convexity); 2701 path->setConvexity(SkPath::kUnknown_Convexity);
2579 REPORTER_ASSERT(reporter, path->isConvex()); 2702 REPORTER_ASSERT(reporter, path->isConvex());
2580 path->reset(); 2703 path->reset();
2581 } 2704 }
2582 2705
2583 static void test_rrect(skiatest::Reporter* reporter) { 2706 static void test_rrect(skiatest::Reporter* reporter) {
2584 SkPath p; 2707 SkPath p;
2585 SkRRect rr; 2708 SkRRect rr;
2586 SkVector radii[] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}}; 2709 SkVector radii[] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
2587 SkRect r = {10, 20, 30, 40}; 2710 SkRect r = {10, 20, 30, 40};
2588 rr.setRectRadii(r, radii); 2711 rr.setRectRadii(r, radii);
2589 p.addRRect(rr); 2712 p.addRRect(rr);
2590 test_rrect_is_convex(reporter, &p); 2713 test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
2591 p.addRRect(rr, SkPath::kCCW_Direction); 2714 p.addRRect(rr, SkPath::kCCW_Direction);
2592 test_rrect_is_convex(reporter, &p); 2715 test_rrect_is_convex(reporter, &p, SkPath::kCCW_Direction);
2593 p.addRoundRect(r, &radii[0].fX); 2716 p.addRoundRect(r, &radii[0].fX);
2594 test_rrect_is_convex(reporter, &p); 2717 test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
2595 p.addRoundRect(r, &radii[0].fX, SkPath::kCCW_Direction); 2718 p.addRoundRect(r, &radii[0].fX, SkPath::kCCW_Direction);
2596 test_rrect_is_convex(reporter, &p); 2719 test_rrect_is_convex(reporter, &p, SkPath::kCCW_Direction);
2597 p.addRoundRect(r, radii[1].fX, radii[1].fY); 2720 p.addRoundRect(r, radii[1].fX, radii[1].fY);
2598 test_rrect_is_convex(reporter, &p); 2721 test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
2599 p.addRoundRect(r, radii[1].fX, radii[1].fY, SkPath::kCCW_Direction); 2722 p.addRoundRect(r, radii[1].fX, radii[1].fY, SkPath::kCCW_Direction);
2600 test_rrect_is_convex(reporter, &p); 2723 test_rrect_is_convex(reporter, &p, SkPath::kCCW_Direction);
2601 } 2724 for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
2725 SkVector save = radii[i];
2726 radii[i].set(0, 0);
2727 rr.setRectRadii(r, radii);
2728 p.addRRect(rr);
2729 test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
2730 radii[i] = save;
2731 }
2732 p.addRoundRect(r, 0, 0);
2733 SkRect returnedRect;
2734 REPORTER_ASSERT(reporter, p.isRect(&returnedRect));
2735 REPORTER_ASSERT(reporter, returnedRect == r);
2736 test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
2737 SkVector zeroRadii[] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}};
2738 rr.setRectRadii(r, zeroRadii);
2739 p.addRRect(rr);
2740 bool closed;
2741 SkPath::Direction dir;
2742 REPORTER_ASSERT(reporter, p.isRect(&closed, &dir));
2743 REPORTER_ASSERT(reporter, closed);
2744 REPORTER_ASSERT(reporter, SkPath::kCW_Direction == dir);
2745 test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
2746 p.addRRect(rr, SkPath::kCW_Direction);
2747 p.addRRect(rr, SkPath::kCW_Direction);
2748 REPORTER_ASSERT(reporter, !p.isConvex());
2749 p.reset();
2750 p.addRRect(rr, SkPath::kCCW_Direction);
2751 p.addRRect(rr, SkPath::kCCW_Direction);
2752 REPORTER_ASSERT(reporter, !p.isConvex());
2753 p.reset();
2754 SkRect emptyR = {10, 20, 10, 30};
2755 rr.setRectRadii(emptyR, radii);
2756 p.addRRect(rr);
2757 REPORTER_ASSERT(reporter, p.isEmpty());
2758 SkRect largeR = {0, 0, SK_ScalarMax, SK_ScalarMax};
2759 rr.setRectRadii(largeR, radii);
2760 p.addRRect(rr);
2761 test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
2762 SkRect infR = {0, 0, SK_ScalarMax, SK_ScalarInfinity};
2763 rr.setRectRadii(infR, radii);
2764 p.addRRect(rr);
2765 test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
2766 SkRect tinyR = {0, 0, 1e-9f, 1e-9f};
2767 p.addRoundRect(tinyR, 5e-11f, 5e-11f);
2768 test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
2769 }
2770
2771 static void test_arc(skiatest::Reporter* reporter) {
2772 SkPath p;
2773 SkRect emptyOval = {10, 20, 30, 20};
2774 REPORTER_ASSERT(reporter, emptyOval.isEmpty());
2775 p.addArc(emptyOval, 1, 2);
2776 REPORTER_ASSERT(reporter, p.isEmpty());
2777 p.reset();
2778 SkRect oval = {10, 20, 30, 40};
2779 p.addArc(oval, 1, 0);
2780 REPORTER_ASSERT(reporter, p.isEmpty());
2781 p.reset();
2782 SkPath cwOval;
2783 cwOval.addOval(oval);
2784 p.addArc(oval, 1, 360);
2785 REPORTER_ASSERT(reporter, p == cwOval);
2786 p.reset();
2787 SkPath ccwOval;
2788 ccwOval.addOval(oval, SkPath::kCCW_Direction);
2789 p.addArc(oval, 1, -360);
2790 REPORTER_ASSERT(reporter, p == ccwOval);
2791 p.reset();
2792 p.addArc(oval, 1, 180);
2793 REPORTER_ASSERT(reporter, p.isConvex());
2794 REPORTER_ASSERT(reporter, p.cheapIsDirection(SkPath::kCW_Direction));
2795 p.setConvexity(SkPath::kUnknown_Convexity);
2796 REPORTER_ASSERT(reporter, p.isConvex());
2797 }
2798
2799 static void check_move(skiatest::Reporter* reporter, SkPath::RawIter* iter,
2800 SkScalar x0, SkScalar y0) {
2801 SkPoint pts[4];
2802 SkPath::Verb v = iter->next(pts);
2803 REPORTER_ASSERT(reporter, v == SkPath::kMove_Verb);
2804 REPORTER_ASSERT(reporter, pts[0].fX == x0);
2805 REPORTER_ASSERT(reporter, pts[0].fY == y0);
2806 }
2807
2808 static void check_line(skiatest::Reporter* reporter, SkPath::RawIter* iter,
2809 SkScalar x1, SkScalar y1) {
2810 SkPoint pts[4];
2811 SkPath::Verb v = iter->next(pts);
2812 REPORTER_ASSERT(reporter, v == SkPath::kLine_Verb);
2813 REPORTER_ASSERT(reporter, pts[1].fX == x1);
2814 REPORTER_ASSERT(reporter, pts[1].fY == y1);
2815 }
2816
2817 static void check_quad(skiatest::Reporter* reporter, SkPath::RawIter* iter,
2818 SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
2819 SkPoint pts[4];
2820 SkPath::Verb v = iter->next(pts);
2821 REPORTER_ASSERT(reporter, v == SkPath::kQuad_Verb);
2822 REPORTER_ASSERT(reporter, pts[1].fX == x1);
2823 REPORTER_ASSERT(reporter, pts[1].fY == y1);
2824 REPORTER_ASSERT(reporter, pts[2].fX == x2);
2825 REPORTER_ASSERT(reporter, pts[2].fY == y2);
2826 }
2827
2828 static void check_done(skiatest::Reporter* reporter, SkPath* p, SkPath::RawIter* iter) {
2829 SkPoint pts[4];
2830 SkPath::Verb v = iter->next(pts);
2831 REPORTER_ASSERT(reporter, v == SkPath::kDone_Verb);
2832 }
2833
2834 static void check_done_and_reset(skiatest::Reporter* reporter, SkPath* p, SkPath ::RawIter* iter) {
2835 check_done(reporter, p, iter);
2836 p->reset();
2837 }
2838
2839 static void check_path_is_move_and_reset(skiatest::Reporter* reporter, SkPath* p ,
2840 SkScalar x0, SkScalar y0) {
2841 SkPath::RawIter iter(*p);
2842 check_move(reporter, &iter, x0, y0);
2843 check_done_and_reset(reporter, p, &iter);
2844 }
2845
2846 static void check_path_is_line_and_reset(skiatest::Reporter* reporter, SkPath* p ,
2847 SkScalar x1, SkScalar y1) {
2848 SkPath::RawIter iter(*p);
2849 check_move(reporter, &iter, 0, 0);
2850 check_line(reporter, &iter, x1, y1);
2851 check_done_and_reset(reporter, p, &iter);
2852 }
2853
2854 static void check_path_is_line(skiatest::Reporter* reporter, SkPath* p,
2855 SkScalar x1, SkScalar y1) {
2856 SkPath::RawIter iter(*p);
2857 check_move(reporter, &iter, 0, 0);
2858 check_line(reporter, &iter, x1, y1);
2859 check_done(reporter, p, &iter);
2860 }
2861
2862 static void check_path_is_line_pair_and_reset(skiatest::Reporter* reporter, SkPa th* p,
2863 SkScalar x1, SkScalar y1, SkScalar x2, SkSca lar y2) {
2864 SkPath::RawIter iter(*p);
2865 check_move(reporter, &iter, 0, 0);
2866 check_line(reporter, &iter, x1, y1);
2867 check_line(reporter, &iter, x2, y2);
2868 check_done_and_reset(reporter, p, &iter);
2869 }
2870
2871 static void check_path_is_quad_and_reset(skiatest::Reporter* reporter, SkPath* p ,
2872 SkScalar x1, SkScalar y1, SkScalar x2, SkSca lar y2) {
2873 SkPath::RawIter iter(*p);
2874 check_move(reporter, &iter, 0, 0);
2875 check_quad(reporter, &iter, x1, y1, x2, y2);
2876 check_done_and_reset(reporter, p, &iter);
2877 }
2878
2879 static void test_arcTo(skiatest::Reporter* reporter) {
2880 SkPath p;
2881 p.arcTo(0, 0, 1, 2, 1);
2882 check_path_is_line_and_reset(reporter, &p, 0, 0);
2883 p.arcTo(1, 2, 1, 2, 1);
2884 check_path_is_line_and_reset(reporter, &p, 1, 2);
2885 p.arcTo(1, 2, 3, 4, 0);
2886 check_path_is_line_and_reset(reporter, &p, 1, 2);
2887 p.arcTo(1, 2, 0, 0, 1);
2888 check_path_is_line_and_reset(reporter, &p, 1, 2);
2889 p.arcTo(1, 0, 1, 1, 1);
2890 SkPoint pt;
2891 REPORTER_ASSERT(reporter, p.getLastPt(&pt) && pt.fX == 1 && pt.fY == 1);
2892 p.reset();
2893 p.arcTo(1, 0, 1, -1, 1);
2894 REPORTER_ASSERT(reporter, p.getLastPt(&pt) && pt.fX == 1 && pt.fY == -1);
2895 p.reset();
2896 SkRect oval = {1, 2, 3, 4};
2897 p.arcTo(oval, 0, 0, true);
2898 check_path_is_move_and_reset(reporter, &p, oval.fRight, oval.centerY());
2899 p.arcTo(oval, 0, 0, false);
2900 check_path_is_move_and_reset(reporter, &p, oval.fRight, oval.centerY());
2901 p.arcTo(oval, 360, 0, true);
2902 check_path_is_move_and_reset(reporter, &p, oval.fRight, oval.centerY());
2903 p.arcTo(oval, 360, 0, false);
2904 check_path_is_move_and_reset(reporter, &p, oval.fRight, oval.centerY());
2905 for (float sweep = 359, delta = 0.5f; sweep != (float) (sweep + delta); ) {
2906 p.arcTo(oval, 0, SkFloatToScalar(sweep), false);
2907 REPORTER_ASSERT(reporter, p.getBounds() == oval);
2908 sweep += delta;
2909 delta /= 2;
2910 }
2911 for (float sweep = 361, delta = 0.5f; sweep != (float) (sweep - delta);) {
2912 p.arcTo(oval, 0, SkFloatToScalar(sweep), false);
2913 REPORTER_ASSERT(reporter, p.getBounds() == oval);
2914 sweep -= delta;
2915 delta /= 2;
2916 }
2917 }
2918
2919 static void test_addPath(skiatest::Reporter* reporter) {
2920 SkPath p, q;
2921 p.lineTo(1, 2);
2922 q.moveTo(4, 4);
2923 q.lineTo(7, 8);
2924 q.conicTo(8, 7, 6, 5, 0.5f);
2925 q.quadTo(6, 7, 8, 6);
2926 q.cubicTo(5, 6, 7, 8, 7, 5);
2927 q.close();
2928 p.addPath(q, -4, -4);
2929 SkRect expected = {0, 0, 4, 4};
2930 REPORTER_ASSERT(reporter, p.getBounds() == expected);
2931 p.reset();
2932 p.reverseAddPath(q);
2933 SkRect reverseExpected = {4, 4, 8, 8};
2934 REPORTER_ASSERT(reporter, p.getBounds() == reverseExpected);
2935 }
2936
2937 static void test_conicTo_special_case(skiatest::Reporter* reporter) {
2938 SkPath p;
2939 p.conicTo(1, 2, 3, 4, -1);
2940 check_path_is_line_and_reset(reporter, &p, 3, 4);
2941 p.conicTo(1, 2, 3, 4, SK_ScalarInfinity);
2942 check_path_is_line_pair_and_reset(reporter, &p, 1, 2, 3, 4);
2943 p.conicTo(1, 2, 3, 4, 1);
2944 check_path_is_quad_and_reset(reporter, &p, 1, 2, 3, 4);
2945 }
2946
2947 static void test_get_point(skiatest::Reporter* reporter) {
2948 SkPath p;
2949 SkPoint pt = p.getPoint(0);
2950 REPORTER_ASSERT(reporter, pt == SkPoint::Make(0, 0));
2951 REPORTER_ASSERT(reporter, !p.getLastPt(NULL));
2952 REPORTER_ASSERT(reporter, !p.getLastPt(&pt) && pt == SkPoint::Make(0, 0));
2953 p.setLastPt(10, 10);
2954 pt = p.getPoint(0);
2955 REPORTER_ASSERT(reporter, pt == SkPoint::Make(10, 10));
2956 REPORTER_ASSERT(reporter, p.getLastPt(NULL));
2957 p.rMoveTo(10, 10);
2958 REPORTER_ASSERT(reporter, p.getLastPt(&pt) && pt == SkPoint::Make(20, 20));
2959 }
2960
2961 static void test_contains(skiatest::Reporter* reporter) {
2962 SkPath p;
2963 p.setFillType(SkPath::kInverseWinding_FillType);
2964 REPORTER_ASSERT(reporter, p.contains(0, 0));
2965 p.setFillType(SkPath::kWinding_FillType);
2966 REPORTER_ASSERT(reporter, !p.contains(0, 0));
2967 p.moveTo(4, 4);
2968 p.lineTo(6, 8);
2969 p.lineTo(8, 4);
2970 // test quick reject
2971 REPORTER_ASSERT(reporter, !p.contains(4, 0));
2972 REPORTER_ASSERT(reporter, !p.contains(0, 4));
2973 REPORTER_ASSERT(reporter, !p.contains(4, 10));
2974 REPORTER_ASSERT(reporter, !p.contains(10, 4));
2975 // test various crossings in x
2976 REPORTER_ASSERT(reporter, !p.contains(5, 7));
2977 REPORTER_ASSERT(reporter, p.contains(6, 7));
2978 REPORTER_ASSERT(reporter, !p.contains(7, 7));
2979 p.reset();
2980 p.moveTo(4, 4);
2981 p.lineTo(8, 6);
2982 p.lineTo(4, 8);
2983 // test various crossings in y
2984 REPORTER_ASSERT(reporter, !p.contains(7, 5));
2985 REPORTER_ASSERT(reporter, p.contains(7, 6));
2986 REPORTER_ASSERT(reporter, !p.contains(7, 7));
2987 // test quads
2988 p.reset();
2989 p.moveTo(4, 4);
2990 p.quadTo(6, 6, 8, 8);
2991 p.quadTo(6, 8, 4, 8);
2992 p.quadTo(4, 6, 4, 4);
2993 REPORTER_ASSERT(reporter, p.contains(5, 6));
2994 REPORTER_ASSERT(reporter, !p.contains(6, 5));
2995
2996 p.reset();
2997 p.moveTo(6, 6);
2998 p.quadTo(8, 8, 6, 8);
2999 p.quadTo(4, 8, 4, 6);
3000 p.quadTo(4, 4, 6, 6);
3001 REPORTER_ASSERT(reporter, p.contains(5, 6));
3002 REPORTER_ASSERT(reporter, !p.contains(6, 5));
3003
3004 #define CONIC_CONTAINS_BUG_FIXED 0
3005 #if CONIC_CONTAINS_BUG_FIXED
3006 p.reset();
3007 p.moveTo(4, 4);
3008 p.conicTo(6, 6, 8, 8, 0.5f);
3009 p.conicTo(6, 8, 4, 8, 0.5f);
3010 p.conicTo(4, 6, 4, 4, 0.5f);
3011 REPORTER_ASSERT(reporter, p.contains(5, 6));
3012 REPORTER_ASSERT(reporter, !p.contains(6, 5));
3013 #endif
3014
3015 // test cubics
3016 SkPoint pts[] = {{5, 4}, {6, 5}, {7, 6}, {6, 6}, {4, 6}, {5, 7}, {5, 5}, {5, 4}, {6, 5}, {7, 6}};
3017 for (int i = 0; i < 3; ++i) {
3018 p.reset();
3019 p.setFillType(SkPath::kEvenOdd_FillType);
3020 p.moveTo(pts[i].fX, pts[i].fY);
3021 p.cubicTo(pts[i + 1].fX, pts[i + 1].fY, pts[i + 2].fX, pts[i + 2].fY, pt s[i + 3].fX, pts[i + 3].fY);
3022 p.cubicTo(pts[i + 4].fX, pts[i + 4].fY, pts[i + 5].fX, pts[i + 5].fY, pt s[i + 6].fX, pts[i + 6].fY);
3023 p.close();
3024 REPORTER_ASSERT(reporter, p.contains(5.5f, 5.5f));
3025 REPORTER_ASSERT(reporter, !p.contains(4.5f, 5.5f));
3026 }
3027 }
3028
3029 class PathTest_Private {
3030 public:
3031 static void TestPathTo(skiatest::Reporter* reporter) {
3032 SkPath p, q;
3033 p.lineTo(4, 4);
3034 p.reversePathTo(q);
3035 check_path_is_line(reporter, &p, 4, 4);
3036 q.moveTo(-4, -4);
3037 p.reversePathTo(q);
3038 check_path_is_line(reporter, &p, 4, 4);
3039 q.lineTo(7, 8);
3040 q.conicTo(8, 7, 6, 5, 0.5f);
3041 q.quadTo(6, 7, 8, 6);
3042 q.cubicTo(5, 6, 7, 8, 7, 5);
3043 q.close();
3044 p.reversePathTo(q);
3045 SkRect reverseExpected = {-4, -4, 8, 8};
3046 REPORTER_ASSERT(reporter, p.getBounds() == reverseExpected);
3047 }
3048 };
2602 3049
2603 static void TestPath(skiatest::Reporter* reporter) { 3050 static void TestPath(skiatest::Reporter* reporter) {
2604 SkTSize<SkScalar>::Make(3,4); 3051 SkTSize<SkScalar>::Make(3,4);
2605 3052
2606 SkPath p, empty; 3053 SkPath p, empty;
2607 SkRect bounds, bounds2; 3054 SkRect bounds, bounds2;
2608 test_empty(reporter, p); 3055 test_empty(reporter, p);
2609 3056
2610 REPORTER_ASSERT(reporter, p.getBounds().isEmpty()); 3057 REPORTER_ASSERT(reporter, p.getBounds().isEmpty());
2611 3058
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2695 test_tricky_cubic(); 3142 test_tricky_cubic();
2696 test_clipped_cubic(); 3143 test_clipped_cubic();
2697 test_crbug_170666(); 3144 test_crbug_170666();
2698 test_bad_cubic_crbug229478(); 3145 test_bad_cubic_crbug229478();
2699 test_bad_cubic_crbug234190(); 3146 test_bad_cubic_crbug234190();
2700 test_android_specific_behavior(reporter); 3147 test_android_specific_behavior(reporter);
2701 test_gen_id(reporter); 3148 test_gen_id(reporter);
2702 test_path_close_issue1474(reporter); 3149 test_path_close_issue1474(reporter);
2703 test_path_to_region(reporter); 3150 test_path_to_region(reporter);
2704 test_rrect(reporter); 3151 test_rrect(reporter);
3152 test_arc(reporter);
3153 test_arcTo(reporter);
3154 test_addPath(reporter);
3155 test_conicTo_special_case(reporter);
3156 test_get_point(reporter);
3157 test_contains(reporter);
3158 PathTest_Private::TestPathTo(reporter);
2705 } 3159 }
2706 3160
2707 #include "TestClassDef.h" 3161 #include "TestClassDef.h"
2708 DEFINE_TESTCLASS("Path", PathTestClass, TestPath) 3162 DEFINE_TESTCLASS("Path", PathTestClass, TestPath)
OLDNEW
« no previous file with comments | « src/core/SkPathRef.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698