Mike R: please sanity check SkPostConfig.h
Mike K: please sanity check Test.cpp and skia_test.cpp

Feel free to look at the rest, but I don't expect any in depth review of path ops innards.

Path Ops first iteration used QuickSort to order segments radiating from an intersection to compute the winding rule.

This revision uses a circular sort instead. Breaking out the circular sort into its own long-lived structure (SkOpAngle) allows doing less work and provides a home for caching additional sorting data.

The circle sort is more stable than the former sort, has a robust ordering and fewer exceptions. It finds unsortable ordering less often. It is less reliant on the initial curve  tangent, using convex hulls instead whenever it can.

Additional debug validation makes sure that the computed structures are self-consistent. A new visualization tool helps verify that the angle ordering is correct.

The 70+M tests pass with this change on Windows, Mac, Linux 32 and Linux 64 in debug and release.

R=mtklein@google.com, reed@google.com

Author: caryclark@google.com

Review URL: https://codereview.chromium.org/131103009

git-svn-id: http://skia.googlecode.com/svn/trunk@14183 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/pathops/SkOpSpan.h b/src/pathops/SkOpSpan.h
index 81ede1c..2fe0b61 100644
--- a/src/pathops/SkOpSpan.h
+++ b/src/pathops/SkOpSpan.h
@@ -17,20 +17,24 @@
     double fT;
     double fOtherT;  // value at fOther[fOtherIndex].fT
     int fOtherIndex;  // can't be used during intersection
+    int fFromAngleIndex;  // (if t > 0) index into segment's angle array going negative in t
+    int fToAngleIndex;  // (if t < 1) index into segment's angle array going positive in t
     int fWindSum;  // accumulated from contours surrounding this one.
     int fOppSum;  // for binary operators: the opposite winding sum
     int fWindValue;  // 0 == canceled; 1 == normal; >1 == coincident
     int fOppValue;  // normally 0 -- when binary coincident edges combine, opp value goes here
+    bool fChased;  // set after span has been added to chase array
     bool fDone;  // if set, this span to next higher T has been processed
+    bool fLoop;  // set when a cubic loops back to this point
+    bool fSmall;   // if set, consecutive points are almost equal
+    bool fTiny;  // if set, consecutive points are equal but consecutive ts are not precisely equal
     bool fUnsortableStart;  // set when start is part of an unsortable pair
     bool fUnsortableEnd;  // set when end is part of an unsortable pair
-    bool fSmall;   // if set, consecutive points are almost equal
-    bool fTiny;  // if set, span may still be considered once for edge following
-    bool fLoop;  // set when a cubic loops back to this point
 
-#ifdef SK_DEBUG
+    // available to testing only
+    const SkOpSegment* debugToSegment(ptrdiff_t* ) const;
     void dump() const;
-#endif
+    void dumpOne() const;
 };
 
 #endif