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

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

Issue 48783002: perpendicular round rects; fuzzy convexity (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: fix release warning Created 7 years, 1 month 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
« src/core/SkGeometry.cpp ('K') | « src/core/SkGeometry.cpp ('k') | no next file » | 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 2265 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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 }
OLDNEW
« src/core/SkGeometry.cpp ('K') | « src/core/SkGeometry.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698