107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com/*
207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com * Copyright 2012 Google Inc.
307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com *
407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com * Use of this source code is governed by a BSD-style license that can be
507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com * found in the LICENSE file.
607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com */
707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#ifndef SkOpAngle_DEFINED
807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#define SkOpAngle_DEFINED
907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
10dac1d17027dcaa5596885a9f333979418b35001ccaryclark#include "SkChunkAlloc.h"
1107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include "SkLineParameters.h"
12cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
13cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.comclass SkOpSegment;
14570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.comstruct SkOpSpan;
1507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
1607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// sorting angles
1707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com// given angles of {dx dy ddx ddy dddx dddy} sort them
1807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass SkOpAngle {
1907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.compublic:
20d892bd8ba676d34d4ce4a73ac7aad88e102fad70caryclark@google.com    enum { kStackBasedCount = 8 }; // FIXME: determine what this should be
21570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    enum IncludeType {
22570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com        kUnaryWinding,
23570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com        kUnaryXor,
24570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com        kBinarySingle,
25570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com        kBinaryOpp,
26570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    };
27d892bd8ba676d34d4ce4a73ac7aad88e102fad70caryclark@google.com
288cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org
294431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    int end() const {
304431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        return fEnd;
3107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
3207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
334431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    const SkOpAngle* findFirst() const;
3407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
354431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool inLoop() const {
364431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        return !!fNext;
3707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
3807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
394431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    void insert(SkOpAngle* );
40cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    bool isHorizontal() const;
414431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    SkOpSpan* lastMarked() const;
428cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org    bool loopContains(const SkOpAngle& ) const;
434431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    int loopCount() const;
444431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    void markStops();
454431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool merge(SkOpAngle* );
4607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
474431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    SkOpAngle* next() const {
484431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        return fNext;
49570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    }
50570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
514431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    SkOpAngle* previous() const;
524431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
53cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    void set(const SkOpSegment* segment, int start, int end);
54ad65a3e5fb1f94699f183551b828efbcc6a133cecaryclark@google.com
55570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    void setLastMarked(SkOpSpan* marked) {
56570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com        fLastMarked = marked;
57570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    }
58570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com
5907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    SkOpSegment* segment() const {
6007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        return const_cast<SkOpSegment*>(fSegment);
6107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
6207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
6307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    int sign() const {
6407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        return SkSign32(fStart - fEnd);
6507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
6607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
674431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool small() const;
684431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
6907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    int start() const {
7007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com        return fStart;
7107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    }
7207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
73cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    bool unorderable() const {
74cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com        return fUnorderable;
75cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    }
76cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
774431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    // available to testing only
784431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#if DEBUG_SORT
794431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    void debugLoop() const;  // called by code during run
804431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#endif
814431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#if DEBUG_ANGLE
824431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    void debugSameAs(const SkOpAngle* compare) const;
83570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com#endif
844431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    void dump() const;
85dac1d17027dcaa5596885a9f333979418b35001ccaryclark    void dumpLoop() const;
86dac1d17027dcaa5596885a9f333979418b35001ccaryclark    void dumpTo(const SkOpSegment* fromSeg, const SkOpAngle* ) const;
87cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
88570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com#if DEBUG_ANGLE
89dac1d17027dcaa5596885a9f333979418b35001ccaryclark    int debugID() const { return fID; }
90dac1d17027dcaa5596885a9f333979418b35001ccaryclark
91cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    void setID(int id) {
92cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com        fID = id;
93cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    }
94dac1d17027dcaa5596885a9f333979418b35001ccaryclark#else
95dac1d17027dcaa5596885a9f333979418b35001ccaryclark    int debugID() const { return 0; }
9607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif
97dac1d17027dcaa5596885a9f333979418b35001ccaryclark
984431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#if DEBUG_VALIDATE
994431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    void debugValidateLoop() const;
1004431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#endif
10107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
10207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comprivate:
1034431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool after(const SkOpAngle* test) const;
1044431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    int allOnOneSide(const SkOpAngle& test) const;
1054431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool calcSlop(double x, double y, double rx, double ry, bool* result) const;
1064431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool checkCrossesZero() const;
1074431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool checkParallel(const SkOpAngle& ) const;
1084431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool computeSector();
1094431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    int convexHullOverlaps(const SkOpAngle& ) const;
1104431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    double distEndRatio(double dist) const;
1114431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    int findSector(SkPath::Verb verb, double x, double y) const;
1124431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool endsIntersect(const SkOpAngle& ) const;
1134431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    double midT() const;
1144431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool oppositePlanes(const SkOpAngle& rh) const;
1154431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool orderable(const SkOpAngle& rh) const;  // false == this < rh ; true == this > rh
1168cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org    bool overlap(const SkOpAngle& test) const;
1174431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    void setCurveHullSweep();
1184431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    void setSector();
119cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    void setSpans();
1204431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool tangentsDiverge(const SkOpAngle& rh, double s0xt0) const;
121cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com
122570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    SkDCubic fCurvePart; // the curve from start to end
12307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    double fSide;
1244431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    SkLineParameters fTangentHalf;  // used only to sort a pair of lines or line-like sections
12507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    const SkOpSegment* fSegment;
1264431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    SkOpAngle* fNext;
127570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com    SkOpSpan* fLastMarked;
1284431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    SkDVector fSweep[2];
12907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    int fStart;
13007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com    int fEnd;
131dac1d17027dcaa5596885a9f333979418b35001ccaryclark    int fComputedEnd;
1324431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    int fSectorMask;
1338608463e17be8b3d96104307d0796a5c8ebca511commit-bot@chromium.org    int8_t fSectorStart;  // in 32nds of a circle
1348608463e17be8b3d96104307d0796a5c8ebca511commit-bot@chromium.org    int8_t fSectorEnd;
1354431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool fIsCurve;
1364431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool fStop; // set if ordered angle is greater than the previous
1374431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    mutable bool fUnorderable;  // this is editable by orderable()
1384431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool fUnorderedSweep;  // set when a cubic's first control point between the sweep vectors
1394431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool fComputeSector;
1404431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool fComputedSector;
1414431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
142cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com#if DEBUG_ANGLE
143cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com    int fID;
144cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com#endif
1454431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#if DEBUG_VALIDATE
1464431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    void debugValidateNext() const;  // in debug builds, verify that angle loop is uncorrupted
1474431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#else
1484431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    void debugValidateNext() const {}
1494431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#endif
150dac1d17027dcaa5596885a9f333979418b35001ccaryclark    void dumpOne(bool showFunc) const;  // available to testing only
1514431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    void dumpPartials() const;  // utility to be called by user from debugger
1524431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    friend class PathOpsAngleTester;
15307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com};
15407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com
155dac1d17027dcaa5596885a9f333979418b35001ccaryclarkclass SkOpAngleSet {
156dac1d17027dcaa5596885a9f333979418b35001ccaryclarkpublic:
157dac1d17027dcaa5596885a9f333979418b35001ccaryclark    SkOpAngleSet();
158dac1d17027dcaa5596885a9f333979418b35001ccaryclark    ~SkOpAngleSet();
159dac1d17027dcaa5596885a9f333979418b35001ccaryclark    SkOpAngle& push_back();
160dac1d17027dcaa5596885a9f333979418b35001ccaryclark    void reset();
161dac1d17027dcaa5596885a9f333979418b35001ccaryclarkprivate:
162dac1d17027dcaa5596885a9f333979418b35001ccaryclark    void dump() const;  // utility to be called by user from debugger
163dac1d17027dcaa5596885a9f333979418b35001ccaryclark#if DEBUG_ANGLE
164dac1d17027dcaa5596885a9f333979418b35001ccaryclark    int fCount;
165dac1d17027dcaa5596885a9f333979418b35001ccaryclark#endif
166dac1d17027dcaa5596885a9f333979418b35001ccaryclark    SkChunkAlloc* fAngles;
167dac1d17027dcaa5596885a9f333979418b35001ccaryclark};
168dac1d17027dcaa5596885a9f333979418b35001ccaryclark
16907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif
170