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" 1154359294a7c9dc54802d512a5d891a35c1663392caryclark#include "SkTDArray.h" 1254359294a7c9dc54802d512a5d891a35c1663392caryclark#include "SkTSort.h" 1307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 1454359294a7c9dc54802d512a5d891a35c1663392caryclarkclass SkChunkAlloc; 15624637cc8ec22c000409704d0b403ac1b81ad4b0caryclarkenum class SkOpRayDir; 16624637cc8ec22c000409704d0b403ac1b81ad4b0caryclarkstruct SkOpRayHit; 1707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass SkPathWriter; 1807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 1907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comclass SkOpContour { 2007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.compublic: 2107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com SkOpContour() { 2207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com reset(); 2354359294a7c9dc54802d512a5d891a35c1663392caryclark } 2454359294a7c9dc54802d512a5d891a35c1663392caryclark 2554359294a7c9dc54802d512a5d891a35c1663392caryclark ~SkOpContour() { 2654359294a7c9dc54802d512a5d891a35c1663392caryclark if (fNext) { 2754359294a7c9dc54802d512a5d891a35c1663392caryclark fNext->~SkOpContour(); 2854359294a7c9dc54802d512a5d891a35c1663392caryclark } 2907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 3007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 3107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool operator<(const SkOpContour& rh) const { 3207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com return fBounds.fTop == rh.fBounds.fTop 3307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com ? fBounds.fLeft < rh.fBounds.fLeft 3407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com : fBounds.fTop < rh.fBounds.fTop; 3507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 3607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 3727c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark void addAlignIntersections(SkOpContourHead* contourList, SkChunkAlloc* allocator) { 3827c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark SkASSERT(fCount > 0); 3927c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark SkOpSegment* segment = &fHead; 4027c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark do { 4127c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark segment->addAlignIntersections(contourList, allocator); 4227c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark } while ((segment = segment->next())); 4327c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark } 4427c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark 451049f1246e7be4ccb68001361efceb8933e6f81ccaryclark void addConic(SkPoint pts[3], SkScalar weight, SkChunkAlloc* allocator) { 461049f1246e7be4ccb68001361efceb8933e6f81ccaryclark appendSegment(allocator).addConic(pts, weight, this); 471049f1246e7be4ccb68001361efceb8933e6f81ccaryclark } 481049f1246e7be4ccb68001361efceb8933e6f81ccaryclark 4954359294a7c9dc54802d512a5d891a35c1663392caryclark void addCubic(SkPoint pts[4], SkChunkAlloc* allocator) { 5054359294a7c9dc54802d512a5d891a35c1663392caryclark appendSegment(allocator).addCubic(pts, this); 5154359294a7c9dc54802d512a5d891a35c1663392caryclark } 5207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 5303b03cad01628146bbb8d4f33c073bd0c77ee558caryclark SkOpSegment* addCurve(SkPath::Verb verb, const SkPoint pts[4], SkChunkAlloc* allocator); 5454359294a7c9dc54802d512a5d891a35c1663392caryclark 5554359294a7c9dc54802d512a5d891a35c1663392caryclark void addLine(SkPoint pts[2], SkChunkAlloc* allocator) { 5654359294a7c9dc54802d512a5d891a35c1663392caryclark appendSegment(allocator).addLine(pts, this); 57ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 58570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com 5954359294a7c9dc54802d512a5d891a35c1663392caryclark void addQuad(SkPoint pts[3], SkChunkAlloc* allocator) { 6054359294a7c9dc54802d512a5d891a35c1663392caryclark appendSegment(allocator).addQuad(pts, this); 6107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 6207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 6354359294a7c9dc54802d512a5d891a35c1663392caryclark void align() { 6454359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(fCount > 0); 6554359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment* segment = &fHead; 6654359294a7c9dc54802d512a5d891a35c1663392caryclark do { 6754359294a7c9dc54802d512a5d891a35c1663392caryclark segment->align(); 6854359294a7c9dc54802d512a5d891a35c1663392caryclark } while ((segment = segment->next())); 6907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 7007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 7154359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment& appendSegment(SkChunkAlloc* allocator) { 7254359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment* result = fCount++ 7354359294a7c9dc54802d512a5d891a35c1663392caryclark ? SkOpTAllocator<SkOpSegment>::Allocate(allocator) : &fHead; 7454359294a7c9dc54802d512a5d891a35c1663392caryclark result->setPrev(fTail); 7554359294a7c9dc54802d512a5d891a35c1663392caryclark if (fTail) { 7654359294a7c9dc54802d512a5d891a35c1663392caryclark fTail->setNext(result); 7754359294a7c9dc54802d512a5d891a35c1663392caryclark } 7854359294a7c9dc54802d512a5d891a35c1663392caryclark fTail = result; 7954359294a7c9dc54802d512a5d891a35c1663392caryclark return *result; 8007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 8107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 8254359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpContour* appendContour(SkChunkAlloc* allocator) { 8354359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpContour* contour = SkOpTAllocator<SkOpContour>::New(allocator); 8496fcdcc219d2a0d3579719b84b28bede76efba64halcanary contour->setNext(nullptr); 8554359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpContour* prev = this; 8654359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpContour* next; 8754359294a7c9dc54802d512a5d891a35c1663392caryclark while ((next = prev->next())) { 8854359294a7c9dc54802d512a5d891a35c1663392caryclark prev = next; 8954359294a7c9dc54802d512a5d891a35c1663392caryclark } 9054359294a7c9dc54802d512a5d891a35c1663392caryclark prev->setNext(contour); 9154359294a7c9dc54802d512a5d891a35c1663392caryclark return contour; 9254359294a7c9dc54802d512a5d891a35c1663392caryclark } 9354359294a7c9dc54802d512a5d891a35c1663392caryclark 9454359294a7c9dc54802d512a5d891a35c1663392caryclark const SkPathOpsBounds& bounds() const { 9554359294a7c9dc54802d512a5d891a35c1663392caryclark return fBounds; 9654359294a7c9dc54802d512a5d891a35c1663392caryclark } 97dac1d17027dcaa5596885a9f333979418b35001ccaryclark 9854359294a7c9dc54802d512a5d891a35c1663392caryclark void calcAngles(SkChunkAlloc* allocator) { 9954359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(fCount > 0); 10054359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment* segment = &fHead; 10154359294a7c9dc54802d512a5d891a35c1663392caryclark do { 10254359294a7c9dc54802d512a5d891a35c1663392caryclark segment->calcAngles(allocator); 10354359294a7c9dc54802d512a5d891a35c1663392caryclark } while ((segment = segment->next())); 104dac1d17027dcaa5596885a9f333979418b35001ccaryclark } 105dac1d17027dcaa5596885a9f333979418b35001ccaryclark 10654359294a7c9dc54802d512a5d891a35c1663392caryclark void complete() { 10754359294a7c9dc54802d512a5d891a35c1663392caryclark setBounds(); 108dac1d17027dcaa5596885a9f333979418b35001ccaryclark } 109dac1d17027dcaa5596885a9f333979418b35001ccaryclark 11054359294a7c9dc54802d512a5d891a35c1663392caryclark int count() const { 11154359294a7c9dc54802d512a5d891a35c1663392caryclark return fCount; 112ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 113dac1d17027dcaa5596885a9f333979418b35001ccaryclark 11454359294a7c9dc54802d512a5d891a35c1663392caryclark int debugID() const { 1151049f1246e7be4ccb68001361efceb8933e6f81ccaryclark return SkDEBUGRELEASE(fID, -1); 11654359294a7c9dc54802d512a5d891a35c1663392caryclark } 11707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 11854359294a7c9dc54802d512a5d891a35c1663392caryclark int debugIndent() const { 119624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark return SkDEBUGRELEASE(fDebugIndent, 0); 120ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 12107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 12254359294a7c9dc54802d512a5d891a35c1663392caryclark#if DEBUG_ACTIVE_SPANS 12354359294a7c9dc54802d512a5d891a35c1663392caryclark void debugShowActiveSpans() { 12454359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment* segment = &fHead; 12554359294a7c9dc54802d512a5d891a35c1663392caryclark do { 12654359294a7c9dc54802d512a5d891a35c1663392caryclark segment->debugShowActiveSpans(); 12754359294a7c9dc54802d512a5d891a35c1663392caryclark } while ((segment = segment->next())); 1284431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 12954359294a7c9dc54802d512a5d891a35c1663392caryclark#endif 1304431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 13154359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpAngle* debugAngle(int id) const { 13296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return SkDEBUGRELEASE(this->globalState()->debugAngle(id), nullptr); 13354359294a7c9dc54802d512a5d891a35c1663392caryclark } 134570863f2e22b8ea7d7c504bd15e4f766af097df2caryclark@google.com 13526ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark void debugCheckHealth(const char* id, SkPathOpsDebug::GlitchLog* ) const; 13626ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark 13754359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpContour* debugContour(int id) { 13896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return SkDEBUGRELEASE(this->globalState()->debugContour(id), nullptr); 1394431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org } 1404431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 14126ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark void debugMissingCoincidence(const char* id, SkPathOpsDebug::GlitchLog* log, 14226ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark const SkOpCoincidence* coincidence) const; 14326ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark 14454359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpPtT* debugPtT(int id) const { 14596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return SkDEBUGRELEASE(this->globalState()->debugPtT(id), nullptr); 14654359294a7c9dc54802d512a5d891a35c1663392caryclark } 1474431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 14854359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpSegment* debugSegment(int id) const { 14996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return SkDEBUGRELEASE(this->globalState()->debugSegment(id), nullptr); 150fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com } 151fa2aeee27af27f2934ee52a9732148f66481fb03caryclark@google.com 15254359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpSpanBase* debugSpan(int id) const { 15396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return SkDEBUGRELEASE(this->globalState()->debugSpan(id), nullptr); 15407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 15507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 15654359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpGlobalState* globalState() const { 15754359294a7c9dc54802d512a5d891a35c1663392caryclark return fState; 15807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 15907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 16054359294a7c9dc54802d512a5d891a35c1663392caryclark void debugValidate() const { 16154359294a7c9dc54802d512a5d891a35c1663392caryclark#if DEBUG_VALIDATE 16254359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpSegment* segment = &fHead; 16396fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkOpSegment* prior = nullptr; 16454359294a7c9dc54802d512a5d891a35c1663392caryclark do { 16554359294a7c9dc54802d512a5d891a35c1663392caryclark segment->debugValidate(); 16654359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(segment->prev() == prior); 16754359294a7c9dc54802d512a5d891a35c1663392caryclark prior = segment; 16854359294a7c9dc54802d512a5d891a35c1663392caryclark } while ((segment = segment->next())); 16954359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(prior == fTail); 17054359294a7c9dc54802d512a5d891a35c1663392caryclark#endif 17107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 17207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 17354359294a7c9dc54802d512a5d891a35c1663392caryclark bool done() const { 17454359294a7c9dc54802d512a5d891a35c1663392caryclark return fDone; 17507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 17607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 177624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark void dump() const; 178624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark void dumpAll() const; 17954359294a7c9dc54802d512a5d891a35c1663392caryclark void dumpAngles() const; 180624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark void dumpContours() const; 181624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark void dumpContoursAll() const; 182624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark void dumpContoursAngles() const; 183624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark void dumpContoursPts() const; 184624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark void dumpContoursPt(int segmentID) const; 185624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark void dumpContoursSegment(int segmentID) const; 186624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark void dumpContoursSpan(int segmentID) const; 187624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark void dumpContoursSpans() const; 18854359294a7c9dc54802d512a5d891a35c1663392caryclark void dumpPt(int ) const; 18926ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark void dumpPts(const char* prefix = "seg") const; 19026ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark void dumpPtsX(const char* prefix) const; 19154359294a7c9dc54802d512a5d891a35c1663392caryclark void dumpSegment(int ) const; 19226ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark void dumpSegments(const char* prefix = "seg", SkPathOp op = (SkPathOp) -1) const; 19354359294a7c9dc54802d512a5d891a35c1663392caryclark void dumpSpan(int ) const; 19454359294a7c9dc54802d512a5d891a35c1663392caryclark void dumpSpans() const; 19554359294a7c9dc54802d512a5d891a35c1663392caryclark 19654359294a7c9dc54802d512a5d891a35c1663392caryclark const SkPoint& end() const { 19754359294a7c9dc54802d512a5d891a35c1663392caryclark return fTail->pts()[SkPathOpsVerbToPoints(fTail->verb())]; 19807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 19907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 200d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark bool findCollapsed() { 201d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark SkASSERT(fCount > 0); 202d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark SkOpSegment* segment = &fHead; 203d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark do { 204d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark segment->findCollapsed(); 205d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark } while ((segment = segment->next())); 206d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark return true; 207d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark } 208d4349723fac9c0fd4dcf8c275fb7c756bdfdff7bcaryclark 209624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark SkOpSpan* findSortableTop(SkOpContour* ); 210624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark 21154359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment* first() { 21254359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(fCount > 0); 21354359294a7c9dc54802d512a5d891a35c1663392caryclark return &fHead; 214ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 215ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 21654359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpSegment* first() const { 21754359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(fCount > 0); 21854359294a7c9dc54802d512a5d891a35c1663392caryclark return &fHead; 219ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 220ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 221624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark void indentDump() const { 222624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark SkDEBUGCODE(fDebugIndent += 2); 22307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 22407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 22554359294a7c9dc54802d512a5d891a35c1663392caryclark void init(SkOpGlobalState* globalState, bool operand, bool isXor) { 22654359294a7c9dc54802d512a5d891a35c1663392caryclark fState = globalState; 22754359294a7c9dc54802d512a5d891a35c1663392caryclark fOperand = operand; 22854359294a7c9dc54802d512a5d891a35c1663392caryclark fXor = isXor; 2291049f1246e7be4ccb68001361efceb8933e6f81ccaryclark SkDEBUGCODE(fID = globalState->nextContourID()); 230dac1d17027dcaa5596885a9f333979418b35001ccaryclark } 231dac1d17027dcaa5596885a9f333979418b35001ccaryclark 2325b5ddd73b4baf22752924bf20d097e96236c36f8caryclark int isCcw() const { 2335b5ddd73b4baf22752924bf20d097e96236c36f8caryclark return fCcw; 2345b5ddd73b4baf22752924bf20d097e96236c36f8caryclark } 2355b5ddd73b4baf22752924bf20d097e96236c36f8caryclark 23654359294a7c9dc54802d512a5d891a35c1663392caryclark bool isXor() const { 23754359294a7c9dc54802d512a5d891a35c1663392caryclark return fXor; 23854359294a7c9dc54802d512a5d891a35c1663392caryclark } 23954359294a7c9dc54802d512a5d891a35c1663392caryclark 2405b5ddd73b4baf22752924bf20d097e96236c36f8caryclark void markDone() { 2415b5ddd73b4baf22752924bf20d097e96236c36f8caryclark SkOpSegment* segment = &fHead; 2425b5ddd73b4baf22752924bf20d097e96236c36f8caryclark do { 2435b5ddd73b4baf22752924bf20d097e96236c36f8caryclark segment->markAllDone(); 2445b5ddd73b4baf22752924bf20d097e96236c36f8caryclark } while ((segment = segment->next())); 2455b5ddd73b4baf22752924bf20d097e96236c36f8caryclark } 2465b5ddd73b4baf22752924bf20d097e96236c36f8caryclark 24727c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark bool missingCoincidence(SkOpCoincidence* coincidences, SkChunkAlloc* allocator) { 24854359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(fCount > 0); 24954359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment* segment = &fHead; 25027c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark bool result = false; 25154359294a7c9dc54802d512a5d891a35c1663392caryclark do { 25254359294a7c9dc54802d512a5d891a35c1663392caryclark if (fState->angleCoincidence()) { 25326ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark#if DEBUG_ANGLE 25426ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark segment->debugCheckAngleCoin(); 25526ad22ab61539e3d3b6bc5e0da8dcebbd52a53decaryclark#endif 25627c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark } else if (segment->missingCoincidence(coincidences, allocator)) { 25727c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark result = true; 25827c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark // FIXME: trying again loops forever in issue3651_6 25927c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark // The continue below is speculative -- once there's an actual case that requires it, 26027c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark // add the plumbing necessary to look for another missing coincidence in the same segment 26127c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark // continue; // try again in case another missing coincidence is further along 26254359294a7c9dc54802d512a5d891a35c1663392caryclark } 26327c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark segment = segment->next(); 26427c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark } while (segment); 26527c8eb8ffd7e221693d840c2b9279d53fe6f03d4caryclark return result; 26654359294a7c9dc54802d512a5d891a35c1663392caryclark } 26754359294a7c9dc54802d512a5d891a35c1663392caryclark 26808bc8488fa2ea2d2a17efb1443f0ec6579d5a3c8caryclark bool moveMultiples() { 26954359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(fCount > 0); 27054359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment* segment = &fHead; 27154359294a7c9dc54802d512a5d891a35c1663392caryclark do { 272d78c088b6136590371fddd4cab67bfb4bf692fd3caryclark if (!segment->moveMultiples()) { 273d78c088b6136590371fddd4cab67bfb4bf692fd3caryclark return false; 274d78c088b6136590371fddd4cab67bfb4bf692fd3caryclark } 27554359294a7c9dc54802d512a5d891a35c1663392caryclark } while ((segment = segment->next())); 27654359294a7c9dc54802d512a5d891a35c1663392caryclark return true; 277a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com } 278a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com 27908bc8488fa2ea2d2a17efb1443f0ec6579d5a3c8caryclark void moveNearby() { 28008bc8488fa2ea2d2a17efb1443f0ec6579d5a3c8caryclark SkASSERT(fCount > 0); 28108bc8488fa2ea2d2a17efb1443f0ec6579d5a3c8caryclark SkOpSegment* segment = &fHead; 28208bc8488fa2ea2d2a17efb1443f0ec6579d5a3c8caryclark do { 28308bc8488fa2ea2d2a17efb1443f0ec6579d5a3c8caryclark segment->moveNearby(); 28408bc8488fa2ea2d2a17efb1443f0ec6579d5a3c8caryclark } while ((segment = segment->next())); 28508bc8488fa2ea2d2a17efb1443f0ec6579d5a3c8caryclark } 28608bc8488fa2ea2d2a17efb1443f0ec6579d5a3c8caryclark 28754359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpContour* next() { 28854359294a7c9dc54802d512a5d891a35c1663392caryclark return fNext; 28907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 29007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 29154359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpContour* next() const { 29254359294a7c9dc54802d512a5d891a35c1663392caryclark return fNext; 293ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 294ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark 2950dc4dd6dda9a7912f696b46d9c02155ec1d1ba5freed bool operand() const { 2960dc4dd6dda9a7912f696b46d9c02155ec1d1ba5freed return fOperand; 29707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 29807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 29954359294a7c9dc54802d512a5d891a35c1663392caryclark bool oppXor() const { 30054359294a7c9dc54802d512a5d891a35c1663392caryclark return fOppXor; 30154359294a7c9dc54802d512a5d891a35c1663392caryclark } 30254359294a7c9dc54802d512a5d891a35c1663392caryclark 303624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark void outdentDump() const { 304624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark SkDEBUGCODE(fDebugIndent -= 2); 30554359294a7c9dc54802d512a5d891a35c1663392caryclark } 30654359294a7c9dc54802d512a5d891a35c1663392caryclark 307624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark void rayCheck(const SkOpRayHit& base, SkOpRayDir dir, SkOpRayHit** hits, SkChunkAlloc* ); 308624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark 30954359294a7c9dc54802d512a5d891a35c1663392caryclark void remove(SkOpContour* contour) { 31054359294a7c9dc54802d512a5d891a35c1663392caryclark if (contour == this) { 31154359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(fCount == 0); 31254359294a7c9dc54802d512a5d891a35c1663392caryclark return; 31354359294a7c9dc54802d512a5d891a35c1663392caryclark } 31496fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(contour->fNext == nullptr); 31554359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpContour* prev = this; 31654359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpContour* next; 31754359294a7c9dc54802d512a5d891a35c1663392caryclark while ((next = prev->next()) != contour) { 31854359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(next); 31954359294a7c9dc54802d512a5d891a35c1663392caryclark prev = next; 32054359294a7c9dc54802d512a5d891a35c1663392caryclark } 32154359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(prev); 32296fcdcc219d2a0d3579719b84b28bede76efba64halcanary prev->setNext(nullptr); 323ccec0f958ffc71a9986d236bc2eb335cb2111119caryclark } 324dac1d17027dcaa5596885a9f333979418b35001ccaryclark 32554359294a7c9dc54802d512a5d891a35c1663392caryclark void reset() { 32696fcdcc219d2a0d3579719b84b28bede76efba64halcanary fTail = nullptr; 32796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fNext = nullptr; 32854359294a7c9dc54802d512a5d891a35c1663392caryclark fCount = 0; 32954359294a7c9dc54802d512a5d891a35c1663392caryclark fDone = false; 33054359294a7c9dc54802d512a5d891a35c1663392caryclark SkDEBUGCODE(fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMin, SK_ScalarMin)); 33154359294a7c9dc54802d512a5d891a35c1663392caryclark SkDEBUGCODE(fFirstSorted = -1); 332624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark SkDEBUGCODE(fDebugIndent = 0); 33354359294a7c9dc54802d512a5d891a35c1663392caryclark } 33454359294a7c9dc54802d512a5d891a35c1663392caryclark 3355b5ddd73b4baf22752924bf20d097e96236c36f8caryclark void resetReverse() { 3365b5ddd73b4baf22752924bf20d097e96236c36f8caryclark SkOpContour* next = this; 3375b5ddd73b4baf22752924bf20d097e96236c36f8caryclark do { 3385b5ddd73b4baf22752924bf20d097e96236c36f8caryclark next->fCcw = -1; 3395b5ddd73b4baf22752924bf20d097e96236c36f8caryclark next->fReverse = false; 3405b5ddd73b4baf22752924bf20d097e96236c36f8caryclark } while ((next = next->next())); 3415b5ddd73b4baf22752924bf20d097e96236c36f8caryclark } 3425b5ddd73b4baf22752924bf20d097e96236c36f8caryclark 3435b5ddd73b4baf22752924bf20d097e96236c36f8caryclark bool reversed() const { 3445b5ddd73b4baf22752924bf20d097e96236c36f8caryclark return fReverse; 3455b5ddd73b4baf22752924bf20d097e96236c36f8caryclark } 3465b5ddd73b4baf22752924bf20d097e96236c36f8caryclark 34754359294a7c9dc54802d512a5d891a35c1663392caryclark void setBounds() { 34854359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(fCount > 0); 34954359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpSegment* segment = &fHead; 35054359294a7c9dc54802d512a5d891a35c1663392caryclark fBounds = segment->bounds(); 35154359294a7c9dc54802d512a5d891a35c1663392caryclark while ((segment = segment->next())) { 35254359294a7c9dc54802d512a5d891a35c1663392caryclark fBounds.add(segment->bounds()); 35354359294a7c9dc54802d512a5d891a35c1663392caryclark } 35454359294a7c9dc54802d512a5d891a35c1663392caryclark } 3550dc4dd6dda9a7912f696b46d9c02155ec1d1ba5freed 3565b5ddd73b4baf22752924bf20d097e96236c36f8caryclark void setCcw(int ccw) { 3575b5ddd73b4baf22752924bf20d097e96236c36f8caryclark fCcw = ccw; 3585b5ddd73b4baf22752924bf20d097e96236c36f8caryclark } 3595b5ddd73b4baf22752924bf20d097e96236c36f8caryclark 36054359294a7c9dc54802d512a5d891a35c1663392caryclark void setGlobalState(SkOpGlobalState* state) { 36154359294a7c9dc54802d512a5d891a35c1663392caryclark fState = state; 36207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 36307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 36454359294a7c9dc54802d512a5d891a35c1663392caryclark void setNext(SkOpContour* contour) { 36554359294a7c9dc54802d512a5d891a35c1663392caryclark// SkASSERT(!fNext == !!contour); 36654359294a7c9dc54802d512a5d891a35c1663392caryclark fNext = contour; 36707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 36807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 36907393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void setOperand(bool isOp) { 37007393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fOperand = isOp; 37107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 37207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 37307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void setOppXor(bool isOppXor) { 37407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fOppXor = isOppXor; 37507393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 37607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 3775b5ddd73b4baf22752924bf20d097e96236c36f8caryclark void setReverse() { 3785b5ddd73b4baf22752924bf20d097e96236c36f8caryclark fReverse = true; 3795b5ddd73b4baf22752924bf20d097e96236c36f8caryclark } 3805b5ddd73b4baf22752924bf20d097e96236c36f8caryclark 38107393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com void setXor(bool isXor) { 38207393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com fXor = isXor; 38307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 38407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 38554359294a7c9dc54802d512a5d891a35c1663392caryclark SkPath::Verb simplifyCubic(SkPoint pts[4]); 38607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 38754359294a7c9dc54802d512a5d891a35c1663392caryclark void sortAngles() { 38854359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(fCount > 0); 38954359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment* segment = &fHead; 39054359294a7c9dc54802d512a5d891a35c1663392caryclark do { 39154359294a7c9dc54802d512a5d891a35c1663392caryclark segment->sortAngles(); 39254359294a7c9dc54802d512a5d891a35c1663392caryclark } while ((segment = segment->next())); 39307393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com } 39407393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 39554359294a7c9dc54802d512a5d891a35c1663392caryclark const SkPoint& start() const { 39654359294a7c9dc54802d512a5d891a35c1663392caryclark return fHead.pts()[0]; 3970dc4dd6dda9a7912f696b46d9c02155ec1d1ba5freed } 3980dc4dd6dda9a7912f696b46d9c02155ec1d1ba5freed 39954359294a7c9dc54802d512a5d891a35c1663392caryclark void toPartialBackward(SkPathWriter* path) const { 40054359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpSegment* segment = fTail; 40154359294a7c9dc54802d512a5d891a35c1663392caryclark do { 402ef784fb7f58c9c021172045a8e0b396c81fdc425caryclark SkAssertResult(segment->addCurveTo(segment->tail(), segment->head(), path)); 40354359294a7c9dc54802d512a5d891a35c1663392caryclark } while ((segment = segment->prev())); 4040dc4dd6dda9a7912f696b46d9c02155ec1d1ba5freed } 4050dc4dd6dda9a7912f696b46d9c02155ec1d1ba5freed 40654359294a7c9dc54802d512a5d891a35c1663392caryclark void toPartialForward(SkPathWriter* path) const { 40754359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpSegment* segment = &fHead; 40854359294a7c9dc54802d512a5d891a35c1663392caryclark do { 409ef784fb7f58c9c021172045a8e0b396c81fdc425caryclark SkAssertResult(segment->addCurveTo(segment->head(), segment->tail(), path)); 41054359294a7c9dc54802d512a5d891a35c1663392caryclark } while ((segment = segment->next())); 4110dc4dd6dda9a7912f696b46d9c02155ec1d1ba5freed } 4120dc4dd6dda9a7912f696b46d9c02155ec1d1ba5freed 4135b5ddd73b4baf22752924bf20d097e96236c36f8caryclark void toReversePath(SkPathWriter* path) const; 41454359294a7c9dc54802d512a5d891a35c1663392caryclark void toPath(SkPathWriter* path) const; 41554359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment* undoneSegment(SkOpSpanBase** startPtr, SkOpSpanBase** endPtr); 4164431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org 41707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.comprivate: 41854359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpGlobalState* fState; 41954359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment fHead; 42054359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment* fTail; 42154359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpContour* fNext; 4220dc4dd6dda9a7912f696b46d9c02155ec1d1ba5freed SkPathOpsBounds fBounds; 4235b5ddd73b4baf22752924bf20d097e96236c36f8caryclark int fCcw; 42454359294a7c9dc54802d512a5d891a35c1663392caryclark int fCount; 42554359294a7c9dc54802d512a5d891a35c1663392caryclark int fFirstSorted; 42654359294a7c9dc54802d512a5d891a35c1663392caryclark bool fDone; // set by find top segment 42707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com bool fOperand; // true for the second argument to a binary operator 4285b5ddd73b4baf22752924bf20d097e96236c36f8caryclark bool fReverse; // true if contour should be reverse written to path (used only by fix winding) 42954359294a7c9dc54802d512a5d891a35c1663392caryclark bool fXor; // set if original path had even-odd fill 43054359294a7c9dc54802d512a5d891a35c1663392caryclark bool fOppXor; // set if opposite path had even-odd fill 4311049f1246e7be4ccb68001361efceb8933e6f81ccaryclark SkDEBUGCODE(int fID); 432624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark SkDEBUGCODE(mutable int fDebugIndent); 433624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark}; 434624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark 435624637cc8ec22c000409704d0b403ac1b81ad4b0caryclarkclass SkOpContourHead : public SkOpContour { 43607393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com}; 43707393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com 43807393cab57ce74a4aae89a31fae9aaa9780fc19dcaryclark@google.com#endif 439