Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Side by Side Diff: src/core/SkPath.cpp

Issue 298973004: In convexity checker don't advance last vector when x-product isn't significant. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: remove debugging code Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/PathTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | tests/PathTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698