SkOpSpan.cpp revision bca19f77479adfd8ba2171753382bc8bf4c2b4ca
154359294a7c9dc54802d512a5d891a35c1663392caryclark/* 254359294a7c9dc54802d512a5d891a35c1663392caryclark * Copyright 2014 Google Inc. 354359294a7c9dc54802d512a5d891a35c1663392caryclark * 454359294a7c9dc54802d512a5d891a35c1663392caryclark * Use of this source code is governed by a BSD-style license that can be 554359294a7c9dc54802d512a5d891a35c1663392caryclark * found in the LICENSE file. 654359294a7c9dc54802d512a5d891a35c1663392caryclark */ 754359294a7c9dc54802d512a5d891a35c1663392caryclark#include "SkOpCoincidence.h" 854359294a7c9dc54802d512a5d891a35c1663392caryclark#include "SkOpContour.h" 954359294a7c9dc54802d512a5d891a35c1663392caryclark#include "SkOpSegment.h" 1054359294a7c9dc54802d512a5d891a35c1663392caryclark#include "SkPathWriter.h" 1154359294a7c9dc54802d512a5d891a35c1663392caryclark 1254359294a7c9dc54802d512a5d891a35c1663392caryclarkbool SkOpPtT::alias() const { 1354359294a7c9dc54802d512a5d891a35c1663392caryclark return this->span()->ptT() != this; 1454359294a7c9dc54802d512a5d891a35c1663392caryclark} 1554359294a7c9dc54802d512a5d891a35c1663392caryclark 1654359294a7c9dc54802d512a5d891a35c1663392caryclarkSkOpContour* SkOpPtT::contour() const { 1754359294a7c9dc54802d512a5d891a35c1663392caryclark return segment()->contour(); 1854359294a7c9dc54802d512a5d891a35c1663392caryclark} 1954359294a7c9dc54802d512a5d891a35c1663392caryclark 2054359294a7c9dc54802d512a5d891a35c1663392caryclarkSkOpGlobalState* SkOpPtT::globalState() const { 2154359294a7c9dc54802d512a5d891a35c1663392caryclark return contour()->globalState(); 2254359294a7c9dc54802d512a5d891a35c1663392caryclark} 2354359294a7c9dc54802d512a5d891a35c1663392caryclark 2454359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpPtT::init(SkOpSpanBase* span, double t, const SkPoint& pt, bool duplicate) { 2554359294a7c9dc54802d512a5d891a35c1663392caryclark fT = t; 2654359294a7c9dc54802d512a5d891a35c1663392caryclark fPt = pt; 2754359294a7c9dc54802d512a5d891a35c1663392caryclark fSpan = span; 2854359294a7c9dc54802d512a5d891a35c1663392caryclark fNext = this; 2954359294a7c9dc54802d512a5d891a35c1663392caryclark fDuplicatePt = duplicate; 3054359294a7c9dc54802d512a5d891a35c1663392caryclark fDeleted = false; 311049f1246e7be4ccb68001361efceb8933e6f81ccaryclark SkDEBUGCODE(fID = span->globalState()->nextPtTID()); 3254359294a7c9dc54802d512a5d891a35c1663392caryclark} 3354359294a7c9dc54802d512a5d891a35c1663392caryclark 3454359294a7c9dc54802d512a5d891a35c1663392caryclarkbool SkOpPtT::onEnd() const { 3554359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpSpanBase* span = this->span(); 3654359294a7c9dc54802d512a5d891a35c1663392caryclark if (span->ptT() != this) { 3754359294a7c9dc54802d512a5d891a35c1663392caryclark return false; 3854359294a7c9dc54802d512a5d891a35c1663392caryclark } 3954359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpSegment* segment = this->segment(); 4054359294a7c9dc54802d512a5d891a35c1663392caryclark return span == segment->head() || span == segment->tail(); 4154359294a7c9dc54802d512a5d891a35c1663392caryclark} 4254359294a7c9dc54802d512a5d891a35c1663392caryclark 4354359294a7c9dc54802d512a5d891a35c1663392caryclarkSkOpPtT* SkOpPtT::prev() { 4454359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* result = this; 4554359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* next = this; 4654359294a7c9dc54802d512a5d891a35c1663392caryclark while ((next = next->fNext) != this) { 4754359294a7c9dc54802d512a5d891a35c1663392caryclark result = next; 4854359294a7c9dc54802d512a5d891a35c1663392caryclark } 4954359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(result->fNext == this); 5054359294a7c9dc54802d512a5d891a35c1663392caryclark return result; 5154359294a7c9dc54802d512a5d891a35c1663392caryclark} 5254359294a7c9dc54802d512a5d891a35c1663392caryclark 5354359294a7c9dc54802d512a5d891a35c1663392caryclarkSkOpPtT* SkOpPtT::remove() { 5454359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* prev = this; 5554359294a7c9dc54802d512a5d891a35c1663392caryclark do { 5654359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* next = prev->fNext; 5754359294a7c9dc54802d512a5d891a35c1663392caryclark if (next == this) { 5854359294a7c9dc54802d512a5d891a35c1663392caryclark prev->removeNext(this); 5954359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(prev->fNext != prev); 6054359294a7c9dc54802d512a5d891a35c1663392caryclark fDeleted = true; 6154359294a7c9dc54802d512a5d891a35c1663392caryclark return prev; 6254359294a7c9dc54802d512a5d891a35c1663392caryclark } 6354359294a7c9dc54802d512a5d891a35c1663392caryclark prev = next; 6454359294a7c9dc54802d512a5d891a35c1663392caryclark } while (prev != this); 6554359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(0); 6654359294a7c9dc54802d512a5d891a35c1663392caryclark return NULL; 6754359294a7c9dc54802d512a5d891a35c1663392caryclark} 6854359294a7c9dc54802d512a5d891a35c1663392caryclark 6954359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpPtT::removeNext(SkOpPtT* kept) { 7054359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(this->fNext); 7154359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* next = this->fNext; 7254359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(this != next->fNext); 7354359294a7c9dc54802d512a5d891a35c1663392caryclark this->fNext = next->fNext; 7454359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSpanBase* span = next->span(); 7554359294a7c9dc54802d512a5d891a35c1663392caryclark next->setDeleted(); 7654359294a7c9dc54802d512a5d891a35c1663392caryclark if (span->ptT() == next) { 7754359294a7c9dc54802d512a5d891a35c1663392caryclark span->upCast()->detach(kept); 7854359294a7c9dc54802d512a5d891a35c1663392caryclark } 7954359294a7c9dc54802d512a5d891a35c1663392caryclark} 8054359294a7c9dc54802d512a5d891a35c1663392caryclark 8154359294a7c9dc54802d512a5d891a35c1663392caryclarkconst SkOpSegment* SkOpPtT::segment() const { 8254359294a7c9dc54802d512a5d891a35c1663392caryclark return span()->segment(); 8354359294a7c9dc54802d512a5d891a35c1663392caryclark} 8454359294a7c9dc54802d512a5d891a35c1663392caryclark 8554359294a7c9dc54802d512a5d891a35c1663392caryclarkSkOpSegment* SkOpPtT::segment() { 8654359294a7c9dc54802d512a5d891a35c1663392caryclark return span()->segment(); 8754359294a7c9dc54802d512a5d891a35c1663392caryclark} 8854359294a7c9dc54802d512a5d891a35c1663392caryclark 8954359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpSpanBase::align() { 9054359294a7c9dc54802d512a5d891a35c1663392caryclark if (this->fAligned) { 9154359294a7c9dc54802d512a5d891a35c1663392caryclark return; 9254359294a7c9dc54802d512a5d891a35c1663392caryclark } 9354359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(!zero_or_one(this->fPtT.fT)); 9454359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(this->fPtT.next()); 9554359294a7c9dc54802d512a5d891a35c1663392caryclark // if a linked pt/t pair has a t of zero or one, use it as the base for alignment 9654359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* ptT = &this->fPtT, * stopPtT = ptT; 9754359294a7c9dc54802d512a5d891a35c1663392caryclark while ((ptT = ptT->next()) != stopPtT) { 9854359294a7c9dc54802d512a5d891a35c1663392caryclark if (zero_or_one(ptT->fT)) { 9954359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment* segment = ptT->segment(); 10054359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(this->segment() != segment); 10154359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(segment->head()->ptT() == ptT || segment->tail()->ptT() == ptT); 10254359294a7c9dc54802d512a5d891a35c1663392caryclark if (ptT->fT) { 10354359294a7c9dc54802d512a5d891a35c1663392caryclark segment->tail()->alignEnd(1, segment->lastPt()); 10454359294a7c9dc54802d512a5d891a35c1663392caryclark } else { 10554359294a7c9dc54802d512a5d891a35c1663392caryclark segment->head()->alignEnd(0, segment->pts()[0]); 10654359294a7c9dc54802d512a5d891a35c1663392caryclark } 10754359294a7c9dc54802d512a5d891a35c1663392caryclark return; 10854359294a7c9dc54802d512a5d891a35c1663392caryclark } 10954359294a7c9dc54802d512a5d891a35c1663392caryclark } 11054359294a7c9dc54802d512a5d891a35c1663392caryclark alignInner(); 11154359294a7c9dc54802d512a5d891a35c1663392caryclark this->fAligned = true; 11254359294a7c9dc54802d512a5d891a35c1663392caryclark} 11354359294a7c9dc54802d512a5d891a35c1663392caryclark 11454359294a7c9dc54802d512a5d891a35c1663392caryclark 11554359294a7c9dc54802d512a5d891a35c1663392caryclark// FIXME: delete spans that collapse 11654359294a7c9dc54802d512a5d891a35c1663392caryclark// delete segments that collapse 11754359294a7c9dc54802d512a5d891a35c1663392caryclark// delete contours that collapse 11854359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpSpanBase::alignEnd(double t, const SkPoint& pt) { 11954359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(zero_or_one(t)); 12054359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment* segment = this->segment(); 12154359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(t ? segment->lastPt() == pt : segment->pts()[0] == pt); 12254359294a7c9dc54802d512a5d891a35c1663392caryclark alignInner(); 12354359294a7c9dc54802d512a5d891a35c1663392caryclark *segment->writablePt(!!t) = pt; 12454359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* ptT = &this->fPtT; 12554359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(t == ptT->fT); 12654359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(pt == ptT->fPt); 12754359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* test = ptT, * stopPtT = ptT; 12854359294a7c9dc54802d512a5d891a35c1663392caryclark while ((test = test->next()) != stopPtT) { 12954359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSegment* other = test->segment(); 13054359294a7c9dc54802d512a5d891a35c1663392caryclark if (other == this->segment()) { 13154359294a7c9dc54802d512a5d891a35c1663392caryclark continue; 13254359294a7c9dc54802d512a5d891a35c1663392caryclark } 13354359294a7c9dc54802d512a5d891a35c1663392caryclark if (!zero_or_one(test->fT)) { 13454359294a7c9dc54802d512a5d891a35c1663392caryclark continue; 13554359294a7c9dc54802d512a5d891a35c1663392caryclark } 13654359294a7c9dc54802d512a5d891a35c1663392caryclark *other->writablePt(!!test->fT) = pt; 13754359294a7c9dc54802d512a5d891a35c1663392caryclark } 13854359294a7c9dc54802d512a5d891a35c1663392caryclark this->fAligned = true; 13954359294a7c9dc54802d512a5d891a35c1663392caryclark} 14054359294a7c9dc54802d512a5d891a35c1663392caryclark 14154359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpSpanBase::alignInner() { 14254359294a7c9dc54802d512a5d891a35c1663392caryclark // force the spans to share points and t values 14354359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* ptT = &this->fPtT, * stopPtT = ptT; 14454359294a7c9dc54802d512a5d891a35c1663392caryclark const SkPoint& pt = ptT->fPt; 14554359294a7c9dc54802d512a5d891a35c1663392caryclark do { 14654359294a7c9dc54802d512a5d891a35c1663392caryclark ptT->fPt = pt; 14754359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpSpanBase* span = ptT->span(); 14854359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* test = ptT; 14954359294a7c9dc54802d512a5d891a35c1663392caryclark do { 15054359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* prev = test; 15154359294a7c9dc54802d512a5d891a35c1663392caryclark if ((test = test->next()) == stopPtT) { 15254359294a7c9dc54802d512a5d891a35c1663392caryclark break; 15354359294a7c9dc54802d512a5d891a35c1663392caryclark } 15454359294a7c9dc54802d512a5d891a35c1663392caryclark if (span == test->span() && !span->segment()->ptsDisjoint(*ptT, *test)) { 15554359294a7c9dc54802d512a5d891a35c1663392caryclark // omit aliases that alignment makes redundant 15654359294a7c9dc54802d512a5d891a35c1663392caryclark if ((!ptT->alias() || test->alias()) && (ptT->onEnd() || !test->onEnd())) { 15754359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(test->alias()); 15854359294a7c9dc54802d512a5d891a35c1663392caryclark prev->removeNext(ptT); 15954359294a7c9dc54802d512a5d891a35c1663392caryclark test = prev; 16054359294a7c9dc54802d512a5d891a35c1663392caryclark } else { 16154359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(ptT->alias()); 16254359294a7c9dc54802d512a5d891a35c1663392caryclark stopPtT = ptT = ptT->remove(); 16354359294a7c9dc54802d512a5d891a35c1663392caryclark break; 16454359294a7c9dc54802d512a5d891a35c1663392caryclark } 16554359294a7c9dc54802d512a5d891a35c1663392caryclark } 16654359294a7c9dc54802d512a5d891a35c1663392caryclark } while (true); 16754359294a7c9dc54802d512a5d891a35c1663392caryclark } while ((ptT = ptT->next()) != stopPtT); 16854359294a7c9dc54802d512a5d891a35c1663392caryclark} 16954359294a7c9dc54802d512a5d891a35c1663392caryclark 17054359294a7c9dc54802d512a5d891a35c1663392caryclarkbool SkOpSpanBase::contains(const SkOpSpanBase* span) const { 17154359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpPtT* start = &fPtT; 17254359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpPtT* check = &span->fPtT; 17354359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(start != check); 17454359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpPtT* walk = start; 17554359294a7c9dc54802d512a5d891a35c1663392caryclark while ((walk = walk->next()) != start) { 17654359294a7c9dc54802d512a5d891a35c1663392caryclark if (walk == check) { 17754359294a7c9dc54802d512a5d891a35c1663392caryclark return true; 17854359294a7c9dc54802d512a5d891a35c1663392caryclark } 17954359294a7c9dc54802d512a5d891a35c1663392caryclark } 18054359294a7c9dc54802d512a5d891a35c1663392caryclark return false; 18154359294a7c9dc54802d512a5d891a35c1663392caryclark} 18254359294a7c9dc54802d512a5d891a35c1663392caryclark 18354359294a7c9dc54802d512a5d891a35c1663392caryclarkSkOpPtT* SkOpSpanBase::contains(const SkOpSegment* segment) { 18454359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* start = &fPtT; 18554359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* walk = start; 18654359294a7c9dc54802d512a5d891a35c1663392caryclark while ((walk = walk->next()) != start) { 18754359294a7c9dc54802d512a5d891a35c1663392caryclark if (walk->segment() == segment) { 18854359294a7c9dc54802d512a5d891a35c1663392caryclark return walk; 18954359294a7c9dc54802d512a5d891a35c1663392caryclark } 19054359294a7c9dc54802d512a5d891a35c1663392caryclark } 19154359294a7c9dc54802d512a5d891a35c1663392caryclark return NULL; 19254359294a7c9dc54802d512a5d891a35c1663392caryclark} 19354359294a7c9dc54802d512a5d891a35c1663392caryclark 19454359294a7c9dc54802d512a5d891a35c1663392caryclarkbool SkOpSpanBase::containsCoinEnd(const SkOpSegment* segment) const { 19554359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(this->segment() != segment); 19654359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpSpanBase* next = this; 19754359294a7c9dc54802d512a5d891a35c1663392caryclark while ((next = next->fCoinEnd) != this) { 19854359294a7c9dc54802d512a5d891a35c1663392caryclark if (next->segment() == segment) { 19954359294a7c9dc54802d512a5d891a35c1663392caryclark return true; 20054359294a7c9dc54802d512a5d891a35c1663392caryclark } 20154359294a7c9dc54802d512a5d891a35c1663392caryclark } 20254359294a7c9dc54802d512a5d891a35c1663392caryclark return false; 20354359294a7c9dc54802d512a5d891a35c1663392caryclark} 20454359294a7c9dc54802d512a5d891a35c1663392caryclark 20554359294a7c9dc54802d512a5d891a35c1663392caryclarkSkOpContour* SkOpSpanBase::contour() const { 20654359294a7c9dc54802d512a5d891a35c1663392caryclark return segment()->contour(); 20754359294a7c9dc54802d512a5d891a35c1663392caryclark} 20854359294a7c9dc54802d512a5d891a35c1663392caryclark 20954359294a7c9dc54802d512a5d891a35c1663392caryclarkSkOpGlobalState* SkOpSpanBase::globalState() const { 21054359294a7c9dc54802d512a5d891a35c1663392caryclark return contour()->globalState(); 21154359294a7c9dc54802d512a5d891a35c1663392caryclark} 21254359294a7c9dc54802d512a5d891a35c1663392caryclark 21354359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpSpanBase::initBase(SkOpSegment* segment, SkOpSpan* prev, double t, const SkPoint& pt) { 21454359294a7c9dc54802d512a5d891a35c1663392caryclark fSegment = segment; 21554359294a7c9dc54802d512a5d891a35c1663392caryclark fPtT.init(this, t, pt, false); 21654359294a7c9dc54802d512a5d891a35c1663392caryclark fCoinEnd = this; 21754359294a7c9dc54802d512a5d891a35c1663392caryclark fFromAngle = NULL; 21854359294a7c9dc54802d512a5d891a35c1663392caryclark fPrev = prev; 21908bc8488fa2ea2d2a17efb1443f0ec6579d5a3c8caryclark fSpanAdds = 0; 22054359294a7c9dc54802d512a5d891a35c1663392caryclark fAligned = true; 22154359294a7c9dc54802d512a5d891a35c1663392caryclark fChased = false; 2221049f1246e7be4ccb68001361efceb8933e6f81ccaryclark SkDEBUGCODE(fCount = 1); 2231049f1246e7be4ccb68001361efceb8933e6f81ccaryclark SkDEBUGCODE(fID = globalState()->nextSpanID()); 22454359294a7c9dc54802d512a5d891a35c1663392caryclark} 22554359294a7c9dc54802d512a5d891a35c1663392caryclark 22654359294a7c9dc54802d512a5d891a35c1663392caryclark// this pair of spans share a common t value or point; merge them and eliminate duplicates 22754359294a7c9dc54802d512a5d891a35c1663392caryclark// this does not compute the best t or pt value; this merely moves all data into a single list 22854359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpSpanBase::merge(SkOpSpan* span) { 22954359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* spanPtT = span->ptT(); 23054359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(this->t() != spanPtT->fT); 23154359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(!zero_or_one(spanPtT->fT)); 23254359294a7c9dc54802d512a5d891a35c1663392caryclark span->detach(this->ptT()); 23354359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* remainder = spanPtT->next(); 23454359294a7c9dc54802d512a5d891a35c1663392caryclark ptT()->insert(spanPtT); 23554359294a7c9dc54802d512a5d891a35c1663392caryclark while (remainder != spanPtT) { 23654359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* next = remainder->next(); 23754359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* compare = spanPtT->next(); 23854359294a7c9dc54802d512a5d891a35c1663392caryclark while (compare != spanPtT) { 23954359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpPtT* nextC = compare->next(); 24054359294a7c9dc54802d512a5d891a35c1663392caryclark if (nextC->span() == remainder->span() && nextC->fT == remainder->fT) { 24154359294a7c9dc54802d512a5d891a35c1663392caryclark goto tryNextRemainder; 24254359294a7c9dc54802d512a5d891a35c1663392caryclark } 24354359294a7c9dc54802d512a5d891a35c1663392caryclark compare = nextC; 24454359294a7c9dc54802d512a5d891a35c1663392caryclark } 24554359294a7c9dc54802d512a5d891a35c1663392caryclark spanPtT->insert(remainder); 24654359294a7c9dc54802d512a5d891a35c1663392caryclarktryNextRemainder: 24754359294a7c9dc54802d512a5d891a35c1663392caryclark remainder = next; 24854359294a7c9dc54802d512a5d891a35c1663392caryclark } 24908bc8488fa2ea2d2a17efb1443f0ec6579d5a3c8caryclark fSpanAdds += span->fSpanAdds; 25054359294a7c9dc54802d512a5d891a35c1663392caryclark} 25154359294a7c9dc54802d512a5d891a35c1663392caryclark 252bca19f77479adfd8ba2171753382bc8bf4c2b4cacaryclarkint SkOpSpan::computeWindSum() { 253bca19f77479adfd8ba2171753382bc8bf4c2b4cacaryclark SkOpGlobalState* globals = this->globalState(); 254bca19f77479adfd8ba2171753382bc8bf4c2b4cacaryclark SkOpContour* contourHead = globals->contourHead(); 255bca19f77479adfd8ba2171753382bc8bf4c2b4cacaryclark int windTry = 0; 256bca19f77479adfd8ba2171753382bc8bf4c2b4cacaryclark while (!this->sortableTop(contourHead) && ++windTry < SkOpGlobalState::kMaxWindingTries) { 257bca19f77479adfd8ba2171753382bc8bf4c2b4cacaryclark ; 258bca19f77479adfd8ba2171753382bc8bf4c2b4cacaryclark } 259bca19f77479adfd8ba2171753382bc8bf4c2b4cacaryclark return this->windSum(); 260bca19f77479adfd8ba2171753382bc8bf4c2b4cacaryclark} 261bca19f77479adfd8ba2171753382bc8bf4c2b4cacaryclark 26254359294a7c9dc54802d512a5d891a35c1663392caryclarkbool SkOpSpan::containsCoincidence(const SkOpSegment* segment) const { 26354359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(this->segment() != segment); 26454359294a7c9dc54802d512a5d891a35c1663392caryclark const SkOpSpan* next = fCoincident; 26554359294a7c9dc54802d512a5d891a35c1663392caryclark do { 26654359294a7c9dc54802d512a5d891a35c1663392caryclark if (next->segment() == segment) { 26754359294a7c9dc54802d512a5d891a35c1663392caryclark return true; 26854359294a7c9dc54802d512a5d891a35c1663392caryclark } 26954359294a7c9dc54802d512a5d891a35c1663392caryclark } while ((next = next->fCoincident) != this); 27054359294a7c9dc54802d512a5d891a35c1663392caryclark return false; 27154359294a7c9dc54802d512a5d891a35c1663392caryclark} 27254359294a7c9dc54802d512a5d891a35c1663392caryclark 27354359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpSpan::detach(SkOpPtT* kept) { 27454359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(!final()); 27554359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSpan* prev = this->prev(); 27654359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(prev); 27754359294a7c9dc54802d512a5d891a35c1663392caryclark SkOpSpanBase* next = this->next(); 27854359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(next); 27954359294a7c9dc54802d512a5d891a35c1663392caryclark prev->setNext(next); 28054359294a7c9dc54802d512a5d891a35c1663392caryclark next->setPrev(prev); 28154359294a7c9dc54802d512a5d891a35c1663392caryclark this->segment()->detach(this); 28254359294a7c9dc54802d512a5d891a35c1663392caryclark this->globalState()->coincidence()->fixUp(this->ptT(), kept); 28354359294a7c9dc54802d512a5d891a35c1663392caryclark this->ptT()->setDeleted(); 28454359294a7c9dc54802d512a5d891a35c1663392caryclark} 28554359294a7c9dc54802d512a5d891a35c1663392caryclark 28654359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpSpan::init(SkOpSegment* segment, SkOpSpan* prev, double t, const SkPoint& pt) { 28754359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(t != 1); 28854359294a7c9dc54802d512a5d891a35c1663392caryclark initBase(segment, prev, t, pt); 28954359294a7c9dc54802d512a5d891a35c1663392caryclark fCoincident = this; 29054359294a7c9dc54802d512a5d891a35c1663392caryclark fToAngle = NULL; 29154359294a7c9dc54802d512a5d891a35c1663392caryclark fWindSum = fOppSum = SK_MinS32; 29254359294a7c9dc54802d512a5d891a35c1663392caryclark fWindValue = 1; 29354359294a7c9dc54802d512a5d891a35c1663392caryclark fOppValue = 0; 294624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark fTopTTry = 0; 29554359294a7c9dc54802d512a5d891a35c1663392caryclark fChased = fDone = false; 29654359294a7c9dc54802d512a5d891a35c1663392caryclark segment->bumpCount(); 29754359294a7c9dc54802d512a5d891a35c1663392caryclark} 29854359294a7c9dc54802d512a5d891a35c1663392caryclark 29954359294a7c9dc54802d512a5d891a35c1663392caryclarkvoid SkOpSpan::setOppSum(int oppSum) { 30054359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(!final()); 30154359294a7c9dc54802d512a5d891a35c1663392caryclark if (fOppSum != SK_MinS32 && fOppSum != oppSum) { 30254359294a7c9dc54802d512a5d891a35c1663392caryclark this->globalState()->setWindingFailed(); 30354359294a7c9dc54802d512a5d891a35c1663392caryclark return; 30454359294a7c9dc54802d512a5d891a35c1663392caryclark } 30554359294a7c9dc54802d512a5d891a35c1663392caryclark SkASSERT(!DEBUG_LIMIT_WIND_SUM || abs(oppSum) <= DEBUG_LIMIT_WIND_SUM); 30654359294a7c9dc54802d512a5d891a35c1663392caryclark fOppSum = oppSum; 30754359294a7c9dc54802d512a5d891a35c1663392caryclark} 308624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark 309624637cc8ec22c000409704d0b403ac1b81ad4b0caryclarkvoid SkOpSpan::setWindSum(int windSum) { 310624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark SkASSERT(!final()); 311624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark if (fWindSum != SK_MinS32 && fWindSum != windSum) { 312624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark this->globalState()->setWindingFailed(); 313624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark return; 314624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark } 315624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark SkASSERT(!DEBUG_LIMIT_WIND_SUM || abs(windSum) <= DEBUG_LIMIT_WIND_SUM); 316624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark fWindSum = windSum; 317624637cc8ec22c000409704d0b403ac1b81ad4b0caryclark} 318