| Index: src/pathops/SkPathOpsTypes.h
|
| diff --git a/src/pathops/SkPathOpsTypes.h b/src/pathops/SkPathOpsTypes.h
|
| index 01fec0d0b616a7d324dd2e1cd9d0e72cca9d204c..0248e7115a6d0066c54af5fb21fd0ab8ecf10e48 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;
|
|
|
|
|