1 #include "Test.h" 2 #include "SkPath.h" 3 #include "SkParse.h" 4 #include "SkSize.h" 5 6 static void check_convexity(skiatest::Reporter* reporter, const SkPath& path, 7 SkPath::Convexity expected) { 8 SkPath::Convexity c = SkPath::ComputeConvexity(path); 9 REPORTER_ASSERT(reporter, c == expected); 10 } 11 12 static void test_convexity2(skiatest::Reporter* reporter) { 13 SkPath pt; 14 pt.moveTo(0, 0); 15 pt.close(); 16 check_convexity(reporter, pt, SkPath::kConvex_Convexity); 17 18 SkPath line; 19 line.moveTo(12, 20); 20 line.lineTo(-12, -20); 21 line.close(); 22 check_convexity(reporter, pt, SkPath::kConvex_Convexity); 23 24 SkPath triLeft; 25 triLeft.moveTo(0, 0); 26 triLeft.lineTo(1, 0); 27 triLeft.lineTo(1, 1); 28 triLeft.close(); 29 check_convexity(reporter, triLeft, SkPath::kConvex_Convexity); 30 31 SkPath triRight; 32 triRight.moveTo(0, 0); 33 triRight.lineTo(-1, 0); 34 triRight.lineTo(1, 1); 35 triRight.close(); 36 check_convexity(reporter, triRight, SkPath::kConvex_Convexity); 37 38 SkPath square; 39 square.moveTo(0, 0); 40 square.lineTo(1, 0); 41 square.lineTo(1, 1); 42 square.lineTo(0, 1); 43 square.close(); 44 check_convexity(reporter, square, SkPath::kConvex_Convexity); 45 46 SkPath redundantSquare; 47 redundantSquare.moveTo(0, 0); 48 redundantSquare.lineTo(0, 0); 49 redundantSquare.lineTo(0, 0); 50 redundantSquare.lineTo(1, 0); 51 redundantSquare.lineTo(1, 0); 52 redundantSquare.lineTo(1, 0); 53 redundantSquare.lineTo(1, 1); 54 redundantSquare.lineTo(1, 1); 55 redundantSquare.lineTo(1, 1); 56 redundantSquare.lineTo(0, 1); 57 redundantSquare.lineTo(0, 1); 58 redundantSquare.lineTo(0, 1); 59 redundantSquare.close(); 60 check_convexity(reporter, redundantSquare, SkPath::kConvex_Convexity); 61 62 SkPath bowTie; 63 bowTie.moveTo(0, 0); 64 bowTie.lineTo(0, 0); 65 bowTie.lineTo(0, 0); 66 bowTie.lineTo(1, 1); 67 bowTie.lineTo(1, 1); 68 bowTie.lineTo(1, 1); 69 bowTie.lineTo(1, 0); 70 bowTie.lineTo(1, 0); 71 bowTie.lineTo(1, 0); 72 bowTie.lineTo(0, 1); 73 bowTie.lineTo(0, 1); 74 bowTie.lineTo(0, 1); 75 bowTie.close(); 76 check_convexity(reporter, bowTie, SkPath::kConcave_Convexity); 77 78 SkPath spiral; 79 spiral.moveTo(0, 0); 80 spiral.lineTo(100, 0); 81 spiral.lineTo(100, 100); 82 spiral.lineTo(0, 100); 83 spiral.lineTo(0, 50); 84 spiral.lineTo(50, 50); 85 spiral.lineTo(50, 75); 86 spiral.close(); 87 check_convexity(reporter, spiral, SkPath::kConcave_Convexity); 88 89 SkPath dent; 90 dent.moveTo(SkIntToScalar(0), SkIntToScalar(0)); 91 dent.lineTo(SkIntToScalar(100), SkIntToScalar(100)); 92 dent.lineTo(SkIntToScalar(0), SkIntToScalar(100)); 93 dent.lineTo(SkIntToScalar(-50), SkIntToScalar(200)); 94 dent.lineTo(SkIntToScalar(-200), SkIntToScalar(100)); 95 dent.close(); 96 check_convexity(reporter, dent, SkPath::kConcave_Convexity); 97 } 98 99 static void check_convex_bounds(skiatest::Reporter* reporter, const SkPath& p, 100 const SkRect& bounds) { 101 REPORTER_ASSERT(reporter, p.isConvex()); 102 REPORTER_ASSERT(reporter, p.getBounds() == bounds); 103 104 SkPath p2(p); 105 REPORTER_ASSERT(reporter, p2.isConvex()); 106 REPORTER_ASSERT(reporter, p2.getBounds() == bounds); 107 108 SkPath other; 109 other.swap(p2); 110 REPORTER_ASSERT(reporter, other.isConvex()); 111 REPORTER_ASSERT(reporter, other.getBounds() == bounds); 112 } 113 114 static void setFromString(SkPath* path, const char str[]) { 115 bool first = true; 116 while (str) { 117 SkScalar x, y; 118 str = SkParse::FindScalar(str, &x); 119 if (NULL == str) { 120 break; 121 } 122 str = SkParse::FindScalar(str, &y); 123 SkASSERT(str); 124 if (first) { 125 path->moveTo(x, y); 126 first = false; 127 } else { 128 path->lineTo(x, y); 129 } 130 } 131 } 132 133 static void test_convexity(skiatest::Reporter* reporter) { 134 static const SkPath::Convexity C = SkPath::kConcave_Convexity; 135 static const SkPath::Convexity V = SkPath::kConvex_Convexity; 136 137 SkPath path; 138 139 REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path)); 140 path.addCircle(0, 0, 10); 141 REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path)); 142 path.addCircle(0, 0, 10); // 2nd circle 143 REPORTER_ASSERT(reporter, C == SkPath::ComputeConvexity(path)); 144 path.reset(); 145 path.addRect(0, 0, 10, 10, SkPath::kCCW_Direction); 146 REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path)); 147 path.reset(); 148 path.addRect(0, 0, 10, 10, SkPath::kCW_Direction); 149 REPORTER_ASSERT(reporter, V == SkPath::ComputeConvexity(path)); 150 151 static const struct { 152 const char* fPathStr; 153 SkPath::Convexity fExpectedConvexity; 154 } gRec[] = { 155 { "", SkPath::kConvex_Convexity }, 156 { "0 0", SkPath::kConvex_Convexity }, 157 { "0 0 10 10", SkPath::kConvex_Convexity }, 158 { "0 0 10 10 20 20 0 0 10 10", SkPath::kConcave_Convexity }, 159 { "0 0 10 10 10 20", SkPath::kConvex_Convexity }, 160 { "0 0 10 10 10 0", SkPath::kConvex_Convexity }, 161 { "0 0 10 10 10 0 0 10", SkPath::kConcave_Convexity }, 162 { "0 0 10 0 0 10 -10 -10", SkPath::kConcave_Convexity }, 163 }; 164 165 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { 166 SkPath path; 167 setFromString(&path, gRec[i].fPathStr); 168 SkPath::Convexity c = SkPath::ComputeConvexity(path); 169 REPORTER_ASSERT(reporter, c == gRec[i].fExpectedConvexity); 170 } 171 } 172 173 void TestPath(skiatest::Reporter* reporter); 174 void TestPath(skiatest::Reporter* reporter) { 175 { 176 SkSize size; 177 size.fWidth = 3.4f; 178 size.width(); 179 size = SkSize::Make(3,4); 180 SkISize isize = SkISize::Make(3,4); 181 } 182 183 SkTSize<SkScalar>::Make(3,4); 184 185 SkPath p, p2; 186 SkRect bounds, bounds2; 187 188 REPORTER_ASSERT(reporter, p.isEmpty()); 189 REPORTER_ASSERT(reporter, p.isConvex()); 190 REPORTER_ASSERT(reporter, p.getFillType() == SkPath::kWinding_FillType); 191 REPORTER_ASSERT(reporter, !p.isInverseFillType()); 192 REPORTER_ASSERT(reporter, p == p2); 193 REPORTER_ASSERT(reporter, !(p != p2)); 194 195 REPORTER_ASSERT(reporter, p.getBounds().isEmpty()); 196 197 bounds.set(0, 0, SK_Scalar1, SK_Scalar1); 198 199 p.addRoundRect(bounds, SK_Scalar1, SK_Scalar1); 200 check_convex_bounds(reporter, p, bounds); 201 202 p.reset(); 203 p.addOval(bounds); 204 check_convex_bounds(reporter, p, bounds); 205 206 p.reset(); 207 p.addRect(bounds); 208 check_convex_bounds(reporter, p, bounds); 209 210 REPORTER_ASSERT(reporter, p != p2); 211 REPORTER_ASSERT(reporter, !(p == p2)); 212 213 // does getPoints return the right result 214 REPORTER_ASSERT(reporter, p.getPoints(NULL, 5) == 4); 215 SkPoint pts[4]; 216 int count = p.getPoints(pts, 4); 217 REPORTER_ASSERT(reporter, count == 4); 218 bounds2.set(pts, 4); 219 REPORTER_ASSERT(reporter, bounds == bounds2); 220 221 bounds.offset(SK_Scalar1*3, SK_Scalar1*4); 222 p.offset(SK_Scalar1*3, SK_Scalar1*4); 223 REPORTER_ASSERT(reporter, bounds == p.getBounds()); 224 225 #if 0 // isRect needs to be implemented 226 REPORTER_ASSERT(reporter, p.isRect(NULL)); 227 bounds.setEmpty(); 228 REPORTER_ASSERT(reporter, p.isRect(&bounds2)); 229 REPORTER_ASSERT(reporter, bounds == bounds2); 230 231 // now force p to not be a rect 232 bounds.set(0, 0, SK_Scalar1/2, SK_Scalar1/2); 233 p.addRect(bounds); 234 REPORTER_ASSERT(reporter, !p.isRect(NULL)); 235 #endif 236 237 SkPoint pt; 238 239 p.moveTo(SK_Scalar1, 0); 240 p.getLastPt(&pt); 241 REPORTER_ASSERT(reporter, pt.fX == SK_Scalar1); 242 243 test_convexity(reporter); 244 test_convexity2(reporter); 245 } 246 247 #include "TestClassDef.h" 248 DEFINE_TESTCLASS("Path", PathTestClass, TestPath) 249