Chromium Code Reviews| 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 |