diff options
author | caryclark <caryclark@google.com> | 2015-03-24 07:28:17 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-24 07:28:17 -0700 |
commit | ccec0f958ffc71a9986d236bc2eb335cb2111119 (patch) | |
tree | f864209e3594293256ac391715d50222ff22d96b /src/pathops/SkPathOpsTypes.h | |
parent | 62a320c8d444cd04e4f2952c269ea4cbd58dee64 (diff) |
pathops version two
R=reed@google.com
marked 'no commit' to attempt to get trybots to run
TBR=reed@google.com
Review URL: https://codereview.chromium.org/1002693002
Diffstat (limited to 'src/pathops/SkPathOpsTypes.h')
-rw-r--r-- | src/pathops/SkPathOpsTypes.h | 129 |
1 files changed, 121 insertions, 8 deletions
diff --git a/src/pathops/SkPathOpsTypes.h b/src/pathops/SkPathOpsTypes.h index 01fec0d0b6..0248e7115a 100644 --- a/src/pathops/SkPathOpsTypes.h +++ b/src/pathops/SkPathOpsTypes.h @@ -22,6 +22,111 @@ enum SkPathOpsMask { kEvenOdd_PathOpsMask = 1 }; +class SkOpCoincidence; +class SkOpContour; + +class SkOpGlobalState { +public: + SkOpGlobalState(SkOpCoincidence* coincidence PATH_OPS_DEBUG_PARAMS(SkOpContour* head)) + : fCoincidence(coincidence) + , fWindingFailed(false) + , fAngleCoincidence(false) +#if DEBUG_VALIDATE + , fPhase(kIntersecting) +#endif + PATH_OPS_DEBUG_PARAMS(fHead(head)) + PATH_OPS_DEBUG_PARAMS(fAngleID(0)) + PATH_OPS_DEBUG_PARAMS(fContourID(0)) + PATH_OPS_DEBUG_PARAMS(fPtTID(0)) + PATH_OPS_DEBUG_PARAMS(fSegmentID(0)) + PATH_OPS_DEBUG_PARAMS(fSpanID(0)) { + } + +#if DEBUG_VALIDATE + enum Phase { + kIntersecting, + kWalking + }; +#endif + + bool angleCoincidence() { + return fAngleCoincidence; + } + + SkOpCoincidence* coincidence() { + return fCoincidence; + } + +#ifdef SK_DEBUG + const struct SkOpAngle* debugAngle(int id) const; + SkOpContour* debugContour(int id); + const class SkOpPtT* debugPtT(int id) const; + const class SkOpSegment* debugSegment(int id) const; + const class SkOpSpanBase* debugSpan(int id) const; + + int nextAngleID() { + return ++fAngleID; + } + + int nextContourID() { + return ++fContourID; + } + int nextPtTID() { + return ++fPtTID; + } + + int nextSegmentID() { + return ++fSegmentID; + } + + int nextSpanID() { + return ++fSpanID; + } +#endif + +#if DEBUG_VALIDATE + Phase phase() const { + return fPhase; + } +#endif + + void setAngleCoincidence() { + fAngleCoincidence = true; + } + +#if DEBUG_VALIDATE + void setPhase(Phase phase) { + SkASSERT(fPhase != phase); + fPhase = phase; + } +#endif + + // called in very rare cases where angles are sorted incorrectly -- signfies op will fail + void setWindingFailed() { + fWindingFailed = true; + } + + bool windingFailed() const { + return fWindingFailed; + } + +private: + SkOpCoincidence* fCoincidence; + bool fWindingFailed; + bool fAngleCoincidence; +#if DEBUG_VALIDATE + Phase fPhase; +#endif +#ifdef SK_DEBUG + SkOpContour* fHead; + int fAngleID; + int fContourID; + int fPtTID; + int fSegmentID; + int fSpanID; +#endif +}; + // Use Almost Equal when comparing coordinates. Use epsilon to compare T values. bool AlmostEqualUlps(float a, float b); inline bool AlmostEqualUlps(double a, double b) { @@ -92,6 +197,7 @@ const double DBL_EPSILON_SUBDIVIDE_ERR = DBL_EPSILON * 16; const double ROUGH_EPSILON = FLT_EPSILON * 64; const double MORE_ROUGH_EPSILON = FLT_EPSILON * 256; const double WAY_ROUGH_EPSILON = FLT_EPSILON * 2048; +const double BUMP_EPSILON = FLT_EPSILON * 4096; inline bool zero_or_one(double x) { return x == 0 || x == 1; @@ -141,12 +247,6 @@ inline bool roughly_zero(double x) { return fabs(x) < ROUGH_EPSILON; } -#if 0 // unused for now -inline bool way_roughly_zero(double x) { - return fabs(x) < WAY_ROUGH_EPSILON; -} -#endif - inline bool approximately_zero_inverse(double x) { return fabs(x) > FLT_EPSILON_INVERSE; } @@ -156,6 +256,10 @@ inline bool approximately_zero_when_compared_to(double x, double y) { return x == 0 || fabs(x) < fabs(y * FLT_EPSILON); } +inline bool precisely_zero_when_compared_to(double x, double y) { + return x == 0 || fabs(x) < fabs(y * DBL_EPSILON); +} + // Use this for comparing Ts in the range of 0 to 1. For general numbers (larger and smaller) use // AlmostEqualUlps instead. inline bool approximately_equal(double x, double y) { @@ -304,7 +408,8 @@ inline bool precisely_between(double a, double b, double c) { // returns true if (a <= b <= c) || (a >= b >= c) inline bool between(double a, double b, double c) { - SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0)); + SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0) + || (precisely_zero(a) && precisely_zero(b) && precisely_zero(c))); return (a - b) * (c - b) <= 0; } @@ -312,6 +417,15 @@ inline bool roughly_equal(double x, double y) { return fabs(x - y) < ROUGH_EPSILON; } +inline bool roughly_negative(double x) { + return x < ROUGH_EPSILON; +} + +inline bool roughly_between(double a, double b, double c) { + return a <= c ? roughly_negative(a - b) && roughly_negative(b - c) + : roughly_negative(b - a) && roughly_negative(c - b); +} + inline bool more_roughly_equal(double x, double y) { return fabs(x - y) < MORE_ROUGH_EPSILON; } @@ -324,7 +438,6 @@ struct SkDPoint; struct SkDVector; struct SkDLine; struct SkDQuad; -struct SkDTriangle; struct SkDCubic; struct SkDRect; |