17839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/*
27839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Copyright 2013 Google Inc.
37839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *
47839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be
57839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * found in the LICENSE file.
67839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger */
77839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#ifndef SkOpContour_DEFINED
87839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#define SkOpContour_DEFINED
97839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkOpSegment.h"
117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkTArray.h"
127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass SkIntersections;
147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass SkOpContour;
157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass SkPathWriter;
167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstruct SkCoincidence {
180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkOpContour* fOther;
197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int fSegments[2];
207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    double fTs[2][2];
217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPoint fPts[2];
227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerclass SkOpContour {
257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerpublic:
267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkOpContour() {
277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        reset();
280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#ifdef SK_DEBUG
290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fID = ++SkPathOpsDebug::gContourID;
307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool operator<(const SkOpContour& rh) const {
347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fBounds.fTop == rh.fBounds.fTop
357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                ? fBounds.fLeft < rh.fBounds.fLeft
367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                : fBounds.fTop < rh.fBounds.fTop;
377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool addCoincident(int index, SkOpContour* other, int otherIndex,
407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                       const SkIntersections& ts, bool swap);
417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void addCoincidentPoints();
427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void addCross(const SkOpContour* crosser) {
447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#ifdef DEBUG_CROSS
457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int index = 0; index < fCrosses.count(); ++index) {
467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            SkASSERT(fCrosses[index] != crosser);
477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
4958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        fCrosses.push_back(crosser);
507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void addCubic(const SkPoint pts[4]) {
537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fSegments.push_back().addCubic(pts, fOperand, fXor);
547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fContainsCurves = fContainsCubics = true;
557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int addLine(const SkPoint pts[2]) {
587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fSegments.push_back().addLine(pts, fOperand, fXor);
597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fSegments.count();
607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void addOtherT(int segIndex, int tIndex, double otherT, int otherIndex) {
637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fSegments[segIndex].addOtherT(tIndex, otherT, otherIndex);
647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool addPartialCoincident(int index, SkOpContour* other, int otherIndex,
670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                       const SkIntersections& ts, int ptIndex, bool swap);
680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int addQuad(const SkPoint pts[3]) {
707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fSegments.push_back().addQuad(pts, fOperand, fXor);
717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fContainsCurves = true;
727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fSegments.count();
737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
75910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    int addT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint& pt, double newT) {
767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        setContainsIntercepts();
77910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger        return fSegments[segIndex].addT(&other->fSegments[otherIndex], pt, newT);
787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int addSelfT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint& pt, double newT) {
817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        setContainsIntercepts();
827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fSegments[segIndex].addSelfT(&other->fSegments[otherIndex], pt, newT);
837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const SkPathOpsBounds& bounds() const {
867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fBounds;
877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void calcCoincidentWinding();
900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void calcPartialCoincidentWinding();
917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
9258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    void checkEnds() {
9358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        if (!fContainsCurves) {
9458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            return;
9558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        }
9658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        int segmentCount = fSegments.count();
9758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
9858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            SkOpSegment* segment = &fSegments[sIndex];
9958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            if (segment->verb() == SkPath::kLine_Verb) {
10058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger                continue;
10158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            }
1020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (segment->done()) {
1030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                continue;   // likely coincident, nothing to do
1040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
1050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            segment->checkEnds();
1060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
1070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
1080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // if same point has different T values, choose a common T
1100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void checkTiny() {
1110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        int segmentCount = fSegments.count();
1120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (segmentCount <= 2) {
1130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return;
1140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
1150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
1160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            fSegments[sIndex].checkTiny();
11758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        }
11858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
11958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
1207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void complete() {
1217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        setBounds();
1227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fContainsIntercepts = false;
1237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool containsCubics() const {
1267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fContainsCubics;
1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool crosses(const SkOpContour* crosser) const {
1307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int index = 0; index < fCrosses.count(); ++index) {
1317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            if (fCrosses[index] == crosser) {
1327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                return true;
1337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
1347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return false;
1367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool done() const {
1397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fDone;
1407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const SkPoint& end() const {
1437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        const SkOpSegment& segment = fSegments.back();
14458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return segment.pts()[SkPathOpsVerbToPoints(segment.verb())];
1457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void fixOtherTIndex() {
1487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int segmentCount = fSegments.count();
1497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int sIndex = 0; sIndex < segmentCount; ++sIndex) {
1507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fSegments[sIndex].fixOtherTIndex();
1517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void joinCoincidence() {
1550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        joinCoincidence(fCoincidences, false);
1560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        joinCoincidence(fPartialCoincidences, true);
1570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
1580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkOpSegment* nonVerticalSegment(int* start, int* end);
1607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool operand() const {
1627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fOperand;
1637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void reset() {
1667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fSegments.reset();
1677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, SK_ScalarMax);
1687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fContainsCurves = fContainsCubics = fContainsIntercepts = fDone = false;
1697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkTArray<SkOpSegment>& segments() {
1727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fSegments;
1737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void setContainsIntercepts() {
1767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fContainsIntercepts = true;
1777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void setOperand(bool isOp) {
1807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fOperand = isOp;
1817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void setOppXor(bool isOppXor) {
1847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fOppXor = isOppXor;
1857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int segmentCount = fSegments.count();
1867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int test = 0; test < segmentCount; ++test) {
1877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fSegments[test].setOppXor(isOppXor);
1887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void setXor(bool isXor) {
1927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fXor = isXor;
1937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void sortSegments();
1967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
1977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    const SkPoint& start() const {
1987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fSegments.front().pts()[0];
1997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
2007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void toPath(SkPathWriter* path) const;
2027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void toPartialBackward(SkPathWriter* path) const {
2047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int segmentCount = fSegments.count();
2057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int test = segmentCount - 1; test >= 0; --test) {
2067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fSegments[test].addCurveTo(1, 0, path, true);
2077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
2097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void toPartialForward(SkPathWriter* path) const {
2117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        int segmentCount = fSegments.count();
2127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int test = 0; test < segmentCount; ++test) {
2137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fSegments[test].addCurveTo(0, 1, path, true);
2147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
2167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void topSortableSegment(const SkPoint& topLeft, SkPoint* bestXY, SkOpSegment** topStart);
2187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkOpSegment* undoneSegment(int* start, int* end);
2197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int updateSegment(int index, const SkPoint* pts) {
2217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        SkOpSegment& segment = fSegments[index];
2227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        segment.updatePts(pts);
22358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        return SkPathOpsVerbToPoints(segment.verb()) + 1;
2247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
2257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if DEBUG_TEST
2277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkTArray<SkOpSegment>& debugSegments() {
2287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return fSegments;
2297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
2307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
2317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
2337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void debugShowActiveSpans() {
2347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        for (int index = 0; index < fSegments.count(); ++index) {
2357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            fSegments[index].debugShowActiveSpans();
2367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
2377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
2387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
2397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if DEBUG_SHOW_WINDING
2417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int debugShowWindingValues(int totalSegments, int ofInterest);
24258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    static void debugShowWindingValues(const SkTArray<SkOpContour*, true>& contourList);
2437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
2447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerprivate:
2460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void calcCommonCoincidentWinding(const SkCoincidence& );
2470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void joinCoincidence(const SkTArray<SkCoincidence, true>& , bool partial);
2487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void setBounds();
2497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkTArray<SkOpSegment> fSegments;
25158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkTArray<SkOpSegment*, true> fSortedSegments;
2527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int fFirstSorted;
25358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkTArray<SkCoincidence, true> fCoincidences;
2540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkTArray<SkCoincidence, true> fPartialCoincidences;
25558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkTArray<const SkOpContour*, true> fCrosses;
2567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkPathOpsBounds fBounds;
2577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool fContainsIntercepts;  // FIXME: is this used by anybody?
2587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool fContainsCubics;
2597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool fContainsCurves;
2607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool fDone;
2617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool fOperand;  // true for the second argument to a binary operator
2627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool fXor;
2637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    bool fOppXor;
2640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#ifdef SK_DEBUG
2657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    int fID;
2667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
2677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger};
2687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
2697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif
270