OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkBuffer.h" | 10 #include "SkBuffer.h" |
(...skipping 2197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2208 } | 2208 } |
2209 | 2209 |
2210 return kStraight_DirChange; | 2210 return kStraight_DirChange; |
2211 } | 2211 } |
2212 | 2212 |
2213 // only valid for a single contour | 2213 // only valid for a single contour |
2214 struct Convexicator { | 2214 struct Convexicator { |
2215 Convexicator() | 2215 Convexicator() |
2216 : fPtCount(0) | 2216 : fPtCount(0) |
2217 , fConvexity(SkPath::kConvex_Convexity) | 2217 , fConvexity(SkPath::kConvex_Convexity) |
2218 , fDirection(SkPath::kUnknown_Direction) { | 2218 , fDirection(SkPath::kUnknown_Direction) |
2219 , fIsFinite(true) { | |
2219 fExpectedDir = kInvalid_DirChange; | 2220 fExpectedDir = kInvalid_DirChange; |
2220 // warnings | 2221 // warnings |
2221 fLastPt.set(0, 0); | 2222 fLastPt.set(0, 0); |
2222 fCurrPt.set(0, 0); | 2223 fCurrPt.set(0, 0); |
2223 fLastVec.set(0, 0); | 2224 fLastVec.set(0, 0); |
2224 fFirstVec.set(0, 0); | 2225 fFirstVec.set(0, 0); |
2225 | 2226 |
2226 fDx = fDy = 0; | 2227 fDx = fDy = 0; |
2227 fSx = fSy = kValueNeverReturnedBySign; | 2228 fSx = fSy = kValueNeverReturnedBySign; |
2228 } | 2229 } |
2229 | 2230 |
2230 SkPath::Convexity getConvexity() const { return fConvexity; } | 2231 SkPath::Convexity getConvexity() const { return fConvexity; } |
2231 | 2232 |
2232 /** The direction returned is only valid if the path is determined convex */ | 2233 /** The direction returned is only valid if the path is determined convex */ |
2233 SkPath::Direction getDirection() const { return fDirection; } | 2234 SkPath::Direction getDirection() const { return fDirection; } |
2234 | 2235 |
2235 void addPt(const SkPoint& pt) { | 2236 void addPt(const SkPoint& pt) { |
2236 if (SkPath::kConcave_Convexity == fConvexity) { | 2237 if (SkPath::kConcave_Convexity == fConvexity || !fIsFinite) { |
2237 return; | 2238 return; |
2238 } | 2239 } |
2239 | 2240 |
2240 if (0 == fPtCount) { | 2241 if (0 == fPtCount) { |
2241 fCurrPt = pt; | 2242 fCurrPt = pt; |
2242 ++fPtCount; | 2243 ++fPtCount; |
2243 } else { | 2244 } else { |
2244 SkVector vec = pt - fCurrPt; | 2245 SkVector vec = pt - fCurrPt; |
2245 if (!SkScalarNearlyZero(vec.lengthSqd(), SK_ScalarNearlyZero*SK_Scal arNearlyZero)) { | 2246 SkScalar lengthSqd = vec.lengthSqd(); |
2247 if (!SkScalarIsFinite(lengthSqd)) { | |
2248 fIsFinite = false; | |
bsalomon
2014/12/05 20:23:46
Do we need to track fIsFinite or can this just be
| |
2249 } else if (!SkScalarNearlyZero(lengthSqd, SK_ScalarNearlyZero*SK_Sca larNearlyZero)) { | |
2246 fLastPt = fCurrPt; | 2250 fLastPt = fCurrPt; |
2247 fCurrPt = pt; | 2251 fCurrPt = pt; |
2248 if (++fPtCount == 2) { | 2252 if (++fPtCount == 2) { |
2249 fFirstVec = fLastVec = vec; | 2253 fFirstVec = fLastVec = vec; |
2250 } else { | 2254 } else { |
2251 SkASSERT(fPtCount > 2); | 2255 SkASSERT(fPtCount > 2); |
2252 this->addVec(vec); | 2256 this->addVec(vec); |
2253 } | 2257 } |
2254 | 2258 |
2255 int sx = sign(vec.fX); | 2259 int sx = sign(vec.fX); |
2256 int sy = sign(vec.fY); | 2260 int sy = sign(vec.fY); |
2257 fDx += (sx != fSx); | 2261 fDx += (sx != fSx); |
2258 fDy += (sy != fSy); | 2262 fDy += (sy != fSy); |
2259 fSx = sx; | 2263 fSx = sx; |
2260 fSy = sy; | 2264 fSy = sy; |
2261 | 2265 |
2262 if (fDx > 3 || fDy > 3) { | 2266 if (fDx > 3 || fDy > 3) { |
2263 fConvexity = SkPath::kConcave_Convexity; | 2267 fConvexity = SkPath::kConcave_Convexity; |
2264 } | 2268 } |
2265 } | 2269 } |
2266 } | 2270 } |
2267 } | 2271 } |
2268 | 2272 |
2269 void close() { | 2273 void close() { |
2270 if (fPtCount > 2) { | 2274 if (fPtCount > 2) { |
2271 this->addVec(fFirstVec); | 2275 this->addVec(fFirstVec); |
2272 } | 2276 } |
2273 } | 2277 } |
2274 | 2278 |
2279 bool isFinite() const { | |
2280 return fIsFinite; | |
2281 } | |
2282 | |
2275 private: | 2283 private: |
2276 void addVec(const SkVector& vec) { | 2284 void addVec(const SkVector& vec) { |
2277 SkASSERT(vec.fX || vec.fY); | 2285 SkASSERT(vec.fX || vec.fY); |
2278 DirChange dir = direction_change(fLastPt, fCurrPt, fLastVec, vec); | 2286 DirChange dir = direction_change(fLastPt, fCurrPt, fLastVec, vec); |
2279 switch (dir) { | 2287 switch (dir) { |
2280 case kLeft_DirChange: // fall through | 2288 case kLeft_DirChange: // fall through |
2281 case kRight_DirChange: | 2289 case kRight_DirChange: |
2282 if (kInvalid_DirChange == fExpectedDir) { | 2290 if (kInvalid_DirChange == fExpectedDir) { |
2283 fExpectedDir = dir; | 2291 fExpectedDir = dir; |
2284 fDirection = (kRight_DirChange == dir) ? SkPath::kCW_Directi on | 2292 fDirection = (kRight_DirChange == dir) ? SkPath::kCW_Directi on |
(...skipping 18 matching lines...) Expand all Loading... | |
2303 SkPoint fLastPt; | 2311 SkPoint fLastPt; |
2304 SkPoint fCurrPt; | 2312 SkPoint fCurrPt; |
2305 // fLastVec does not necessarily start at fLastPt. We only advance it when t he cross product | 2313 // fLastVec does not necessarily start at fLastPt. We only advance it when t he cross product |
2306 // value with the current vec is deemed to be of a significant value. | 2314 // value with the current vec is deemed to be of a significant value. |
2307 SkVector fLastVec, fFirstVec; | 2315 SkVector fLastVec, fFirstVec; |
2308 int fPtCount; // non-degenerate points | 2316 int fPtCount; // non-degenerate points |
2309 DirChange fExpectedDir; | 2317 DirChange fExpectedDir; |
2310 SkPath::Convexity fConvexity; | 2318 SkPath::Convexity fConvexity; |
2311 SkPath::Direction fDirection; | 2319 SkPath::Direction fDirection; |
2312 int fDx, fDy, fSx, fSy; | 2320 int fDx, fDy, fSx, fSy; |
2321 bool fIsFinite; | |
2313 }; | 2322 }; |
2314 | 2323 |
2315 SkPath::Convexity SkPath::internalGetConvexity() const { | 2324 SkPath::Convexity SkPath::internalGetConvexity() const { |
2316 SkASSERT(kUnknown_Convexity == fConvexity); | 2325 SkASSERT(kUnknown_Convexity == fConvexity); |
2317 SkPoint pts[4]; | 2326 SkPoint pts[4]; |
2318 SkPath::Verb verb; | 2327 SkPath::Verb verb; |
2319 SkPath::Iter iter(*this, true); | 2328 SkPath::Iter iter(*this, true); |
2320 | 2329 |
2321 int contourCount = 0; | 2330 int contourCount = 0; |
2322 int count; | 2331 int count; |
2323 Convexicator state; | 2332 Convexicator state; |
2324 | 2333 |
2334 if (!isFinite()) { | |
2335 return kUnknown_Convexity; | |
2336 } | |
2325 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { | 2337 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { |
2326 switch (verb) { | 2338 switch (verb) { |
2327 case kMove_Verb: | 2339 case kMove_Verb: |
2328 if (++contourCount > 1) { | 2340 if (++contourCount > 1) { |
2329 fConvexity = kConcave_Convexity; | 2341 fConvexity = kConcave_Convexity; |
2330 return kConcave_Convexity; | 2342 return kConcave_Convexity; |
2331 } | 2343 } |
2332 pts[1] = pts[0]; | 2344 pts[1] = pts[0]; |
2333 count = 1; | 2345 count = 1; |
2334 break; | 2346 break; |
2335 case kLine_Verb: count = 1; break; | 2347 case kLine_Verb: count = 1; break; |
2336 case kQuad_Verb: count = 2; break; | 2348 case kQuad_Verb: count = 2; break; |
2337 case kConic_Verb: count = 2; break; | 2349 case kConic_Verb: count = 2; break; |
2338 case kCubic_Verb: count = 3; break; | 2350 case kCubic_Verb: count = 3; break; |
2339 case kClose_Verb: | 2351 case kClose_Verb: |
2340 state.close(); | 2352 state.close(); |
2341 count = 0; | 2353 count = 0; |
2342 break; | 2354 break; |
2343 default: | 2355 default: |
2344 SkDEBUGFAIL("bad verb"); | 2356 SkDEBUGFAIL("bad verb"); |
2345 fConvexity = kConcave_Convexity; | 2357 fConvexity = kConcave_Convexity; |
2346 return kConcave_Convexity; | 2358 return kConcave_Convexity; |
2347 } | 2359 } |
2348 | 2360 |
2349 for (int i = 1; i <= count; i++) { | 2361 for (int i = 1; i <= count; i++) { |
2350 state.addPt(pts[i]); | 2362 state.addPt(pts[i]); |
2351 } | 2363 } |
2352 // early exit | 2364 // early exit |
2365 if (!state.isFinite()) { | |
2366 return kUnknown_Convexity; | |
2367 } | |
2353 if (kConcave_Convexity == state.getConvexity()) { | 2368 if (kConcave_Convexity == state.getConvexity()) { |
2354 fConvexity = kConcave_Convexity; | 2369 fConvexity = kConcave_Convexity; |
2355 return kConcave_Convexity; | 2370 return kConcave_Convexity; |
2356 } | 2371 } |
2357 } | 2372 } |
2358 fConvexity = state.getConvexity(); | 2373 fConvexity = state.getConvexity(); |
2359 if (kConvex_Convexity == fConvexity && kUnknown_Direction == fDirection) { | 2374 if (kConvex_Convexity == fConvexity && kUnknown_Direction == fDirection) { |
2360 fDirection = state.getDirection(); | 2375 fDirection = state.getDirection(); |
2361 } | 2376 } |
2362 return static_cast<Convexity>(fConvexity); | 2377 return static_cast<Convexity>(fConvexity); |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2864 switch (this->getFillType()) { | 2879 switch (this->getFillType()) { |
2865 case SkPath::kEvenOdd_FillType: | 2880 case SkPath::kEvenOdd_FillType: |
2866 case SkPath::kInverseEvenOdd_FillType: | 2881 case SkPath::kInverseEvenOdd_FillType: |
2867 w &= 1; | 2882 w &= 1; |
2868 break; | 2883 break; |
2869 default: | 2884 default: |
2870 break; | 2885 break; |
2871 } | 2886 } |
2872 return SkToBool(w); | 2887 return SkToBool(w); |
2873 } | 2888 } |
OLD | NEW |