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 2265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2276 SkASSERT(mask == fSegmentMask); | 2276 SkASSERT(mask == fSegmentMask); |
| 2277 #endif // SK_DEBUG_PATH | 2277 #endif // SK_DEBUG_PATH |
| 2278 } | 2278 } |
| 2279 #endif // SK_DEBUG | 2279 #endif // SK_DEBUG |
| 2280 | 2280 |
| 2281 /////////////////////////////////////////////////////////////////////////////// | 2281 /////////////////////////////////////////////////////////////////////////////// |
| 2282 | 2282 |
| 2283 static int sign(SkScalar x) { return x < 0; } | 2283 static int sign(SkScalar x) { return x < 0; } |
| 2284 #define kValueNeverReturnedBySign 2 | 2284 #define kValueNeverReturnedBySign 2 |
| 2285 | 2285 |
| 2286 static int CrossProductSign(const SkVector& a, const SkVector& b) { | 2286 static bool AlmostEqual(SkScalar compA, SkScalar compB) { |
| 2287 return SkScalarSignAsInt(SkPoint::CrossProduct(a, b)); | 2287 // The error epsilon was empirically derived; worse case round rects |
| 2288 // with a mid point outset by 2x float epsilon in tests had an error | |
| 2289 // of 12. | |
| 2290 const int epsilon = 16; | |
| 2291 if (!SkScalarIsFinite(compA) || !SkScalarIsFinite(compB)) { | |
| 2292 return false; | |
| 2293 } | |
| 2294 if (sk_float_abs(compA) <= FLT_EPSILON && sk_float_abs(compB) <= FLT_EPSILON ) { | |
| 2295 return true; | |
| 2296 } | |
| 2297 int aBits = SkFloatAs2sCompliment(compA); | |
| 2298 int bBits = SkFloatAs2sCompliment(compB); | |
| 2299 return aBits < bBits + epsilon && bBits < aBits + epsilon; | |
| 2288 } | 2300 } |
| 2289 | 2301 |
| 2290 // only valid for a single contour | 2302 // only valid for a single contour |
| 2291 struct Convexicator { | 2303 struct Convexicator { |
| 2292 Convexicator() | 2304 Convexicator() |
| 2293 : fPtCount(0) | 2305 : fPtCount(0) |
| 2294 , fConvexity(SkPath::kConvex_Convexity) | 2306 , fConvexity(SkPath::kConvex_Convexity) |
| 2295 , fDirection(SkPath::kUnknown_Direction) { | 2307 , fDirection(SkPath::kUnknown_Direction) { |
| 2296 fSign = 0; | 2308 fSign = 0; |
| 2297 // warnings | 2309 // warnings |
| 2310 fLastPt.set(0, 0); | |
| 2298 fCurrPt.set(0, 0); | 2311 fCurrPt.set(0, 0); |
| 2299 fVec0.set(0, 0); | 2312 fVec0.set(0, 0); |
| 2300 fVec1.set(0, 0); | 2313 fVec1.set(0, 0); |
| 2301 fFirstVec.set(0, 0); | 2314 fFirstVec.set(0, 0); |
| 2302 | 2315 |
| 2303 fDx = fDy = 0; | 2316 fDx = fDy = 0; |
| 2304 fSx = fSy = kValueNeverReturnedBySign; | 2317 fSx = fSy = kValueNeverReturnedBySign; |
| 2305 } | 2318 } |
| 2306 | 2319 |
| 2307 SkPath::Convexity getConvexity() const { return fConvexity; } | 2320 SkPath::Convexity getConvexity() const { return fConvexity; } |
| 2308 | 2321 |
| 2309 /** The direction returned is only valid if the path is determined convex */ | 2322 /** The direction returned is only valid if the path is determined convex */ |
| 2310 SkPath::Direction getDirection() const { return fDirection; } | 2323 SkPath::Direction getDirection() const { return fDirection; } |
| 2311 | 2324 |
| 2312 void addPt(const SkPoint& pt) { | 2325 void addPt(const SkPoint& pt) { |
| 2313 if (SkPath::kConcave_Convexity == fConvexity) { | 2326 if (SkPath::kConcave_Convexity == fConvexity) { |
| 2314 return; | 2327 return; |
| 2315 } | 2328 } |
| 2316 | 2329 |
| 2317 if (0 == fPtCount) { | 2330 if (0 == fPtCount) { |
| 2318 fCurrPt = pt; | 2331 fCurrPt = pt; |
| 2319 ++fPtCount; | 2332 ++fPtCount; |
| 2320 } else { | 2333 } else { |
| 2321 SkVector vec = pt - fCurrPt; | 2334 SkVector vec = pt - fCurrPt; |
| 2322 if (vec.fX || vec.fY) { | 2335 if (vec.fX || vec.fY) { |
| 2336 fLastPt = fCurrPt; | |
| 2323 fCurrPt = pt; | 2337 fCurrPt = pt; |
| 2324 if (++fPtCount == 2) { | 2338 if (++fPtCount == 2) { |
| 2325 fFirstVec = fVec1 = vec; | 2339 fFirstVec = fVec1 = vec; |
| 2326 } else { | 2340 } else { |
| 2327 SkASSERT(fPtCount > 2); | 2341 SkASSERT(fPtCount > 2); |
| 2328 this->addVec(vec); | 2342 this->addVec(vec); |
| 2329 } | 2343 } |
| 2330 | 2344 |
| 2331 int sx = sign(vec.fX); | 2345 int sx = sign(vec.fX); |
| 2332 int sy = sign(vec.fY); | 2346 int sy = sign(vec.fY); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 2346 if (fPtCount > 2) { | 2360 if (fPtCount > 2) { |
| 2347 this->addVec(fFirstVec); | 2361 this->addVec(fFirstVec); |
| 2348 } | 2362 } |
| 2349 } | 2363 } |
| 2350 | 2364 |
| 2351 private: | 2365 private: |
| 2352 void addVec(const SkVector& vec) { | 2366 void addVec(const SkVector& vec) { |
| 2353 SkASSERT(vec.fX || vec.fY); | 2367 SkASSERT(vec.fX || vec.fY); |
| 2354 fVec0 = fVec1; | 2368 fVec0 = fVec1; |
| 2355 fVec1 = vec; | 2369 fVec1 = vec; |
| 2356 int sign = CrossProductSign(fVec0, fVec1); | 2370 SkScalar cross = SkPoint::CrossProduct(fVec0, fVec1); |
|
reed1
2013/10/29 20:50:06
I need some comment block or other way to know wha
| |
| 2371 SkScalar smallest = SkTMin(fCurrPt.fX, SkTMin(fCurrPt.fY, SkTMin(fLastPt .fX, fLastPt.fY))); | |
| 2372 SkScalar largest = SkTMax(fCurrPt.fX, SkTMax(fCurrPt.fY, SkTMax(fLastPt. fX, fLastPt.fY))); | |
| 2373 largest = SkTMax(largest, -smallest); | |
| 2374 int sign = AlmostEqual(largest, largest + cross) ? 0 : SkScalarSignAsInt (cross); | |
| 2357 if (0 == fSign) { | 2375 if (0 == fSign) { |
| 2358 fSign = sign; | 2376 fSign = sign; |
| 2359 if (1 == sign) { | 2377 if (1 == sign) { |
| 2360 fDirection = SkPath::kCW_Direction; | 2378 fDirection = SkPath::kCW_Direction; |
| 2361 } else if (-1 == sign) { | 2379 } else if (-1 == sign) { |
| 2362 fDirection = SkPath::kCCW_Direction; | 2380 fDirection = SkPath::kCCW_Direction; |
| 2363 } | 2381 } |
| 2364 } else if (sign) { | 2382 } else if (sign) { |
| 2365 if (fSign != sign) { | 2383 if (fSign != sign) { |
| 2366 fConvexity = SkPath::kConcave_Convexity; | 2384 fConvexity = SkPath::kConcave_Convexity; |
| 2367 fDirection = SkPath::kUnknown_Direction; | 2385 fDirection = SkPath::kUnknown_Direction; |
| 2368 } | 2386 } |
| 2369 } | 2387 } |
| 2370 } | 2388 } |
| 2371 | 2389 |
| 2390 SkPoint fLastPt; | |
| 2372 SkPoint fCurrPt; | 2391 SkPoint fCurrPt; |
| 2373 SkVector fVec0, fVec1, fFirstVec; | 2392 SkVector fVec0, fVec1, fFirstVec; |
| 2374 int fPtCount; // non-degenerate points | 2393 int fPtCount; // non-degenerate points |
| 2375 int fSign; | 2394 int fSign; |
| 2376 SkPath::Convexity fConvexity; | 2395 SkPath::Convexity fConvexity; |
| 2377 SkPath::Direction fDirection; | 2396 SkPath::Direction fDirection; |
| 2378 int fDx, fDy, fSx, fSy; | 2397 int fDx, fDy, fSx, fSy; |
| 2379 }; | 2398 }; |
| 2380 | 2399 |
| 2381 SkPath::Convexity SkPath::internalGetConvexity() const { | 2400 SkPath::Convexity SkPath::internalGetConvexity() const { |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3002 switch (this->getFillType()) { | 3021 switch (this->getFillType()) { |
| 3003 case SkPath::kEvenOdd_FillType: | 3022 case SkPath::kEvenOdd_FillType: |
| 3004 case SkPath::kInverseEvenOdd_FillType: | 3023 case SkPath::kInverseEvenOdd_FillType: |
| 3005 w &= 1; | 3024 w &= 1; |
| 3006 break; | 3025 break; |
| 3007 default: | 3026 default: |
| 3008 break; | 3027 break; |
| 3009 } | 3028 } |
| 3010 return SkToBool(w); | 3029 return SkToBool(w); |
| 3011 } | 3030 } |
| OLD | NEW |