| Index: src/pathops/SkPathOpsTSect.h
|
| diff --git a/src/pathops/SkPathOpsTSect.h b/src/pathops/SkPathOpsTSect.h
|
| index bd26e5ace3b5b6af3448b31b076999641aea1e0e..70ee8ababd3c84d74100cee05ed5979a2ee954ad 100644
|
| --- a/src/pathops/SkPathOpsTSect.h
|
| +++ b/src/pathops/SkPathOpsTSect.h
|
| @@ -274,7 +274,7 @@ private:
|
| bool binarySearchCoin(SkTSect<OppCurve, TCurve>* , double tStart, double tStep, double* t,
|
| double* oppT);
|
| SkTSpan<TCurve, OppCurve>* boundsMax() const;
|
| - void coincidentCheck(SkTSect<OppCurve, TCurve>* sect2);
|
| + bool coincidentCheck(SkTSect<OppCurve, TCurve>* sect2);
|
| void coincidentForce(SkTSect<OppCurve, TCurve>* sect2, double start1s, double start1e);
|
| bool coincidentHasT(double t);
|
| int collapsed() const;
|
| @@ -287,14 +287,13 @@ private:
|
| return PATH_OPS_DEBUG_T_SECT_RELEASE(fID, -1);
|
| }
|
|
|
| - void deleteEmptySpans();
|
| + bool deleteEmptySpans();
|
| void dumpCommon(const SkTSpan<TCurve, OppCurve>* ) const;
|
| void dumpCommonCurves(const SkTSpan<TCurve, OppCurve>* ) const;
|
| static int EndsEqual(const SkTSect* sect1, const SkTSect<OppCurve, TCurve>* sect2,
|
| SkIntersections* );
|
| - SkTSpan<TCurve, OppCurve>* extractCoincident(SkTSect<OppCurve, TCurve>* sect2,
|
| - SkTSpan<TCurve, OppCurve>* first,
|
| - SkTSpan<TCurve, OppCurve>* last);
|
| + bool extractCoincident(SkTSect<OppCurve, TCurve>* sect2, SkTSpan<TCurve, OppCurve>* first,
|
| + SkTSpan<TCurve, OppCurve>* last, SkTSpan<TCurve, OppCurve>** result);
|
| SkTSpan<TCurve, OppCurve>* findCoincidentRun(SkTSpan<TCurve, OppCurve>* first,
|
| SkTSpan<TCurve, OppCurve>** lastPtr);
|
| int intersects(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp,
|
| @@ -302,7 +301,7 @@ private:
|
| bool isParallel(const SkDLine& thisLine, const SkTSect<OppCurve, TCurve>* opp) const;
|
| int linesIntersect(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp,
|
| SkTSpan<OppCurve, TCurve>* oppSpan, SkIntersections* );
|
| - void markSpanGone(SkTSpan<TCurve, OppCurve>* span);
|
| + bool markSpanGone(SkTSpan<TCurve, OppCurve>* span);
|
| bool matchedDirection(double t, const SkTSect<OppCurve, TCurve>* sect2, double t2) const;
|
| void matchedDirCheck(double t, const SkTSect<OppCurve, TCurve>* sect2, double t2,
|
| bool* calcMatched, bool* oppMatched) const;
|
| @@ -313,7 +312,7 @@ private:
|
| void removeCoincident(SkTSpan<TCurve, OppCurve>* span, bool isBetween);
|
| void removeAllBut(const SkTSpan<OppCurve, TCurve>* keep, SkTSpan<TCurve, OppCurve>* span,
|
| SkTSect<OppCurve, TCurve>* opp);
|
| - void removeSpan(SkTSpan<TCurve, OppCurve>* span);
|
| + bool removeSpan(SkTSpan<TCurve, OppCurve>* span);
|
| void removeSpanRange(SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurve>* last);
|
| void removeSpans(SkTSpan<TCurve, OppCurve>* span, SkTSect<OppCurve, TCurve>* opp);
|
| SkTSpan<TCurve, OppCurve>* spanAtT(double t, SkTSpan<TCurve, OppCurve>** priorSpan);
|
| @@ -981,7 +980,7 @@ SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::boundsMax() const {
|
| }
|
|
|
| template<typename TCurve, typename OppCurve>
|
| -void SkTSect<TCurve, OppCurve>::coincidentCheck(SkTSect<OppCurve, TCurve>* sect2) {
|
| +bool SkTSect<TCurve, OppCurve>::coincidentCheck(SkTSect<OppCurve, TCurve>* sect2) {
|
| SkTSpan<TCurve, OppCurve>* first = fHead;
|
| SkTSpan<TCurve, OppCurve>* last, * next;
|
| do {
|
| @@ -998,7 +997,10 @@ void SkTSect<TCurve, OppCurve>::coincidentCheck(SkTSect<OppCurve, TCurve>* sect2
|
| // check to see if a range of points are on the curve
|
| SkTSpan<TCurve, OppCurve>* coinStart = first;
|
| do {
|
| - coinStart = this->extractCoincident(sect2, coinStart, last);
|
| + bool success = this->extractCoincident(sect2, coinStart, last, &coinStart);
|
| + if (!success) {
|
| + return false;
|
| + }
|
| } while (coinStart && !last->fDeleted);
|
| if (!fHead || !sect2->fHead) {
|
| break;
|
| @@ -1007,6 +1009,7 @@ void SkTSect<TCurve, OppCurve>::coincidentCheck(SkTSect<OppCurve, TCurve>* sect2
|
| break;
|
| }
|
| } while ((first = next));
|
| + return true;
|
| }
|
|
|
| template<typename TCurve, typename OppCurve>
|
| @@ -1143,24 +1146,29 @@ bool SkTSect<TCurve, OppCurve>::debugHasBounded(const SkTSpan<OppCurve, TCurve>*
|
| }
|
|
|
| template<typename TCurve, typename OppCurve>
|
| -void SkTSect<TCurve, OppCurve>::deleteEmptySpans() {
|
| +bool SkTSect<TCurve, OppCurve>::deleteEmptySpans() {
|
| SkTSpan<TCurve, OppCurve>* test;
|
| SkTSpan<TCurve, OppCurve>* next = fHead;
|
| while ((test = next)) {
|
| next = test->fNext;
|
| if (!test->fBounded) {
|
| - this->removeSpan(test);
|
| + if (!this->removeSpan(test)) {
|
| + return false;
|
| + }
|
| }
|
| }
|
| + return true;
|
| }
|
|
|
| template<typename TCurve, typename OppCurve>
|
| -SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::extractCoincident(
|
| +bool SkTSect<TCurve, OppCurve>::extractCoincident(
|
| SkTSect<OppCurve, TCurve>* sect2,
|
| - SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurve>* last) {
|
| + SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurve>* last,
|
| + SkTSpan<TCurve, OppCurve>** result) {
|
| first = findCoincidentRun(first, &last);
|
| if (!first || !last) {
|
| - return nullptr;
|
| + *result = nullptr;
|
| + return true;
|
| }
|
| // march outwards to find limit of coincidence from here to previous and next spans
|
| double startT = first->fStartT;
|
| @@ -1218,10 +1226,12 @@ SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::extractCoincident(
|
| SkOPASSERT(oppStartT == oppFirst->fStartT);
|
| SkOPASSERT(oppEndT == oppLast->fEndT);
|
| if (!oppFirst) {
|
| - return nullptr;
|
| + *result = nullptr;
|
| + return true;
|
| }
|
| if (!oppLast) {
|
| - return nullptr;
|
| + *result = nullptr;
|
| + return true;
|
| }
|
| // reduce coincident runs to single entries
|
| this->validate();
|
| @@ -1250,12 +1260,15 @@ SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::extractCoincident(
|
| this->removeCoincident(first, false);
|
| sect2->removeCoincident(oppFirst, true);
|
| if (deleteEmptySpans) {
|
| - this->deleteEmptySpans();
|
| - sect2->deleteEmptySpans();
|
| + if (!this->deleteEmptySpans() || !sect2->deleteEmptySpans()) {
|
| + *result = nullptr;
|
| + return false;
|
| + }
|
| }
|
| this->validate();
|
| sect2->validate();
|
| - return last && !last->fDeleted && fHead && sect2->fHead ? last : nullptr;
|
| + *result = last && !last->fDeleted && fHead && sect2->fHead ? last : nullptr;
|
| + return true;
|
| }
|
|
|
| template<typename TCurve, typename OppCurve>
|
| @@ -1540,12 +1553,15 @@ int SkTSect<TCurve, OppCurve>::linesIntersect(SkTSpan<TCurve, OppCurve>* span,
|
|
|
|
|
| template<typename TCurve, typename OppCurve>
|
| -void SkTSect<TCurve, OppCurve>::markSpanGone(SkTSpan<TCurve, OppCurve>* span) {
|
| - --fActiveCount;
|
| +bool SkTSect<TCurve, OppCurve>::markSpanGone(SkTSpan<TCurve, OppCurve>* span) {
|
| + if (--fActiveCount < 0) {
|
| + return false;
|
| + }
|
| span->fNext = fDeleted;
|
| fDeleted = span;
|
| SkOPASSERT(!span->fDeleted);
|
| span->fDeleted = true;
|
| + return true;
|
| }
|
|
|
| template<typename TCurve, typename OppCurve>
|
| @@ -1710,9 +1726,9 @@ void SkTSect<TCurve, OppCurve>::removeCoincident(SkTSpan<TCurve, OppCurve>* span
|
| }
|
|
|
| template<typename TCurve, typename OppCurve>
|
| -void SkTSect<TCurve, OppCurve>::removeSpan(SkTSpan<TCurve, OppCurve>* span) {
|
| +bool SkTSect<TCurve, OppCurve>::removeSpan(SkTSpan<TCurve, OppCurve>* span) {
|
| this->unlinkSpan(span);
|
| - this->markSpanGone(span);
|
| + return this->markSpanGone(span);
|
| }
|
|
|
| template<typename TCurve, typename OppCurve>
|
| @@ -2148,7 +2164,9 @@ void SkTSect<TCurve, OppCurve>::BinarySearch(SkTSect<TCurve, OppCurve>* sect1,
|
| start1s = sect1->fHead->fStartT;
|
| start1e = sect1->tail()->fEndT;
|
| }
|
| - sect1->coincidentCheck(sect2);
|
| + if (!sect1->coincidentCheck(sect2)) {
|
| + return;
|
| + }
|
| sect1->validate();
|
| sect2->validate();
|
| #if DEBUG_T_SECT_LOOP_COUNT
|
|
|