|  | /* | 
|  | * Copyright 2012 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  | #ifndef SkOpAngle_DEFINED | 
|  | #define SkOpAngle_DEFINED | 
|  |  | 
|  | #include "SkChunkAlloc.h" | 
|  | #include "SkLineParameters.h" | 
|  |  | 
|  | class SkOpSegment; | 
|  | struct SkOpSpan; | 
|  |  | 
|  | // sorting angles | 
|  | // given angles of {dx dy ddx ddy dddx dddy} sort them | 
|  | class SkOpAngle { | 
|  | public: | 
|  | enum { kStackBasedCount = 8 }; // FIXME: determine what this should be | 
|  | enum IncludeType { | 
|  | kUnaryWinding, | 
|  | kUnaryXor, | 
|  | kBinarySingle, | 
|  | kBinaryOpp, | 
|  | }; | 
|  |  | 
|  |  | 
|  | int end() const { | 
|  | return fEnd; | 
|  | } | 
|  |  | 
|  | const SkOpAngle* findFirst() const; | 
|  |  | 
|  | bool inLoop() const { | 
|  | return !!fNext; | 
|  | } | 
|  |  | 
|  | void insert(SkOpAngle* ); | 
|  | bool isHorizontal() const; | 
|  | SkOpSpan* lastMarked() const; | 
|  | bool loopContains(const SkOpAngle& ) const; | 
|  | int loopCount() const; | 
|  | void markStops(); | 
|  | bool merge(SkOpAngle* ); | 
|  |  | 
|  | SkOpAngle* next() const { | 
|  | return fNext; | 
|  | } | 
|  |  | 
|  | SkOpAngle* previous() const; | 
|  |  | 
|  | void set(const SkOpSegment* segment, int start, int end); | 
|  |  | 
|  | void setLastMarked(SkOpSpan* marked) { | 
|  | fLastMarked = marked; | 
|  | } | 
|  |  | 
|  | SkOpSegment* segment() const { | 
|  | return const_cast<SkOpSegment*>(fSegment); | 
|  | } | 
|  |  | 
|  | int sign() const { | 
|  | return SkSign32(fStart - fEnd); | 
|  | } | 
|  |  | 
|  | bool small() const; | 
|  |  | 
|  | int start() const { | 
|  | return fStart; | 
|  | } | 
|  |  | 
|  | bool unorderable() const { | 
|  | return fUnorderable; | 
|  | } | 
|  |  | 
|  | // available to testing only | 
|  | #if DEBUG_SORT | 
|  | void debugLoop() const;  // called by code during run | 
|  | #endif | 
|  | #if DEBUG_ANGLE | 
|  | void debugSameAs(const SkOpAngle* compare) const; | 
|  | #endif | 
|  | void dump() const; | 
|  | void dumpLoop() const; | 
|  | void dumpTo(const SkOpSegment* fromSeg, const SkOpAngle* ) const; | 
|  |  | 
|  | #if DEBUG_ANGLE | 
|  | int debugID() const { return fID; } | 
|  |  | 
|  | void setID(int id) { | 
|  | fID = id; | 
|  | } | 
|  | #else | 
|  | int debugID() const { return 0; } | 
|  | #endif | 
|  |  | 
|  | #if DEBUG_VALIDATE | 
|  | void debugValidateLoop() const; | 
|  | #endif | 
|  |  | 
|  | private: | 
|  | bool after(const SkOpAngle* test) const; | 
|  | int allOnOneSide(const SkOpAngle& test) const; | 
|  | bool calcSlop(double x, double y, double rx, double ry, bool* result) const; | 
|  | bool checkCrossesZero() const; | 
|  | bool checkParallel(const SkOpAngle& ) const; | 
|  | bool computeSector(); | 
|  | int convexHullOverlaps(const SkOpAngle& ) const; | 
|  | double distEndRatio(double dist) const; | 
|  | int findSector(SkPath::Verb verb, double x, double y) const; | 
|  | bool endsIntersect(const SkOpAngle& ) const; | 
|  | double midT() const; | 
|  | bool oppositePlanes(const SkOpAngle& rh) const; | 
|  | bool orderable(const SkOpAngle& rh) const;  // false == this < rh ; true == this > rh | 
|  | bool overlap(const SkOpAngle& test) const; | 
|  | void setCurveHullSweep(); | 
|  | void setSector(); | 
|  | void setSpans(); | 
|  | bool tangentsDiverge(const SkOpAngle& rh, double s0xt0) const; | 
|  |  | 
|  | SkDCubic fCurvePart; // the curve from start to end | 
|  | double fSide; | 
|  | SkLineParameters fTangentHalf;  // used only to sort a pair of lines or line-like sections | 
|  | const SkOpSegment* fSegment; | 
|  | SkOpAngle* fNext; | 
|  | SkOpSpan* fLastMarked; | 
|  | SkDVector fSweep[2]; | 
|  | int fStart; | 
|  | int fEnd; | 
|  | int fComputedEnd; | 
|  | int fSectorMask; | 
|  | int8_t fSectorStart;  // in 32nds of a circle | 
|  | int8_t fSectorEnd; | 
|  | bool fIsCurve; | 
|  | bool fStop; // set if ordered angle is greater than the previous | 
|  | mutable bool fUnorderable;  // this is editable by orderable() | 
|  | bool fUnorderedSweep;  // set when a cubic's first control point between the sweep vectors | 
|  | bool fComputeSector; | 
|  | bool fComputedSector; | 
|  |  | 
|  | #if DEBUG_ANGLE | 
|  | int fID; | 
|  | #endif | 
|  | #if DEBUG_VALIDATE | 
|  | void debugValidateNext() const;  // in debug builds, verify that angle loop is uncorrupted | 
|  | #else | 
|  | void debugValidateNext() const {} | 
|  | #endif | 
|  | void dumpOne(bool showFunc) const;  // available to testing only | 
|  | void dumpPartials() const;  // utility to be called by user from debugger | 
|  | friend class PathOpsAngleTester; | 
|  | }; | 
|  |  | 
|  | class SkOpAngleSet { | 
|  | public: | 
|  | SkOpAngleSet(); | 
|  | ~SkOpAngleSet(); | 
|  | SkOpAngle& push_back(); | 
|  | void reset(); | 
|  | private: | 
|  | void dump() const;  // utility to be called by user from debugger | 
|  | #if DEBUG_ANGLE | 
|  | int fCount; | 
|  | #endif | 
|  | SkChunkAlloc* fAngles; | 
|  | }; | 
|  |  | 
|  | #endif |