X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fthird_party%2Fskia%2Fsrc%2Fpathops%2FSkOpSegment.cpp;h=747cd9d4973b0087e3e0730b2f9894ead6e96f6f;hb=4a1a0bdd01eef90b0826a0e761d3379d3715c10f;hp=4e8b5d28d9d80c14597ab8ddad9a2199ad21d145;hpb=b1be5ca53587d23e7aeb77b26861fdc0a181ffd8;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/third_party/skia/src/pathops/SkOpSegment.cpp b/src/third_party/skia/src/pathops/SkOpSegment.cpp index 4e8b5d2..747cd9d 100644 --- a/src/third_party/skia/src/pathops/SkOpSegment.cpp +++ b/src/third_party/skia/src/pathops/SkOpSegment.cpp @@ -405,12 +405,14 @@ void SkOpSegment::addCurveTo(int start, int end, SkPathWriter* path, bool active } void SkOpSegment::addEndSpan(int endIndex) { + SkASSERT(span(endIndex).fT == 1 || (span(endIndex).fTiny + && approximately_greater_than_one(span(endIndex).fT))); int spanCount = fTs.count(); int startIndex = endIndex - 1; while (fTs[startIndex].fT == 1 || fTs[startIndex].fTiny) { - ++startIndex; - SkASSERT(startIndex < spanCount - 1); - ++endIndex; + --startIndex; + SkASSERT(startIndex > 0); + --endIndex; } SkOpAngle& angle = fAngles.push_back(); angle.set(this, spanCount - 1, startIndex); @@ -815,7 +817,11 @@ int SkOpSegment::addSelfT(const SkPoint& pt, double newT) { // FIXME? assert that only one other span has a valid windValue or oppValue void SkOpSegment::addSimpleAngle(int index) { SkOpSpan* span = &fTs[index]; - if (index == 0) { + int idx; + int start, end; + if (span->fT == 0) { + idx = 0; + span = &fTs[0]; do { if (span->fToAngle) { SkASSERT(span->fToAngle->loopCount() == 2); @@ -823,13 +829,15 @@ void SkOpSegment::addSimpleAngle(int index) { span->fFromAngle = span->fToAngle->next(); return; } - span = &fTs[++index]; + span = &fTs[++idx]; } while (span->fT == 0); - SkASSERT(index == 1); - index = 0; - SkASSERT(!fTs[0].fTiny && fTs[1].fT > 0); - addStartSpan(1); + SkASSERT(!fTs[0].fTiny && fTs[idx].fT > 0); + addStartSpan(idx); + start = 0; + end = idx; } else { + idx = count() - 1; + span = &fTs[idx]; do { if (span->fFromAngle) { SkASSERT(span->fFromAngle->loopCount() == 2); @@ -837,29 +845,48 @@ void SkOpSegment::addSimpleAngle(int index) { span->fToAngle = span->fFromAngle->next(); return; } - span = &fTs[--index]; + span = &fTs[--idx]; } while (span->fT == 1); - SkASSERT(index == count() - 2); - index = count() - 1; - SkASSERT(!fTs[index - 1].fTiny && fTs[index - 1].fT < 1); - addEndSpan(index); + SkASSERT(!fTs[idx].fTiny && fTs[idx].fT < 1); + addEndSpan(++idx); + start = idx; + end = count(); } - span = &fTs[index]; - SkOpSegment* other = span->fOther; - SkOpSpan& oSpan = other->fTs[span->fOtherIndex]; + SkOpSegment* other; + SkOpSpan* oSpan; + index = start; + do { + span = &fTs[index]; + other = span->fOther; + int oFrom = span->fOtherIndex; + oSpan = &other->fTs[oFrom]; + if (oSpan->fT < 1 && oSpan->fWindValue) { + break; + } + if (oSpan->fT == 0) { + continue; + } + oFrom = other->nextExactSpan(oFrom, -1); + SkOpSpan* oFromSpan = &other->fTs[oFrom]; + SkASSERT(oFromSpan->fT < 1); + if (oFromSpan->fWindValue) { + break; + } + } while (++index < end); SkOpAngle* angle, * oAngle; - if (index == 0) { + if (span->fT == 0) { SkASSERT(span->fOtherIndex - 1 >= 0); SkASSERT(span->fOtherT == 1); - SkDEBUGCODE(SkOpSpan& oPrior = other->fTs[span->fOtherIndex - 1]); + SkDEBUGCODE(int oPriorIndex = other->nextExactSpan(span->fOtherIndex, -1)); + SkDEBUGCODE(const SkOpSpan& oPrior = other->span(oPriorIndex)); SkASSERT(!oPrior.fTiny && oPrior.fT < 1); other->addEndSpan(span->fOtherIndex); angle = span->fToAngle; - oAngle = oSpan.fFromAngle; + oAngle = oSpan->fFromAngle; } else { SkASSERT(span->fOtherIndex + 1 < other->count()); SkASSERT(span->fOtherT == 0); - SkASSERT(!oSpan.fTiny && (other->fTs[span->fOtherIndex + 1].fT > 0 + SkASSERT(!oSpan->fTiny && (other->fTs[span->fOtherIndex + 1].fT > 0 || (other->fTs[span->fOtherIndex + 1].fFromAngle == NULL && other->fTs[span->fOtherIndex + 1].fToAngle == NULL))); int oIndex = 1; @@ -873,7 +900,7 @@ void SkOpSegment::addSimpleAngle(int index) { } while (true); other->addStartSpan(oIndex); angle = span->fFromAngle; - oAngle = oSpan.fToAngle; + oAngle = oSpan->fToAngle; } angle->insert(oAngle); } @@ -1348,7 +1375,10 @@ void SkOpSegment::addTCoincident(const SkPoint& startPt, const SkPoint& endPt, d success = true; break; } - oPeek = &other->fTs[++oPeekIndex]; + if (++oPeekIndex == oCount) { + break; + } + oPeek = &other->fTs[oPeekIndex]; } while (endPt == oPeek->fPt); } if (success) { @@ -2264,9 +2294,10 @@ void SkOpSegment::checkSmall() { } const SkOpSpan& firstSpan = this->firstSpan(*thisSpan); const SkOpSpan& lastSpan = this->lastSpan(*thisSpan); + const SkOpSpan* nextSpan = &firstSpan + 1; ptrdiff_t smallCount = &lastSpan - &firstSpan + 1; SkASSERT(1 <= smallCount && smallCount < count()); - if (smallCount <= 1) { + if (smallCount <= 1 && !nextSpan->fSmall) { SkASSERT(1 == smallCount); checkSmallCoincidence(firstSpan, NULL); continue; @@ -3037,6 +3068,13 @@ int SkOpSegment::findOtherT(double t, const SkOpSegment* match) const { int SkOpSegment::findT(double t, const SkPoint& pt, const SkOpSegment* match) const { int count = this->count(); + // prefer exact matches over approximate matches + for (int index = 0; index < count; ++index) { + const SkOpSpan& span = fTs[index]; + if (span.fT == t && span.fOther == match) { + return index; + } + } for (int index = 0; index < count; ++index) { const SkOpSpan& span = fTs[index]; if (approximately_equal_orderable(span.fT, t) && span.fOther == match) { @@ -3402,7 +3440,7 @@ SkOpSpan* SkOpSegment::markAndChaseWinding(const SkOpAngle* angle, int winding) SkOpSegment* other = this; while ((other = other->nextChase(&index, &step, &min, &last))) { if (other->fTs[min].fWindSum != SK_MinS32) { - SkASSERT(other->fTs[min].fWindSum == winding); +// SkASSERT(other->fTs[min].fWindSum == winding); SkASSERT(!last); break; } @@ -3956,6 +3994,24 @@ void SkOpSegment::pinT(const SkPoint& pt, double* t) { } } +bool SkOpSegment::reversePoints(const SkPoint& p1, const SkPoint& p2) const { + SkASSERT(p1 != p2); + int spanCount = count(); + int p1IndexMin = -1; + int p2IndexMax = spanCount; + for (int index = 0; index < spanCount; ++index) { + const SkOpSpan& span = fTs[index]; + if (span.fPt == p1) { + if (p1IndexMin < 0) { + p1IndexMin = index; + } + } else if (span.fPt == p2) { + p2IndexMax = index; + } + } + return p1IndexMin > p2IndexMax; +} + void SkOpSegment::setCoincidentRange(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other) { int count = this->count();