SkOpContour.h revision dac1d17027dcaa5596885a9f333979418b35001c
107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com/* 207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com * Copyright 2013 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 SkOpContour_DEFINED 807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#define SkOpContour_DEFINED 907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 1007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include "SkOpSegment.h" 1107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#include "SkTArray.h" 1207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 130bcb8ca8a8fc04a4a9c69013ccc46645d2f2ae77commit-bot@chromium.org#if defined(SK_DEBUG) || !FORCE_RELEASE 140bcb8ca8a8fc04a4a9c69013ccc46645d2f2ae77commit-bot@chromium.org#include "SkThread.h" 150bcb8ca8a8fc04a4a9c69013ccc46645d2f2ae77commit-bot@chromium.org#endif 160bcb8ca8a8fc04a4a9c69013ccc46645d2f2ae77commit-bot@chromium.org 1707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass SkIntersections; 1807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass SkOpContour; 1907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass SkPathWriter; 2007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 2107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comstruct SkCoincidence { 22570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com SkOpContour* fOther; 2307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com int fSegments[2]; 2407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com double fTs[2][2]; 25dac1d17027dcaa5596885a9f333979418b35001ccaryclark SkPoint fPts[2][2]; 26dac1d17027dcaa5596885a9f333979418b35001ccaryclark int fNearly[2]; 2707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}; 2807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 2907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass SkOpContour { 3007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.compublic: 3107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com SkOpContour() { 3207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com reset(); 334431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#if defined(SK_DEBUG) || !FORCE_RELEASE 340bcb8ca8a8fc04a4a9c69013ccc46645d2f2ae77commit-bot@chromium.org fID = sk_atomic_inc(&SkPathOpsDebug::gContourID); 3507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif 3607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 3707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 3807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool operator<(const SkOpContour& rh) const { 3907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return fBounds.fTop == rh.fBounds.fTop 4007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com ? fBounds.fLeft < rh.fBounds.fLeft 4107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com : fBounds.fTop < rh.fBounds.fTop; 4207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 4307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 447eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com bool addCoincident(int index, SkOpContour* other, int otherIndex, 4507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const SkIntersections& ts, bool swap); 4607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void addCoincidentPoints(); 4707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 4807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void addCross(const SkOpContour* crosser) { 4907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#ifdef DEBUG_CROSS 5007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com for (int index = 0; index < fCrosses.count(); ++index) { 5107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com SkASSERT(fCrosses[index] != crosser); 5207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 5307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif 54d892bd8ba676d34d4ce4a73ac7aad88e102fad70caryclark@google.com fCrosses.push_back(crosser); 5507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 5607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 5707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void addCubic(const SkPoint pts[4]) { 5807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fSegments.push_back().addCubic(pts, fOperand, fXor); 5907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fContainsCurves = fContainsCubics = true; 6007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 6107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 6207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com int addLine(const SkPoint pts[2]) { 6307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fSegments.push_back().addLine(pts, fOperand, fXor); 6407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return fSegments.count(); 6507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 6607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 6707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void addOtherT(int segIndex, int tIndex, double otherT, int otherIndex) { 6807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fSegments[segIndex].addOtherT(tIndex, otherT, otherIndex); 6907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 7007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 717eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com bool addPartialCoincident(int index, SkOpContour* other, int otherIndex, 72570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com const SkIntersections& ts, int ptIndex, bool swap); 73570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com 7407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com int addQuad(const SkPoint pts[3]) { 7507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fSegments.push_back().addQuad(pts, fOperand, fXor); 7607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fContainsCurves = true; 7707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return fSegments.count(); 7807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 7907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 80866f4e34a943c115ac372c22123a1520aa5f9b06commit-bot@chromium.org int addT(int segIndex, SkOpContour* other, int otherIndex, const SkPoint& pt, double newT) { 8107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com setContainsIntercepts(); 82866f4e34a943c115ac372c22123a1520aa5f9b06commit-bot@chromium.org return fSegments[segIndex].addT(&other->fSegments[otherIndex], pt, newT); 8307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 8407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 854431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org int addSelfT(int segIndex, const SkPoint& pt, double newT) { 8607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com setContainsIntercepts(); 874431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org return fSegments[segIndex].addSelfT(pt, newT); 8807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 8907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 90dac1d17027dcaa5596885a9f333979418b35001ccaryclark void align(const SkOpSegment::AlignedSpan& aligned, bool swap, SkCoincidence* coincidence); 91dac1d17027dcaa5596885a9f333979418b35001ccaryclark void alignCoincidence(const SkOpSegment::AlignedSpan& aligned, 92dac1d17027dcaa5596885a9f333979418b35001ccaryclark SkTArray<SkCoincidence, true>* coincidences); 93dac1d17027dcaa5596885a9f333979418b35001ccaryclark 94dac1d17027dcaa5596885a9f333979418b35001ccaryclark void alignCoincidence(const SkOpSegment::AlignedSpan& aligned) { 95dac1d17027dcaa5596885a9f333979418b35001ccaryclark alignCoincidence(aligned, &fCoincidences); 96dac1d17027dcaa5596885a9f333979418b35001ccaryclark alignCoincidence(aligned, &fPartialCoincidences); 97dac1d17027dcaa5596885a9f333979418b35001ccaryclark } 98dac1d17027dcaa5596885a9f333979418b35001ccaryclark 99dac1d17027dcaa5596885a9f333979418b35001ccaryclark void alignMultiples(SkTDArray<SkOpSegment::AlignedSpan>* aligned) { 100dac1d17027dcaa5596885a9f333979418b35001ccaryclark int segmentCount = fSegments.count(); 101dac1d17027dcaa5596885a9f333979418b35001ccaryclark for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { 102dac1d17027dcaa5596885a9f333979418b35001ccaryclark SkOpSegment& segment = fSegments[sIndex]; 103dac1d17027dcaa5596885a9f333979418b35001ccaryclark if (segment.hasMultiples()) { 104dac1d17027dcaa5596885a9f333979418b35001ccaryclark segment.alignMultiples(aligned); 105dac1d17027dcaa5596885a9f333979418b35001ccaryclark } 106dac1d17027dcaa5596885a9f333979418b35001ccaryclark } 107dac1d17027dcaa5596885a9f333979418b35001ccaryclark } 108dac1d17027dcaa5596885a9f333979418b35001ccaryclark 109dac1d17027dcaa5596885a9f333979418b35001ccaryclark void alignTPt(int segmentIndex, const SkOpContour* other, int otherIndex, 110dac1d17027dcaa5596885a9f333979418b35001ccaryclark bool swap, int tIndex, SkIntersections* ts, SkPoint* point) const; 111dac1d17027dcaa5596885a9f333979418b35001ccaryclark 11207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const SkPathOpsBounds& bounds() const { 11307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return fBounds; 11407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 11507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 1164431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org bool calcAngles(); 11707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void calcCoincidentWinding(); 118570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com void calcPartialCoincidentWinding(); 11907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 1204431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org void checkDuplicates() { 1214431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org int segmentCount = fSegments.count(); 1224431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { 1234431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org SkOpSegment& segment = fSegments[sIndex]; 1244431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org if (segment.count() > 2) { 1254431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org segment.checkDuplicates(); 1264431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 1274431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 1284431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 1294431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 130fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com void checkEnds() { 131fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com if (!fContainsCurves) { 132fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com return; 133fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com } 134fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com int segmentCount = fSegments.count(); 135fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { 136fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com SkOpSegment* segment = &fSegments[sIndex]; 137fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com if (segment->verb() == SkPath::kLine_Verb) { 138fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com continue; 139fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com } 1407eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com if (segment->done()) { 1417eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com continue; // likely coincident, nothing to do 1427eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com } 143570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com segment->checkEnds(); 144570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com } 145570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com } 146570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com 1474431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org void checkMultiples() { 1484431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org int segmentCount = fSegments.count(); 1494431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { 1504431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org SkOpSegment& segment = fSegments[sIndex]; 1514431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org if (segment.count() > 2) { 1524431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org segment.checkMultiples(); 153dac1d17027dcaa5596885a9f333979418b35001ccaryclark fMultiples |= segment.hasMultiples(); 1544431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 1554431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 1564431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 1574431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 1584431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org void checkSmall() { 1594431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org int segmentCount = fSegments.count(); 1604431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { 1614431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org SkOpSegment& segment = fSegments[sIndex]; 162dac1d17027dcaa5596885a9f333979418b35001ccaryclark // OPTIMIZATION : skip segments that are done? 1634431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org if (segment.hasSmall()) { 1644431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org segment.checkSmall(); 1654431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 1664431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 1674431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 1684431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 169570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com // if same point has different T values, choose a common T 170570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com void checkTiny() { 171570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com int segmentCount = fSegments.count(); 172570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com if (segmentCount <= 2) { 173570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com return; 174570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com } 175570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { 1764431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org SkOpSegment& segment = fSegments[sIndex]; 1774431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org if (segment.hasTiny()) { 1784431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org segment.checkTiny(); 1794431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 180fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com } 181fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com } 182fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com 18307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void complete() { 18407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com setBounds(); 18507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fContainsIntercepts = false; 18607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 18707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 18807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool containsCubics() const { 18907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return fContainsCubics; 19007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 19107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 19207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool crosses(const SkOpContour* crosser) const { 19307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com for (int index = 0; index < fCrosses.count(); ++index) { 19407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com if (fCrosses[index] == crosser) { 19507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return true; 19607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 19707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 19807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return false; 19907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 20007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 20107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool done() const { 20207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return fDone; 20307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 20407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 20507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const SkPoint& end() const { 20607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const SkOpSegment& segment = fSegments.back(); 207277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com return segment.pts()[SkPathOpsVerbToPoints(segment.verb())]; 20807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 20907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 21007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void fixOtherTIndex() { 21107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com int segmentCount = fSegments.count(); 21207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com for (int sIndex = 0; sIndex < segmentCount; ++sIndex) { 21307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fSegments[sIndex].fixOtherTIndex(); 21407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 21507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 21607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 217dac1d17027dcaa5596885a9f333979418b35001ccaryclark bool hasMultiples() const { 218dac1d17027dcaa5596885a9f333979418b35001ccaryclark return fMultiples; 219dac1d17027dcaa5596885a9f333979418b35001ccaryclark } 220dac1d17027dcaa5596885a9f333979418b35001ccaryclark 221a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com void joinCoincidence() { 222a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com joinCoincidence(fCoincidences, false); 223a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com joinCoincidence(fPartialCoincidences, true); 224a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com } 225a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com 22607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com SkOpSegment* nonVerticalSegment(int* start, int* end); 2273284017a60ea4fc3dc5b95838ba0c301ee1e4e8dskia.committer@gmail.com 22807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool operand() const { 22907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return fOperand; 23007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 23107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 23207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void reset() { 23307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fSegments.reset(); 23407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, SK_ScalarMax); 235dac1d17027dcaa5596885a9f333979418b35001ccaryclark fContainsCurves = fContainsCubics = fContainsIntercepts = fDone = fMultiples = false; 23607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 23707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 238dac1d17027dcaa5596885a9f333979418b35001ccaryclark void resolveNearCoincidence(); 239dac1d17027dcaa5596885a9f333979418b35001ccaryclark 24007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com SkTArray<SkOpSegment>& segments() { 24107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return fSegments; 24207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 24307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 24407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void setContainsIntercepts() { 24507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fContainsIntercepts = true; 24607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 24707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 24807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void setOperand(bool isOp) { 24907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fOperand = isOp; 25007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 25107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 25207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void setOppXor(bool isOppXor) { 25307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fOppXor = isOppXor; 25407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com int segmentCount = fSegments.count(); 25507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com for (int test = 0; test < segmentCount; ++test) { 25607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fSegments[test].setOppXor(isOppXor); 25707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 25807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 25907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 26007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void setXor(bool isXor) { 26107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fXor = isXor; 26207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 26307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 2644431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org void sortAngles(); 26507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void sortSegments(); 2663284017a60ea4fc3dc5b95838ba0c301ee1e4e8dskia.committer@gmail.com 26707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com const SkPoint& start() const { 26807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return fSegments.front().pts()[0]; 26907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 2703284017a60ea4fc3dc5b95838ba0c301ee1e4e8dskia.committer@gmail.com 27107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void toPath(SkPathWriter* path) const; 2723284017a60ea4fc3dc5b95838ba0c301ee1e4e8dskia.committer@gmail.com 27307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void toPartialBackward(SkPathWriter* path) const { 27407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com int segmentCount = fSegments.count(); 27507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com for (int test = segmentCount - 1; test >= 0; --test) { 27607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fSegments[test].addCurveTo(1, 0, path, true); 27707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 27807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 27907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 28007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void toPartialForward(SkPathWriter* path) const { 28107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com int segmentCount = fSegments.count(); 28207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com for (int test = 0; test < segmentCount; ++test) { 28307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fSegments[test].addCurveTo(0, 1, path, true); 28407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 28507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 28607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 28707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void topSortableSegment(const SkPoint& topLeft, SkPoint* bestXY, SkOpSegment** topStart); 28807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com SkOpSegment* undoneSegment(int* start, int* end); 28907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 29007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com int updateSegment(int index, const SkPoint* pts) { 29107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com SkOpSegment& segment = fSegments[index]; 29207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com segment.updatePts(pts); 293277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com return SkPathOpsVerbToPoints(segment.verb()) + 1; 29407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 29507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 29607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#if DEBUG_TEST 29707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com SkTArray<SkOpSegment>& debugSegments() { 29807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return fSegments; 29907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 30007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif 30107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 302a5e55925ea03e76885804bda77408a1d6f04c335caryclark@google.com#if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY 30307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void debugShowActiveSpans() { 30407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com for (int index = 0; index < fSegments.count(); ++index) { 30507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fSegments[index].debugShowActiveSpans(); 30607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 30707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 30807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif 30907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 31007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#if DEBUG_SHOW_WINDING 31107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com int debugShowWindingValues(int totalSegments, int ofInterest); 312d892bd8ba676d34d4ce4a73ac7aad88e102fad70caryclark@google.com static void debugShowWindingValues(const SkTArray<SkOpContour*, true>& contourList); 31307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif 31407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 3154431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org // available to test routines only 3164431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org void dump() const; 3174431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org void dumpAngles() const; 318dac1d17027dcaa5596885a9f333979418b35001ccaryclark void dumpCoincidence(const SkCoincidence& ) const; 319dac1d17027dcaa5596885a9f333979418b35001ccaryclark void dumpCoincidences() const; 320dac1d17027dcaa5596885a9f333979418b35001ccaryclark void dumpPt(int ) const; 3214431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org void dumpPts() const; 322dac1d17027dcaa5596885a9f333979418b35001ccaryclark void dumpSpan(int ) const; 3234431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org void dumpSpans() const; 3244431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 32507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comprivate: 326dac1d17027dcaa5596885a9f333979418b35001ccaryclark void alignPt(int index, SkPoint* point, int zeroPt) const; 327dac1d17027dcaa5596885a9f333979418b35001ccaryclark int alignT(bool swap, int tIndex, SkIntersections* ts) const; 328a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com void calcCommonCoincidentWinding(const SkCoincidence& ); 329dac1d17027dcaa5596885a9f333979418b35001ccaryclark void checkCoincidentPair(const SkCoincidence& oneCoin, int oneIdx, 330dac1d17027dcaa5596885a9f333979418b35001ccaryclark const SkCoincidence& twoCoin, int twoIdx, bool partial); 331a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com void joinCoincidence(const SkTArray<SkCoincidence, true>& , bool partial); 33207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void setBounds(); 33307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 33407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com SkTArray<SkOpSegment> fSegments; 335d892bd8ba676d34d4ce4a73ac7aad88e102fad70caryclark@google.com SkTArray<SkOpSegment*, true> fSortedSegments; 33607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com int fFirstSorted; 337d892bd8ba676d34d4ce4a73ac7aad88e102fad70caryclark@google.com SkTArray<SkCoincidence, true> fCoincidences; 338570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com SkTArray<SkCoincidence, true> fPartialCoincidences; 339d892bd8ba676d34d4ce4a73ac7aad88e102fad70caryclark@google.com SkTArray<const SkOpContour*, true> fCrosses; 34007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com SkPathOpsBounds fBounds; 34107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool fContainsIntercepts; // FIXME: is this used by anybody? 34207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool fContainsCubics; 34307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool fContainsCurves; 34407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool fDone; 345dac1d17027dcaa5596885a9f333979418b35001ccaryclark bool fMultiples; // set if some segment has multiple identical intersections with other curves 34607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool fOperand; // true for the second argument to a binary operator 34707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool fXor; 34807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool fOppXor; 3494431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#if defined(SK_DEBUG) || !FORCE_RELEASE 3504431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org int debugID() const { return fID; } 35107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com int fID; 3524431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#else 3534431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org int debugID() const { return -1; } 35407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif 35507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}; 35607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 35707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif 358