| /* |
| * 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 "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; |
| 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 dumpFromTo(const SkOpSegment* fromSeg, int from, int to) const; |
| |
| #if DEBUG_ANGLE |
| void setID(int id) { |
| fID = id; |
| } |
| #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 |
| 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 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_SORT |
| void debugOne(bool showFunc) const; // available to testing only |
| #endif |
| #if DEBUG_ANGLE |
| int debugID() const { return fID; } |
| int fID; |
| #endif |
| #if DEBUG_VALIDATE |
| void debugValidateNext() const; // in debug builds, verify that angle loop is uncorrupted |
| #else |
| void debugValidateNext() const {} |
| #endif |
| void dumpLoop() const; // utility to be called by user from debugger |
| void dumpPartials() const; // utility to be called by user from debugger |
| friend class PathOpsAngleTester; |
| }; |
| |
| #endif |