aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops/SkPathOpsTypes.h
diff options
context:
space:
mode:
authorGravatar caryclark <caryclark@google.com>2015-03-24 07:28:17 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-03-24 07:28:17 -0700
commitccec0f958ffc71a9986d236bc2eb335cb2111119 (patch)
treef864209e3594293256ac391715d50222ff22d96b /src/pathops/SkPathOpsTypes.h
parent62a320c8d444cd04e4f2952c269ea4cbd58dee64 (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.h129
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;