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 2205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2216 } | 2216 } |
2217 #endif // SK_DEBUG_PATH | 2217 #endif // SK_DEBUG_PATH |
2218 } | 2218 } |
2219 #endif // SK_DEBUG | 2219 #endif // SK_DEBUG |
2220 | 2220 |
2221 /////////////////////////////////////////////////////////////////////////////// | 2221 /////////////////////////////////////////////////////////////////////////////// |
2222 | 2222 |
2223 static int sign(SkScalar x) { return x < 0; } | 2223 static int sign(SkScalar x) { return x < 0; } |
2224 #define kValueNeverReturnedBySign 2 | 2224 #define kValueNeverReturnedBySign 2 |
2225 | 2225 |
2226 static bool AlmostEqual(SkScalar compA, SkScalar compB) { | 2226 static bool almost_equal(SkScalar compA, SkScalar compB) { |
2227 // The error epsilon was empirically derived; worse case round rects | 2227 // The error epsilon was empirically derived; worse case round rects |
2228 // with a mid point outset by 2x float epsilon in tests had an error | 2228 // with a mid point outset by 2x float epsilon in tests had an error |
2229 // of 12. | 2229 // of 12. |
2230 const int epsilon = 16; | 2230 const int epsilon = 16; |
2231 if (!SkScalarIsFinite(compA) || !SkScalarIsFinite(compB)) { | 2231 if (!SkScalarIsFinite(compA) || !SkScalarIsFinite(compB)) { |
2232 return false; | 2232 return false; |
2233 } | 2233 } |
2234 // no need to check for small numbers because SkPath::Iter has removed degen
erate values | 2234 // no need to check for small numbers because SkPath::Iter has removed degen
erate values |
2235 int aBits = SkFloatAs2sCompliment(compA); | 2235 int aBits = SkFloatAs2sCompliment(compA); |
2236 int bBits = SkFloatAs2sCompliment(compB); | 2236 int bBits = SkFloatAs2sCompliment(compB); |
2237 return aBits < bBits + epsilon && bBits < aBits + epsilon; | 2237 return aBits < bBits + epsilon && bBits < aBits + epsilon; |
2238 } | 2238 } |
2239 | 2239 |
2240 // only valid for a single contour | 2240 // only valid for a single contour |
2241 struct Convexicator { | 2241 struct Convexicator { |
2242 Convexicator() | 2242 Convexicator() |
2243 : fPtCount(0) | 2243 : fPtCount(0) |
2244 , fConvexity(SkPath::kConvex_Convexity) | 2244 , fConvexity(SkPath::kConvex_Convexity) |
2245 , fDirection(SkPath::kUnknown_Direction) { | 2245 , fDirection(SkPath::kUnknown_Direction) { |
2246 fSign = 0; | 2246 fSign = 0; |
2247 // warnings | 2247 // warnings |
2248 fLastPt.set(0, 0); | 2248 fLastPt.set(0, 0); |
2249 fCurrPt.set(0, 0); | 2249 fCurrPt.set(0, 0); |
2250 fVec0.set(0, 0); | 2250 fLastVec.set(0, 0); |
2251 fVec1.set(0, 0); | |
2252 fFirstVec.set(0, 0); | 2251 fFirstVec.set(0, 0); |
2253 | 2252 |
2254 fDx = fDy = 0; | 2253 fDx = fDy = 0; |
2255 fSx = fSy = kValueNeverReturnedBySign; | 2254 fSx = fSy = kValueNeverReturnedBySign; |
2256 } | 2255 } |
2257 | 2256 |
2258 SkPath::Convexity getConvexity() const { return fConvexity; } | 2257 SkPath::Convexity getConvexity() const { return fConvexity; } |
2259 | 2258 |
2260 /** The direction returned is only valid if the path is determined convex */ | 2259 /** The direction returned is only valid if the path is determined convex */ |
2261 SkPath::Direction getDirection() const { return fDirection; } | 2260 SkPath::Direction getDirection() const { return fDirection; } |
2262 | 2261 |
2263 void addPt(const SkPoint& pt) { | 2262 void addPt(const SkPoint& pt) { |
2264 if (SkPath::kConcave_Convexity == fConvexity) { | 2263 if (SkPath::kConcave_Convexity == fConvexity) { |
2265 return; | 2264 return; |
2266 } | 2265 } |
2267 | 2266 |
2268 if (0 == fPtCount) { | 2267 if (0 == fPtCount) { |
2269 fCurrPt = pt; | 2268 fCurrPt = pt; |
2270 ++fPtCount; | 2269 ++fPtCount; |
2271 } else { | 2270 } else { |
2272 SkVector vec = pt - fCurrPt; | 2271 SkVector vec = pt - fCurrPt; |
2273 if (vec.fX || vec.fY) { | 2272 if (vec.fX || vec.fY) { |
2274 fLastPt = fCurrPt; | 2273 fLastPt = fCurrPt; |
2275 fCurrPt = pt; | 2274 fCurrPt = pt; |
2276 if (++fPtCount == 2) { | 2275 if (++fPtCount == 2) { |
2277 fFirstVec = fVec1 = vec; | 2276 fFirstVec = fLastVec = vec; |
2278 } else { | 2277 } else { |
2279 SkASSERT(fPtCount > 2); | 2278 SkASSERT(fPtCount > 2); |
2280 this->addVec(vec); | 2279 this->addVec(vec); |
2281 } | 2280 } |
2282 | 2281 |
2283 int sx = sign(vec.fX); | 2282 int sx = sign(vec.fX); |
2284 int sy = sign(vec.fY); | 2283 int sy = sign(vec.fY); |
2285 fDx += (sx != fSx); | 2284 fDx += (sx != fSx); |
2286 fDy += (sy != fSy); | 2285 fDy += (sy != fSy); |
2287 fSx = sx; | 2286 fSx = sx; |
2288 fSy = sy; | 2287 fSy = sy; |
2289 | 2288 |
2290 if (fDx > 3 || fDy > 3) { | 2289 if (fDx > 3 || fDy > 3) { |
2291 fConvexity = SkPath::kConcave_Convexity; | 2290 fConvexity = SkPath::kConcave_Convexity; |
2292 } | 2291 } |
2293 } | 2292 } |
2294 } | 2293 } |
2295 } | 2294 } |
2296 | 2295 |
2297 void close() { | 2296 void close() { |
2298 if (fPtCount > 2) { | 2297 if (fPtCount > 2) { |
2299 this->addVec(fFirstVec); | 2298 this->addVec(fFirstVec); |
2300 } | 2299 } |
2301 } | 2300 } |
2302 | 2301 |
2303 private: | 2302 private: |
2304 void addVec(const SkVector& vec) { | 2303 void addVec(const SkVector& vec) { |
2305 SkASSERT(vec.fX || vec.fY); | 2304 SkASSERT(vec.fX || vec.fY); |
2306 fVec0 = fVec1; | 2305 SkScalar cross = SkPoint::CrossProduct(fLastVec, vec); |
2307 fVec1 = vec; | |
2308 SkScalar cross = SkPoint::CrossProduct(fVec0, fVec1); | |
2309 SkScalar smallest = SkTMin(fCurrPt.fX, SkTMin(fCurrPt.fY, SkTMin(fLastPt
.fX, fLastPt.fY))); | 2306 SkScalar smallest = SkTMin(fCurrPt.fX, SkTMin(fCurrPt.fY, SkTMin(fLastPt
.fX, fLastPt.fY))); |
2310 SkScalar largest = SkTMax(fCurrPt.fX, SkTMax(fCurrPt.fY, SkTMax(fLastPt.
fX, fLastPt.fY))); | 2307 SkScalar largest = SkTMax(fCurrPt.fX, SkTMax(fCurrPt.fY, SkTMax(fLastPt.
fX, fLastPt.fY))); |
2311 largest = SkTMax(largest, -smallest); | 2308 largest = SkTMax(largest, -smallest); |
2312 int sign = AlmostEqual(largest, largest + cross) ? 0 : SkScalarSignAsInt
(cross); | 2309 if (!almost_equal(largest, largest + cross)) { |
2313 if (0 == fSign) { | 2310 int sign = SkScalarSignAsInt(cross); |
2314 fSign = sign; | 2311 if (0 == fSign) { |
2315 if (1 == sign) { | 2312 fSign = sign; |
2316 fDirection = SkPath::kCW_Direction; | 2313 fDirection = (1 == sign) ? SkPath::kCW_Direction : SkPath::kCCW_
Direction; |
2317 } else if (-1 == sign) { | 2314 } else if (sign && fSign != sign) { |
2318 fDirection = SkPath::kCCW_Direction; | |
2319 } | |
2320 } else if (sign) { | |
2321 if (fSign != sign) { | |
2322 fConvexity = SkPath::kConcave_Convexity; | 2315 fConvexity = SkPath::kConcave_Convexity; |
2323 fDirection = SkPath::kUnknown_Direction; | 2316 fDirection = SkPath::kUnknown_Direction; |
2324 } | 2317 } |
| 2318 fLastVec = vec; |
2325 } | 2319 } |
2326 } | 2320 } |
2327 | 2321 |
2328 SkPoint fLastPt; | 2322 SkPoint fLastPt; |
2329 SkPoint fCurrPt; | 2323 SkPoint fCurrPt; |
2330 SkVector fVec0, fVec1, fFirstVec; | 2324 // fLastVec does not necessarily start at fLastPt. We only advance it when t
he cross product |
| 2325 // value with the current vec is deemed to be of a significant value. |
| 2326 SkVector fLastVec, fFirstVec; |
2331 int fPtCount; // non-degenerate points | 2327 int fPtCount; // non-degenerate points |
2332 int fSign; | 2328 int fSign; |
2333 SkPath::Convexity fConvexity; | 2329 SkPath::Convexity fConvexity; |
2334 SkPath::Direction fDirection; | 2330 SkPath::Direction fDirection; |
2335 int fDx, fDy, fSx, fSy; | 2331 int fDx, fDy, fSx, fSy; |
2336 }; | 2332 }; |
2337 | 2333 |
2338 SkPath::Convexity SkPath::internalGetConvexity() const { | 2334 SkPath::Convexity SkPath::internalGetConvexity() const { |
2339 SkASSERT(kUnknown_Convexity == fConvexity); | 2335 SkASSERT(kUnknown_Convexity == fConvexity); |
2340 SkPoint pts[4]; | 2336 SkPoint pts[4]; |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2887 switch (this->getFillType()) { | 2883 switch (this->getFillType()) { |
2888 case SkPath::kEvenOdd_FillType: | 2884 case SkPath::kEvenOdd_FillType: |
2889 case SkPath::kInverseEvenOdd_FillType: | 2885 case SkPath::kInverseEvenOdd_FillType: |
2890 w &= 1; | 2886 w &= 1; |
2891 break; | 2887 break; |
2892 default: | 2888 default: |
2893 break; | 2889 break; |
2894 } | 2890 } |
2895 return SkToBool(w); | 2891 return SkToBool(w); |
2896 } | 2892 } |
OLD | NEW |