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 |