From: Cary Clark Date: Mon, 23 Jan 2017 14:38:52 +0000 (+0000) Subject: Revert "offset angle check edge in common" X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~55^2~706 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=59d5a0e3f560da40e0ae7036a01d7d58ce3718d8;p=platform%2Fupstream%2FlibSkiaSharp.git Revert "offset angle check edge in common" This reverts commit d2eb581ebc8f8009e80cccccd74d5b341ef5bd5b. Reason for revert: broke Google3 MSAN run of dm Original change's description: > offset angle check edge in common > > When curves cross, their intersection points may be nearby, but not exactly the same. > Sort the angles formed by the crossing curves when all angles don't have the same > origin. > > This sets up the framework to solve test case that currently fail (e.g., joel6) but > does not fix all related test cases (e.g., joel9). > > All older existing test cases, including extended tests, pass. > > Rework the test framework to better report when tests expected to produce failing > results now pass. > > Add new point and vector operations to support offset angles. > > TBR=reed@google.com > BUG=skia:6041 > > Change-Id: I67c651ded0a25e99ad93d55d6a35109b3ee3698e > Reviewed-on: https://skia-review.googlesource.com/6624 > Commit-Queue: Cary Clark > Reviewed-by: Cary Clark > TBR=caryclark@google.com,reviews@skia.org # Not skipping CQ checks because original CL landed > 1 day ago. BUG=skia:6041 Change-Id: I43db0808522ac44aceeb4f70e296167ea84a3663 Reviewed-on: https://skia-review.googlesource.com/7373 Commit-Queue: Cary Clark Reviewed-by: Cary Clark --- diff --git a/src/pathops/SkOpAngle.cpp b/src/pathops/SkOpAngle.cpp index f41ef23..c07e8cc 100644 --- a/src/pathops/SkOpAngle.cpp +++ b/src/pathops/SkOpAngle.cpp @@ -62,15 +62,23 @@ bool SkOpAngle::after(SkOpAngle* test) { SkOpAngle* lh = test; SkOpAngle* rh = lh->fNext; SkASSERT(lh != rh); + fPart.fCurve = fOriginalCurvePart; + lh->fPart.fCurve = lh->fOriginalCurvePart; + lh->fPart.fCurve.offset(lh->segment()->verb(), fPart.fCurve[0] - lh->fPart.fCurve[0]); + rh->fPart.fCurve = rh->fOriginalCurvePart; + rh->fPart.fCurve.offset(rh->segment()->verb(), fPart.fCurve[0] - rh->fPart.fCurve[0]); + #if DEBUG_ANGLE SkString bugOut; - this->debugAfter(lh, rh, &bugOut); + bugOut.printf("%s [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g" + " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g" + " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g ", __FUNCTION__, + lh->segment()->debugID(), lh->debugID(), lh->fSectorStart, lh->fSectorEnd, + lh->fStart->t(), lh->fEnd->t(), + segment()->debugID(), debugID(), fSectorStart, fSectorEnd, fStart->t(), fEnd->t(), + rh->segment()->debugID(), rh->debugID(), rh->fSectorStart, rh->fSectorEnd, + rh->fStart->t(), rh->fEnd->t()); SkString bugPart[3] = { lh->debugPart(), this->debugPart(), rh->debugPart() }; -#if 0 // convenient place to set a breakpoint to trace through a specific angle compare - if (lh->debugID() == 4 && this->debugID() == 16 && rh->debugID() == 5) { - SkDebugf(""); - } -#endif #endif if (lh->fComputeSector && !lh->computeSector()) { return COMPARE_RESULT(1, true); @@ -82,106 +90,23 @@ bool SkOpAngle::after(SkOpAngle* test) { return COMPARE_RESULT(3, true); } #if DEBUG_ANGLE // reset bugOut with computed sectors - this->debugAfter(lh, rh, &bugOut); + bugOut.printf("%s [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g" + " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g" + " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g ", __FUNCTION__, + lh->segment()->debugID(), lh->debugID(), lh->fSectorStart, lh->fSectorEnd, + lh->fStart->t(), lh->fEnd->t(), + segment()->debugID(), debugID(), fSectorStart, fSectorEnd, fStart->t(), fEnd->t(), + rh->segment()->debugID(), rh->debugID(), rh->fSectorStart, rh->fSectorEnd, + rh->fStart->t(), rh->fEnd->t()); #endif - /* If the curve pairs share a point, the computed sector is valid. Otherwise, the sectors must - be sufficiently different that translating them won't change the sort order. For instance, - curves with different origins may mis-sort if the computed sectors are 1 and 5. - - Curves with different origins have more information though -- there are more ways for their - convex hulls not to overlap. Try to resolve different origins directly before translating - one curve to share the opposite's origin. - */ - bool lrOverlap, ltrOverlap; - SkDVector lhOffset = fOriginalCurvePart[0] - lh->fOriginalCurvePart[0]; - bool lhHasOffset = lhOffset.fX || lhOffset.fY; - SkDVector rhOffset = fOriginalCurvePart[0] - rh->fOriginalCurvePart[0]; - bool rhHasOffset = rhOffset.fX || rhOffset.fY; - int lhStart, lhEnd, thStart, thEnd, rhStart, rhEnd; - bool lhX0, thX0, rhX0; - if (lhHasOffset | rhHasOffset) { - lhX0 = lh->sectorRange(&lhStart, &lhEnd, lhHasOffset); - thX0 = this->sectorRange(&thStart, &thEnd, false); - rhX0 = rh->sectorRange(&rhStart, &rhEnd, rhHasOffset); - lrOverlap = lhX0 + rhX0 + (lhStart <= rhEnd) + (rhStart <= lhEnd) >= 2; - ltrOverlap = thX0 + lhX0 + (lhStart <= thEnd) + (thStart <= lhEnd) >= 2 - || rhX0 + thX0 + (thStart <= rhEnd) + (rhStart <= thEnd) >= 2; - } else { - lrOverlap = lh->fSectorMask & rh->fSectorMask; - ltrOverlap = (lh->fSectorMask | rh->fSectorMask) & fSectorMask; - } - if (!lrOverlap & !ltrOverlap) { // no lh/this/rh sector overlap - return COMPARE_RESULT(4, (lh->fSectorEnd > rh->fSectorStart) - ^ (fSectorStart > lh->fSectorEnd) ^ (fSectorStart > rh->fSectorStart)); - } + bool ltrOverlap = (lh->fSectorMask | rh->fSectorMask) & fSectorMask; + bool lrOverlap = lh->fSectorMask & rh->fSectorMask; int lrOrder; // set to -1 if either order works - fPart.fCurve = fOriginalCurvePart; - lh->fPart.fCurve = lh->fOriginalCurvePart; - rh->fPart.fCurve = rh->fOriginalCurvePart; - if (lhHasOffset | rhHasOffset) { - bool lhSweepsCCW = lh->sweepsCCW(); - bool thSweepsCCW = this->sweepsCCW(); - bool rhSweepsCCW = rh->sweepsCCW(); - Turn thStartFromLhEnd = this->ccwOf(lh, lhSweepsCCW, !thSweepsCCW); - Turn thEndFromRhStart = this->ccwOf(rh, !rhSweepsCCW, thSweepsCCW); - if (!lrOverlap && Turn::kCcw == thStartFromLhEnd && Turn::kCw == thEndFromRhStart) { - if (!this->sweepContains(lh) && !this->sweepContains(rh)) { - return COMPARE_RESULT(5, true); - } - } - Turn lhStartFromRhStart = lh->ccwOf(rh, !rhSweepsCCW, !lhSweepsCCW); - Turn lhEndFromRhStart = lh->fPart.isCurve() - ? lh->ccwOf(rh, !rhSweepsCCW, lhSweepsCCW) : lhStartFromRhStart; - bool lhOrRhIsCurve = lh->fPart.isCurve() || rh->fPart.isCurve(); - Turn lhStartFromRhEnd; - if (lhOrRhIsCurve) { - if (rh->fPart.isCurve()) { - lhStartFromRhEnd = lh->ccwOf(rh, rhSweepsCCW, !lhSweepsCCW); - } else { - lhStartFromRhEnd = lhStartFromRhStart; - } - // cancel overlap only if sweep doesn't contain other curve's sweep pts - if (!lh->sweepContains(rh)) { - // clear overlap if both turn in the same direction - lrOverlap &= (int) lhStartFromRhEnd * (int) lhEndFromRhStart < 0; - } - } else { - lrOverlap = false; - } - Turn thStartFromRhEnd SkDEBUGCODE(= Turn::kDebugUninitialized); - Turn thEndFromLhStart SkDEBUGCODE(= Turn::kDebugUninitialized); - if (lhOrRhIsCurve || fPart.isCurve()) { - thStartFromRhEnd = rh->fPart.isCurve() || fPart.isCurve() - ? this->ccwOf(rh, rhSweepsCCW, !thSweepsCCW) : thEndFromRhStart; - thEndFromLhStart = lh->fPart.isCurve() || fPart.isCurve() - ? this->ccwOf(lh, !lhSweepsCCW, thSweepsCCW) : thStartFromLhEnd; - // clear overlap if both pairs turn in the same direction - if (!this->sweepContains(lh) && !this->sweepContains(rh)) { - ltrOverlap &= (int) thStartFromRhEnd * (int) thEndFromRhStart <= 0 - || (int) thStartFromLhEnd * (int) thEndFromLhStart <= 0; - } - } else { - ltrOverlap = false; + if (!lrOverlap) { // no lh/rh sector overlap + if (!ltrOverlap) { // no lh/this/rh sector overlap + return COMPARE_RESULT(4, (lh->fSectorEnd > rh->fSectorStart) + ^ (fSectorStart > lh->fSectorEnd) ^ (fSectorStart > rh->fSectorStart)); } - if (!lrOverlap & !ltrOverlap) { - Turn lhFromRh = (Turn) ((int) lhEndFromRhStart | (int) lhStartFromRhStart); - Turn thFromLh = (Turn) ((int) thEndFromLhStart | (int) thStartFromLhEnd); - Turn thFromRh = (Turn) ((int) thEndFromRhStart | (int) thStartFromRhEnd); - bool result = Turn::kCw == lhFromRh ? - Turn::kCcw == thFromLh && Turn::kCw == thFromRh : - Turn::kCcw == thFromLh || Turn::kCw == thFromRh; - return COMPARE_RESULT(6, result); - } - if (lhHasOffset) { - lh->fPart.fCurve.offset(lh->segment()->verb(), lhOffset); - } - if (rhHasOffset) { - rh->fPart.fCurve.offset(rh->segment()->verb(), rhOffset); - } - lrOverlap = lh->fSectorMask & rh->fSectorMask; - ltrOverlap = (lh->fSectorMask | rh->fSectorMask) & fSectorMask; - } - if (!lrOverlap) { // no lh/rh sector overlap, no offsets int lrGap = (rh->fSectorStart - lh->fSectorStart + 32) & 0x1f; /* A tiny change can move the start +/- 4. The order can only be determined if lr gap is not 12 to 20 or -12 to -20. @@ -197,13 +122,11 @@ bool SkOpAngle::after(SkOpAngle* test) { } else { lrOrder = (int) lh->orderable(rh); if (!ltrOverlap) { - return COMPARE_RESULT(7, !lrOrder); + return COMPARE_RESULT(5, !lrOrder); } } int ltOrder; - SkDEBUGCODE(bool ltOverlap = lhHasOffset || lh->fSectorMask & fSectorMask); - SkDEBUGCODE(bool trOverlap = rhHasOffset || rh->fSectorMask & fSectorMask); - SkASSERT(ltOverlap || trOverlap); + SkASSERT((lh->fSectorMask & fSectorMask) || (rh->fSectorMask & fSectorMask)); if (lh->fSectorMask & fSectorMask) { ltOrder = (int) lh->orderable(this); } else { @@ -220,7 +143,7 @@ bool SkOpAngle::after(SkOpAngle* test) { this->alignmentSameSide(lh, <Order); this->alignmentSameSide(rh, &trOrder); if (lrOrder >= 0 && ltOrder >= 0 && trOrder >= 0) { - return COMPARE_RESULT(8, lrOrder ? (ltOrder & trOrder) : (ltOrder | trOrder)); + return COMPARE_RESULT(7, lrOrder ? (ltOrder & trOrder) : (ltOrder | trOrder)); } SkASSERT(lrOrder >= 0 || ltOrder >= 0 || trOrder >= 0); // There's not enough information to sort. Get the pairs of angles in opposite planes. @@ -232,25 +155,25 @@ bool SkOpAngle::after(SkOpAngle* test) { SkDEBUGCODE(bool lrOpposite = lh->oppositePlanes(rh)); bool ltOpposite = lh->oppositePlanes(this); SkOPASSERT(lrOpposite != ltOpposite); - return COMPARE_RESULT(9, ltOpposite); + return COMPARE_RESULT(8, ltOpposite); } else if (ltOrder == 1 && trOrder == 0) { SkASSERT(lrOrder < 0); bool trOpposite = oppositePlanes(rh); - return COMPARE_RESULT(10, trOpposite); + return COMPARE_RESULT(9, trOpposite); } else if (lrOrder == 1 && trOrder == 1) { SkASSERT(ltOrder < 0); // SkDEBUGCODE(bool trOpposite = oppositePlanes(rh)); bool lrOpposite = lh->oppositePlanes(rh); // SkASSERT(lrOpposite != trOpposite); - return COMPARE_RESULT(11, lrOpposite); + return COMPARE_RESULT(10, lrOpposite); } if (lrOrder < 0) { if (ltOrder < 0) { - return COMPARE_RESULT(12, trOrder); + return COMPARE_RESULT(11, trOrder); } - return COMPARE_RESULT(13, ltOrder); + return COMPARE_RESULT(12, ltOrder); } - return COMPARE_RESULT(14, !lrOrder); + return COMPARE_RESULT(13, !lrOrder); } // given a line, see if the opposite curve's convex hull is all on one side @@ -325,101 +248,10 @@ void SkOpAngle::alignmentSameSide(const SkOpAngle* test, int* order) const { } } -static bool same_side(double cross1, double cross2) { - return cross1 * cross2 > 0 && !roughly_zero_when_compared_to(cross1, cross2) - && !roughly_zero_when_compared_to(cross2, cross1); -} - -static double same_side_candidate(double cross1, double cross2) { - return same_side(cross1, cross2) ? SkTAbs(cross1) > SkTAbs(cross2) ? cross1 : cross2 : 0; -} - -SkOpAngle::Turn SkOpAngle::ccwOf(const SkOpAngle* rh, bool rhCW, bool thisCCW, bool recursed) - const { - const SkDPoint& startPt = fPart.fCurve[0]; - const SkDPoint& rhStartPt = rh->fPart.fCurve[0]; - SkDVector startOffset = rhStartPt - startPt; - bool commonPt = 0 == startOffset.fX && 0 == startOffset.fY; - const SkDVector& sweep = fPart.fSweep[(int) thisCCW]; - const SkDVector& rhSweep = rh->fPart.fSweep[(int) rhCW]; - const SkDVector* testV; - SkDVector rhEndV; - if (commonPt) { - testV = &rhSweep; - } else { - rhEndV = rhSweep + startOffset; - testV = &rhEndV; - } - double endCheck = sweep.crossCheck(*testV); -#if 0 && DEBUG_ANGLE // too verbose to show on all the time - SkDebugf("%s {{{%1.9g,%1.9g}, {%1.9g,%1.9g}}} id=1\n", __func__, rhStartPt.fX, rhStartPt.fY, - rhStartPt.fX + rhSweep.fX, rhStartPt.fY + rhSweep.fY); - SkDebugf("%s {{{%1.9g,%1.9g}, {%1.9g,%1.9g}}} id=2\n", __func__, startPt.fX, startPt.fY, - startPt.fX + sweep.fX, startPt.fY + sweep.fY); -#endif - if (0 == endCheck) { - if (sweep.dot(*testV) < 0) { - return Turn::kNone; // neither clockwise nor counterclockwise - } - // if the pair of angles share an edge, use its other sweep to check the turn value - if ((fPart.isCurve() || rh->fPart.isCurve())) { - if (recursed) { - return Turn::kNone; - } - return this->ccwOf(rh, !rhCW, !thisCCW, true); - } - } - if (commonPt) { - return toTurn(endCheck > 0); - } - double startCheck = sweep.crossCheck(startOffset); - if ((startCheck == 0 || startOffset.lengthSquared() < FLT_EPSILON_SQUARED * 2049) && - (endCheck == 0 || testV->lengthSquared() < FLT_EPSILON_SQUARED * 2049)) { - double cross = sweep.cross(rhSweep); - if (cross != 0) - return toTurn(cross > 0); - } - if (same_side(startCheck, endCheck)) { - return toTurn(startCheck > 0); - } - SkDVector reverseSweep = -sweep; - SkDVector rhReverseStartV = startOffset - sweep; - double reverseStartCheck = reverseSweep.crossCheck(rhReverseStartV); - SkDVector rhReverseEndV = rhReverseStartV + rhSweep; - double reverseEndCheck = reverseSweep.crossCheck(rhReverseEndV); - if (same_side(reverseStartCheck, reverseEndCheck)) { - return toTurn(reverseStartCheck < 0); - } - double rhEndCheck = rhSweep.crossCheck(rhReverseEndV); - double rhStartCheck = rhSweep.crossCheck(*testV); - double endSide = same_side_candidate(rhEndCheck, rhStartCheck); - SkDVector rhReverseSweep = -rhSweep; - double rhReverseEndCheck = rhReverseSweep.crossCheck(rhReverseStartV); - double rhReverseStartCheck = rhReverseSweep.crossCheck(startOffset); - double startSide = -same_side_candidate(rhReverseEndCheck, rhReverseStartCheck); - if (startSide || endSide) { - return toTurn((SkTAbs(startSide) > SkTAbs(endSide) ? startSide : endSide) > 0); - } - // if a pair crosses only slightly, no two ends will be on the same side - // look for the smaller ratio to guess which segment only crosses the other slightly - double crosses[] = { endCheck, reverseStartCheck, reverseEndCheck, - rhStartCheck, rhEndCheck, rhReverseStartCheck, rhReverseEndCheck }; - int smallest = -1; - double smallCross = SkTAbs(startCheck); - for (int index = 0; index < (int) SK_ARRAY_COUNT(crosses); ++index) { - double testCross = SkTAbs(crosses[index]); - if (smallCross > testCross) { - smallCross = testCross; - smallest = index; - } - } - return toTurn((smallest <= 2 ? endCheck : -rhReverseEndCheck) > 0); -} - -bool SkOpAngle::checkCrossesZero(int* start, int* end) const { - *start = SkTMin(fSectorStart, fSectorEnd); - *end = SkTMax(fSectorStart, fSectorEnd); - bool crossesZero = *end - *start > 16; +bool SkOpAngle::checkCrossesZero() const { + int start = SkTMin(fSectorStart, fSectorEnd); + int end = SkTMax(fSectorStart, fSectorEnd); + bool crossesZero = end - start > 16; return crossesZero; } @@ -794,6 +626,7 @@ SkOpGlobalState* SkOpAngle::globalState() const { return this->segment()->globalState(); } + // OPTIMIZE: if this loops to only one other angle, after first compare fails, insert on other side // OPTIMIZE: return where insertion succeeded. Then, start next insertion on opposite side bool SkOpAngle::insert(SkOpAngle* angle) { @@ -1016,19 +849,6 @@ SkOpAngle* SkOpAngle::previous() const { } while (true); } -// returns true if rounded sector range crosses zero -bool SkOpAngle::sectorRange(int* start, int* end, bool roundOut) const { - if (checkCrossesZero(start, end)) { - SkTSwap(*start, *end); - } - // round away since the offset curves may swap order - if (roundOut) { - *start = (((*start + 1) & ~0x03) - 1) & 0x1f; - *end |= 0x03; - } - return *end < *start; -} - SkOpSegment* SkOpAngle::segment() const { return fStart->segment(); } @@ -1165,25 +985,23 @@ deferTilLater: fSectorMask = 1 << fSectorStart; return; } - int start, end; - bool crossesZero = this->checkCrossesZero(&start, &end); - bool bumpStart = (fSectorStart & 3) == 3; - bool bumpEnd = (fSectorEnd & 3) == 3; - if (bumpStart | bumpEnd) { - bool curveBendsCCW = (fSectorStart == start) ^ crossesZero; - // bump the start and end of the sector span if they are on exact compass points - if (bumpStart) { - fSectorStart = (fSectorStart + (curveBendsCCW ? 1 : 31)) & 0x1f; - } - if (bumpEnd) { - fSectorEnd = (fSectorEnd + (curveBendsCCW ? 31 : 1)) & 0x1f; - } - crossesZero = this->checkCrossesZero(&start, &end); + bool crossesZero = this->checkCrossesZero(); + int start = SkTMin(fSectorStart, fSectorEnd); + bool curveBendsCCW = (fSectorStart == start) ^ crossesZero; + // bump the start and end of the sector span if they are on exact compass points + if ((fSectorStart & 3) == 3) { + fSectorStart = (fSectorStart + (curveBendsCCW ? 1 : 31)) & 0x1f; } + if ((fSectorEnd & 3) == 3) { + fSectorEnd = (fSectorEnd + (curveBendsCCW ? 31 : 1)) & 0x1f; + } + crossesZero = this->checkCrossesZero(); + start = SkTMin(fSectorStart, fSectorEnd); + int end = SkTMax(fSectorStart, fSectorEnd); if (!crossesZero) { fSectorMask = (unsigned) -1 >> (31 - end + start) << start; } else { - fSectorMask = (unsigned) -1 >> (31 - start) | (unsigned) -1 << end; + fSectorMask = (unsigned) -1 >> (31 - start) | ((unsigned) -1 << end); } } @@ -1191,70 +1009,6 @@ SkOpSpan* SkOpAngle::starter() { return fStart->starter(fEnd); } -bool SkOpAngle::sweepsCCW() const { - if (!fPart.isCurve()) { - return false; // lines have no sweep - } -#if 0 && DEBUG_ANGLE // too verbose to show all the time - SkDebugf("%s {{{0,0}, {%g,%g}}} id=1\n", __func__, fPart.fSweep[0].fX, fPart.fSweep[0].fY); - SkDebugf("%s {{{0,0}, {%g,%g}}} id=2\n", __func__, fPart.fSweep[1].fX, fPart.fSweep[1].fY); -#endif - return fPart.fSweep[0].crossCheck(fPart.fSweep[1]) < 0; -} - -static bool sweep_edge_contains(const SkDVector& edge, const SkDVector& v, double* direction) { - double cross = edge.crossCheck(v); - if (cross) { - if (cross * *direction < 0) { - return true; - } - *direction = cross; - } - return false; -} - -static bool sweep_contains(const SkDVector sweep[2], const SkDVector& v, double* direction) { - if (sweep_edge_contains(sweep[0], v, direction)) { - return true; - } - return sweep_edge_contains(sweep[1], v, direction); -} - -bool SkOpAngle::sweepContains(const SkOpAngle* rh) const { - if (!fPart.isCurve()) { - return false; - } - if (!rh->fPart.isCurve()) { - return false; - } - const SkDPoint& startPt = fPart.fCurve[0]; - const SkDVector* sweep = fPart.fSweep; - const SkDPoint& rhStartPt = rh->fPart.fCurve[0]; - double direction = 0; - if (startPt != rhStartPt) { - SkDVector vTest = rhStartPt - startPt; - if (sweep_contains(sweep, vTest, &direction)) { - return true; - } - for (int index = 0; index < (int) SK_ARRAY_COUNT(rh->fPart.fSweep); ++index) { - SkDPoint sweepEnd = rhStartPt; - sweepEnd += rh->fPart.fSweep[index]; - SkDVector vTest = sweepEnd - startPt; - if (sweep_contains(sweep, vTest, &direction)) { - return true; - } - } - } else { - for (int index = 0; index < (int) SK_ARRAY_COUNT(rh->fPart.fSweep); ++index) { - const SkDVector& vTest = rh->fPart.fSweep[index]; - if (sweep_contains(sweep, vTest, &direction)) { - return true; - } - } - } - return false; -} - bool SkOpAngle::tangentsDiverge(const SkOpAngle* rh, double s0xt0) { if (s0xt0 == 0) { return false; diff --git a/src/pathops/SkOpAngle.h b/src/pathops/SkOpAngle.h index d11a1c1..d8615c3 100644 --- a/src/pathops/SkOpAngle.h +++ b/src/pathops/SkOpAngle.h @@ -41,12 +41,8 @@ public: #endif #if DEBUG_ANGLE - void debugAfter(const SkOpAngle* lh, const SkOpAngle* rh, SkString* bugOut) const; bool debugCheckCoincidence() const { return fCheckCoincidence; } void debugCheckNearCoincidence() const; -#endif - SkDPoint* debugFirstPt() { return &fOriginalCurvePart.fLine.fPts[0]; } -#if DEBUG_ANGLE SkString debugPart() const; #endif const SkOpPtT* debugPtT(int id) const; @@ -100,20 +96,10 @@ public: } private: - enum class Turn { -#ifdef SK_DEBUG - kDebugUninitialized = -2, -#endif - kCcw = -1, - kNone, - kCw - }; - bool after(SkOpAngle* test); void alignmentSameSide(const SkOpAngle* test, int* order) const; int allOnOneSide(const SkOpAngle* test); - Turn ccwOf(const SkOpAngle* rh, bool rhCW, bool thisCCW, bool recursed = false) const; - bool checkCrossesZero(int* start, int* end) const; + bool checkCrossesZero() const; bool checkParallel(SkOpAngle* ); bool computeSector(); int convexHullOverlaps(const SkOpAngle* ); @@ -126,13 +112,9 @@ private: bool midToSide(const SkOpAngle* rh, bool* inside) const; bool oppositePlanes(const SkOpAngle* rh) const; bool orderable(SkOpAngle* rh); // false == this < rh ; true == this > rh - bool sectorRange(int* start, int* end, bool roundOut) const; void setSector(); void setSpans(); - bool sweepContains(const SkOpAngle* rh) const; - bool sweepsCCW() const; bool tangentsDiverge(const SkOpAngle* rh, double s0xt0); - Turn toTurn(bool ccw) const { return ccw ? Turn::kCcw : Turn::kCw; } SkDCurve fOriginalCurvePart; // the curve from start to end SkDCurveSweep fPart; // the curve from start to end offset as needed diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp index 6ed37dc..45a1138 100644 --- a/src/pathops/SkPathOpsDebug.cpp +++ b/src/pathops/SkPathOpsDebug.cpp @@ -18,6 +18,7 @@ bool SkPathOpsDebug::gDumpOp; // set to true to write op to file before a crash bool SkPathOpsDebug::gVerifyOp; // set to true to compare result against regions #endif +bool SkPathOpsDebug::gRunFail; // set to true to check for success on tests known to fail bool SkPathOpsDebug::gVeryVerbose; // set to true to run extensive checking tests #undef FAIL_IF @@ -666,6 +667,10 @@ void SkOpGlobalState::debugResetLoopCounts() { } #endif +bool SkOpGlobalState::DebugRunFail() { + return SkPathOpsDebug::gRunFail; +} + // this is const so it can be called by const methods that overwise don't alter state #if DEBUG_VALIDATE || DEBUG_COIN void SkOpGlobalState::debugSetPhase(const char* funcName DEBUG_COIN_DECLARE_PARAMS()) const { @@ -1244,17 +1249,6 @@ void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int This checks the distance between start points; the distance between */ #if DEBUG_ANGLE -void SkOpAngle::debugAfter(const SkOpAngle* lh, const SkOpAngle* rh, SkString* bugOut) const { - bugOut->printf("%s [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g" - " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g" - " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g ", __FUNCTION__, - lh->segment()->debugID(), lh->debugID(), lh->fSectorStart, lh->fSectorEnd, - lh->fStart->t(), lh->fEnd->t(), - segment()->debugID(), debugID(), fSectorStart, fSectorEnd, fStart->t(), fEnd->t(), - rh->segment()->debugID(), rh->debugID(), rh->fSectorStart, rh->fSectorEnd, - rh->fStart->t(), rh->fEnd->t()); -} - void SkOpAngle::debugCheckNearCoincidence() const { const SkOpAngle* test = this; do { @@ -1382,8 +1376,8 @@ void SkOpAngle::debugValidate() const { } next = next->fNext; } while (next && next != first); - SkASSERT(wind == 0); - SkASSERT(opp == 0); + SkASSERT(wind == 0 || !SkPathOpsDebug::gRunFail); + SkASSERT(opp == 0 || !SkPathOpsDebug::gRunFail); #endif } @@ -1410,8 +1404,8 @@ void SkOpAngle::debugValidateNext() const { #ifdef SK_DEBUG void SkCoincidentSpans::debugStartCheck(const SkOpSpanBase* outer, const SkOpSpanBase* over, const SkOpGlobalState* debugState) const { - SkASSERT(coinPtTEnd()->span() == over); - SkASSERT(oppPtTEnd()->span() == outer); + SkASSERT(coinPtTEnd()->span() == over || !SkOpGlobalState::DebugRunFail()); + SkASSERT(oppPtTEnd()->span() == outer || !SkOpGlobalState::DebugRunFail()); } #endif diff --git a/src/pathops/SkPathOpsDebug.h b/src/pathops/SkPathOpsDebug.h index 0f3fada..97fa534 100644 --- a/src/pathops/SkPathOpsDebug.h +++ b/src/pathops/SkPathOpsDebug.h @@ -374,6 +374,7 @@ public: static void DumpGlitchType(GlitchType ); #endif + static bool gRunFail; static bool gVeryVerbose; #if DEBUG_DUMP_VERIFY diff --git a/src/pathops/SkPathOpsPoint.h b/src/pathops/SkPathOpsPoint.h index deadbc2..f314f69 100644 --- a/src/pathops/SkPathOpsPoint.h +++ b/src/pathops/SkPathOpsPoint.h @@ -29,29 +29,13 @@ struct SkDVector { fY += v.fY; } - SkDVector operator+(const SkDVector& v) const { - SkDVector result = *this; - result += v; - return result; - } - // only called by nearestT, which is currently only used by testing void operator-=(const SkDVector& v) { fX -= v.fX; fY -= v.fY; } - SkDVector operator-(const SkDVector& v) const { - SkDVector result = *this; - result -= v; - return result; - } - - SkDVector operator-() const { - SkDVector result = { -fX, -fY }; - return result; - } - + // only used by testing void operator/=(const double s) { fX /= s; fY /= s; @@ -105,13 +89,6 @@ struct SkDVector { fX *= inverseLength; fY *= inverseLength; } - - void setLengthSquared(double lenSquared) { - double inverseLength = lenSquared / this->lengthSquared(); - fX *= inverseLength; - fY *= inverseLength; - } - }; struct SkDPoint { @@ -150,14 +127,15 @@ struct SkDPoint { fY -= v.fY; } - SkDPoint operator+(const SkDVector& v) const { + // only used by testing + SkDPoint operator+(const SkDVector& v) { SkDPoint result = *this; result += v; return result; } // only used by testing - SkDPoint operator-(const SkDVector& v) const { + SkDPoint operator-(const SkDVector& v) { SkDPoint result = *this; result -= v; return result; diff --git a/src/pathops/SkPathOpsTypes.h b/src/pathops/SkPathOpsTypes.h index 4e9fbe9..f525ea4 100644 --- a/src/pathops/SkPathOpsTypes.h +++ b/src/pathops/SkPathOpsTypes.h @@ -77,6 +77,8 @@ public: const class SkOpPtT* debugPtT(int id) const; #endif + static bool DebugRunFail(); + #ifdef SK_DEBUG const class SkOpSegment* debugSegment(int id) const; bool debugSkipAssert() const { return fDebugSkipAssert; } diff --git a/tests/PathOpsAngleTest.cpp b/tests/PathOpsAngleTest.cpp index a598aea..d5285c8 100644 --- a/tests/PathOpsAngleTest.cpp +++ b/tests/PathOpsAngleTest.cpp @@ -478,67 +478,6 @@ DEF_TEST(PathOpsAngleAfter, reporter) { } } -static void offset_start(SkOpAngle* angle, const SkPoint* line, bool offsetStart) { - SkDPoint* pt = angle->debugFirstPt(); - if (!offsetStart) { - pt->fX = pt->fY = 0; - return; - } - pt->fX = line[1].fX * 0.001f; - pt->fY = line[1].fY * 0.001f; -} - -// test if offset line edges return the same results as edges without offsets -DEF_TEST(PathOpsOffsetLineAngle, reporter) { - static SkPoint radialLines[][2] = { - { {0, 0}, { 2, -1} }, { {0, 0}, { 2, -2} }, { {0, 0}, { 1, -2} }, { {0, 0}, { 0, -2} }, - { {0, 0}, {-1, -2} }, { {0, 0}, {-2, -2} }, { {0, 0}, {-2, -1} }, { {0, 0}, {-2, 0} }, - { {0, 0}, {-2, 1} }, { {0, 0}, {-2, 2} }, { {0, 0}, {-1, 2} }, { {0, 0}, { 0, 2} }, - { {0, 0}, { 1, 2} }, { {0, 0}, { 2, 2} }, { {0, 0}, { 2, 1} }, { {0, 0}, { 2, 0} }, - }; - SkChunkAlloc allocator(4096); - SkOpContourHead contour; - SkOpGlobalState state(&contour, &allocator SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr)); - contour.init(&state, false, false); - for (int lh = 0; lh < 16; ++lh) { - for (int mid = 0; mid < 16; ++mid) { - if (lh == mid) { - continue; - } - for (int rh = 0; rh < 16; ++rh) { - if (lh == rh || mid == rh) { - continue; - } - allocator.reset(); - contour.reset(); - contour.addLine(radialLines[lh]); - contour.addLine(radialLines[mid]); - contour.addLine(radialLines[rh]); - SkOpSegment* seg1 = contour.first(); - seg1->debugAddAngle(0, 1); - SkOpSegment* seg2 = seg1->next(); - seg2->debugAddAngle(0, 1); - SkOpSegment* seg3 = seg2->next(); - seg3->debugAddAngle(0, 1); - SkOpAngle* angle1 = seg1->debugLastAngle(); - SkOpAngle* angle2 = seg2->debugLastAngle(); - SkOpAngle* angle3 = seg3->debugLastAngle(); - PathOpsAngleTester::SetNext(*angle1, *angle3); - /* int expected = */ PathOpsAngleTester::After(*angle2, *angle1); - for (int test = 1; test <= 8; ++test) { - offset_start(angle1, radialLines[lh], test & 1); - offset_start(angle2, radialLines[mid], test & 2); - offset_start(angle3, radialLines[rh], test & 4); - /* int found = */ PathOpsAngleTester::After(*angle2, *angle1); -#if 0 // this test fails; haven't explored if this is a real bug or not - REPORTER_ASSERT(reporter, expected == found); -#endif - } - } - } - } -} - void SkOpSegment::debugAddAngle(double startT, double endT) { SkOpPtT* startPtT = startT == 0 ? fHead.ptT() : startT == 1 ? fTail.ptT() : this->addT(startT); diff --git a/tests/PathOpsChalkboardTest.cpp b/tests/PathOpsChalkboardTest.cpp index acfa46f..8c74e7f 100644 --- a/tests/PathOpsChalkboardTest.cpp +++ b/tests/PathOpsChalkboardTest.cpp @@ -91,6 +91,9 @@ static void testChalkboard(PathOpsThreadState* data) { } static void chalkboard_threaded(skiatest::Reporter* reporter, const char* filename) { +#if DEBUG_UNDER_DEVELOPMENT + return; +#endif initializeTests(reporter, "chalkboard"); PathOpsThreadedTestRunner testRunner(reporter); SkRandom r; diff --git a/tests/PathOpsExtendedTest.cpp b/tests/PathOpsExtendedTest.cpp index 06fee80..d70deb3 100644 --- a/tests/PathOpsExtendedTest.cpp +++ b/tests/PathOpsExtendedTest.cpp @@ -320,26 +320,21 @@ int comparePaths(skiatest::Reporter* reporter, const char* filename, const SkPat static SkTDArray gTestOp; -static void dumpPathOpFunction(const char* testName, const SkPath& a, const SkPath& b, - const SkPathOp shapeOp) { +static void showPathOpPath(const char* testName, const SkPath& one, const SkPath& two, + const SkPath& a, const SkPath& b, const SkPath& scaledOne, const SkPath& scaledTwo, + const SkPathOp shapeOp, const SkMatrix& scale) { + SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs)); if (!testName) { testName = "xOp"; } SkDebugf("static void %s_%s(skiatest::Reporter* reporter, const char* filename) {\n", testName, opSuffixes[shapeOp]); + *gTestOp.append() = shapeOp; SkDebugf(" SkPath path, pathB;\n"); SkPathOpsDebug::ShowOnePath(a, "path", false); SkPathOpsDebug::ShowOnePath(b, "pathB", false); SkDebugf(" testPathOp(reporter, path, pathB, %s, filename);\n", opStrs[shapeOp]); SkDebugf("}\n"); -} - -static void showPathOpPath(const char* testName, const SkPath& one, const SkPath& two, - const SkPath& a, const SkPath& b, const SkPath& scaledOne, const SkPath& scaledTwo, - const SkPathOp shapeOp, const SkMatrix& scale) { - SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs)); - *gTestOp.append() = shapeOp; - dumpPathOpFunction(testName, a, b, shapeOp); drawAsciiPaths(scaledOne, scaledTwo, true); } @@ -349,15 +344,11 @@ static int comparePaths(skiatest::Reporter* reporter, const char* testName, cons const SkPath& scaledOne, const SkPath& two, const SkPath& scaledTwo, SkBitmap& bitmap, const SkPath& a, const SkPath& b, const SkPathOp shapeOp, const SkMatrix& scale, ExpectMatch expectMatch) { - if (ExpectMatch::kFlaky == expectMatch) { - return 0; // fuzz data may cause asserts in region generating code, so don't try - } int errors2x2; const int MAX_ERRORS = 8; (void) pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2); if (ExpectMatch::kNo == expectMatch) { if (errors2x2 < MAX_ERRORS) { - SkDebugf("%s failing test %s now succeeds\n", __FUNCTION__, testName); REPORTER_ASSERT(reporter, 0); } return 0; @@ -514,11 +505,6 @@ bool testSimplifyCheck(skiatest::Reporter* reporter, const SkPath& path, const c ExpectSuccess::kYes : ExpectSuccess::kNo, SkipAssert::kNo, ExpectMatch::kNo); } -bool testSimplifyTry(skiatest::Reporter* reporter, const SkPath& path, const char* filename) { - return inner_simplify(reporter, path, filename, ExpectSuccess::kYes, SkipAssert::kNo, - ExpectMatch::kNo); -} - #if DEBUG_SHOW_TEST_NAME static void showName(const SkPath& a, const SkPath& b, const SkPathOp shapeOp) { SkDebugf("\n"); @@ -539,23 +525,18 @@ static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP SkDEBUGPARAMS(testName))) { if (ExpectSuccess::kYes == expectSuccess) { SkDebugf("%s %s did not expect failure\n", __FUNCTION__, testName); - dumpPathOpFunction(testName, a, b, shapeOp); REPORTER_ASSERT(reporter, 0); } return false; } else { if (ExpectSuccess::kNo == expectSuccess) { SkDebugf("%s %s unexpected success\n", __FUNCTION__, testName); - dumpPathOpFunction(testName, a, b, shapeOp); REPORTER_ASSERT(reporter, 0); } } if (!reporter->verbose()) { return true; } - if (ExpectMatch::kFlaky == expectMatch) { - return true; // fuzzy data may assert in region construction: see bug.skia.org/6129 - } SkPath pathOut, scaledPathOut; SkRegion rgnA, rgnB, openClip, rgnOut; openClip.setRect(-16000, -16000, 16000, 16000); @@ -598,18 +579,29 @@ bool testPathOpCheck(skiatest::Reporter* reporter, const SkPath& a, const SkPath ExpectSuccess::kYes : ExpectSuccess::kNo, SkipAssert::kNo, ExpectMatch::kNo); } -bool testPathOpTry(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, - const SkPathOp shapeOp, const char* testName) { - return innerPathOp(reporter, a, b, shapeOp, testName, - ExpectSuccess::kYes, SkipAssert::kNo, ExpectMatch::kNo); -} - bool testPathOpFuzz(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, const SkPathOp shapeOp, const char* testName) { return innerPathOp(reporter, a, b, shapeOp, testName, ExpectSuccess::kFlaky, SkipAssert::kYes, ExpectMatch::kFlaky); } +bool testPathOpFail(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, + const SkPathOp shapeOp, const char* testName) { +#if DEBUG_SHOW_TEST_NAME + showName(a, b, shapeOp); +#endif + SkPath orig; + orig.lineTo(54, 43); + SkPath out = orig; + if (Op(a, b, shapeOp, &out) ) { + SkDebugf("%s test is expected to fail\n", __FUNCTION__); + REPORTER_ASSERT(reporter, 0); + return false; + } + SkASSERT(out == orig); + return true; +} + SK_DECLARE_STATIC_MUTEX(gMutex); void initializeTests(skiatest::Reporter* reporter, const char* test) { diff --git a/tests/PathOpsExtendedTest.h b/tests/PathOpsExtendedTest.h index 7c8ceb1..9f8b0ae 100644 --- a/tests/PathOpsExtendedTest.h +++ b/tests/PathOpsExtendedTest.h @@ -36,18 +36,17 @@ extern bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPa const SkPathOp , const char* testName); extern bool testPathOpCheck(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, const SkPathOp , const char* testName, bool checkFail); +extern bool testPathOpFail(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, + const SkPathOp, const char* testName); extern bool testPathOpFuzz(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, const SkPathOp , const char* testName); -extern bool testPathOpTry(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, - const SkPathOp , const char* testName); extern bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state, const char* pathStr); extern bool testSimplify(skiatest::Reporter* reporter, const SkPath& path, const char* filename); extern bool testSimplifyCheck(skiatest::Reporter* reporter, const SkPath& path, const char* filename, bool checkFail); extern bool testSimplifyFuzz(skiatest::Reporter* reporter, const SkPath& path, - const char* filename); -extern bool testSimplifyTry(skiatest::Reporter* reporter, const SkPath& path, const char* filename); + const char* filename); void initializeTests(skiatest::Reporter* reporter, const char* testName); diff --git a/tests/PathOpsFuzz763Test.cpp b/tests/PathOpsFuzz763Test.cpp index 996f4e7..90d5723 100644 --- a/tests/PathOpsFuzz763Test.cpp +++ b/tests/PathOpsFuzz763Test.cpp @@ -2092,7 +2092,8 @@ path.quadTo(SkBits2Float(0x42240000), SkBits2Float(0x41ed7d86), SkBits2Float(0x4 path.close(); SkPath path2(path); - testPathOpTry(reporter, path1, path2, (SkPathOp) 2, filename); + // DEBUG_UNDER_DEVELOPMENT fuzz763_1026368 disable expectation check for now + testPathOpCheck(reporter, path1, path2, (SkPathOp) 2, filename, !SkOpGlobalState::DebugRunFail()); } static void fuzz763_5485218(skiatest::Reporter* reporter, const char* filename) { diff --git a/tests/PathOpsIssue3651.cpp b/tests/PathOpsIssue3651.cpp index dc93657..bd4ed2d 100644 --- a/tests/PathOpsIssue3651.cpp +++ b/tests/PathOpsIssue3651.cpp @@ -472,7 +472,9 @@ path.close(); static void issue3651_1a(skiatest::Reporter* reporter, const char* filename) { SkPath path = path1_a(); SkPath pathB = path2_a(); - testPathOpTry(reporter, path, pathB, SkPathOp::kUnion_SkPathOp, filename); + // DEBUG_UNDER_DEVELOPMENT issue3651_1a disable expectation check for now + testPathOpCheck(reporter, path, pathB, SkPathOp::kUnion_SkPathOp, filename, + !SkOpGlobalState::DebugRunFail()); } static SkPath path3() { @@ -1202,7 +1204,9 @@ path.close(); static void issue3651_1(skiatest::Reporter* reporter, const char* filename) { SkPath path = path1(); SkPath pathB = path2(); - testPathOpTry(reporter, path, pathB, SkPathOp::kUnion_SkPathOp, filename); + // DEBUG_UNDER_DEVELOPMENT issue3651_1 disable expectation check for now + testPathOpCheck(reporter, path, pathB, SkPathOp::kUnion_SkPathOp, filename, + !SkOpGlobalState::DebugRunFail()); } static void issue3651_2(skiatest::Reporter* reporter, const char* filename) { diff --git a/tests/PathOpsSimplifyFailTest.cpp b/tests/PathOpsSimplifyFailTest.cpp index 44bb50c..b6f210e 100644 --- a/tests/PathOpsSimplifyFailTest.cpp +++ b/tests/PathOpsSimplifyFailTest.cpp @@ -215,278 +215,9 @@ path.close(); testSimplifyFuzz(reporter, path, filename); } -static void fuzz_twister(skiatest::Reporter* reporter, const char* filename) { - SkPath path; - path.setFillType((SkPath::FillType) 0); -path.moveTo(0, 600); -path.lineTo(3.35544e+07f, 600); -path.lineTo(3.35544e+07f, 0); -path.lineTo(0, 0); -path.lineTo(0, 600); -path.close(); -path.moveTo(63, 600); -path.lineTo(3.35545e+07f, 600); -path.lineTo(3.35545e+07f, 0); -path.lineTo(63, 0); -path.lineTo(63, 600); -path.close(); -path.moveTo(93, 600); -path.lineTo(3.35545e+07f, 600); -path.lineTo(3.35545e+07f, 0); -path.lineTo(93, 0); -path.lineTo(93, 600); -path.close(); -path.moveTo(123, 600); -path.lineTo(3.35546e+07f, 600); -path.lineTo(3.35546e+07f, 0); -path.lineTo(123, 0); -path.lineTo(123, 600); -path.close(); - testSimplifyFuzz(reporter, path, filename); -} - -static void fuzz_twister2(skiatest::Reporter* reporter, const char* filename) { - SkPath path; - -path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x44160000)); // 0, 600 -path.lineTo(SkBits2Float(0x4bfffffe), SkBits2Float(0x44160000)); // 3.35544e+07f, 600 -path.lineTo(SkBits2Float(0x4bfffffe), SkBits2Float(0x00000000)); // 3.35544e+07f, 0 -path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0 -path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x44160000)); // 0, 600 -path.close(); - -path.moveTo(SkBits2Float(0x427c0000), SkBits2Float(0x00000000)); // 63, 0 -path.lineTo(SkBits2Float(0x4c00000f), SkBits2Float(0x00000000)); // 3.35545e+07f, 0 -path.lineTo(SkBits2Float(0x4c00000f), SkBits2Float(0x00000000)); // 3.35545e+07f, 0 -path.lineTo(SkBits2Float(0x427c0000), SkBits2Float(0x00000000)); // 63, 0 -path.close(); - -path.moveTo(SkBits2Float(0x42ba0000), SkBits2Float(0x00000000)); // 93, 0 -path.lineTo(SkBits2Float(0x4c000016), SkBits2Float(0x00000000)); // 3.35545e+07f, 0 -path.lineTo(SkBits2Float(0x4c000016), SkBits2Float(0x00000000)); // 3.35545e+07f, 0 -path.lineTo(SkBits2Float(0x42ba0000), SkBits2Float(0x00000000)); // 93, 0 -path.close(); - -path.moveTo(SkBits2Float(0x42f60000), SkBits2Float(0x00000000)); // 123, 0 -path.lineTo(SkBits2Float(0x4c00001e), SkBits2Float(0x00000000)); // 3.35546e+07f, 0 -path.lineTo(SkBits2Float(0x4c00001e), SkBits2Float(0x00000000)); // 3.35546e+07f, 0 -path.lineTo(SkBits2Float(0x42f60000), SkBits2Float(0x00000000)); // 123, 0 -path.close(); - - testSimplifyFuzz(reporter, path, filename); -} - -static void fuzz994s_11(skiatest::Reporter* reporter, const char* filename) { - SkPath path; - path.setFillType((SkPath::FillType) 0); -path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90 -path.close(); -path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90 -path.close(); -path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90 -path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x42b40000)); // 110, 90 -path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x41f00000)); // 110, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90 -path.close(); -path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30 -path.lineTo(SkBits2Float(0x46ff4c00), SkBits2Float(0x41f00000)); // 32678, 30 -path.lineTo(SkBits2Float(0x46ff4c00), SkBits2Float(0x41f00000)); // 32678, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30 -path.close(); -path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x4c000006)); // 10, 3.35545e+07f -path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x4c000006)); // 110, 3.35545e+07f -path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x41f00000)); // 110, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x4c000006)); // 10, 3.35545e+07f -path.close(); -path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x439d8000)); // 10, 315 -path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x439d8000)); // 110, 315 -path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x437f0000)); // 110, 255 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x437f0000)); // 10, 255 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x439d8000)); // 10, 315 -path.close(); -path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x42700000)); // 0, 60 -path.lineTo(SkBits2Float(0x42c80000), SkBits2Float(0x42700000)); // 100, 60 -path.lineTo(SkBits2Float(0x42c80000), SkBits2Float(0x00000000)); // 100, 0 -path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0 -path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x42700000)); // 0, 60 -path.close(); -path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90 -path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x42b40000)); // 110, 90 -path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x41f00000)); // 110, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90 -path.close(); -path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x4c000006)); // 10, 3.35545e+07f -path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x4c000006)); // 110, 3.35545e+07f -path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x41f00000)); // 110, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x4c000006)); // 10, 3.35545e+07f -path.close(); -path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90 -path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x42b40000)); // 110, 90 -path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x41f00000)); // 110, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30 -path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90 -path.close(); - - testSimplifyFuzz(reporter, path, filename); -} - -static void fuzz994s_3414(skiatest::Reporter* reporter, const char* filename) { - SkPath path; - path.setFillType((SkPath::FillType) 0); -path.moveTo(SkBits2Float(0x42c80000), SkBits2Float(0x42480000)); // 100, 50 -path.conicTo(SkBits2Float(0x42c80000), SkBits2Float(0x00000000), SkBits2Float(0x42480000), SkBits2Float(0x00000000), SkBits2Float(0x3f3504f3)); // 100, 0, 50, 0, 0.707107f -path.conicTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000), SkBits2Float(0x00000000), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 0, 0, 0, 50, 0.707107f -path.conicTo(SkBits2Float(0x00000000), SkBits2Float(0x42c80000), SkBits2Float(0x42480000), SkBits2Float(0x42c80000), SkBits2Float(0x3f3504f3)); // 0, 100, 50, 100, 0.707107f -path.conicTo(SkBits2Float(0x42c80000), SkBits2Float(0x42c80000), SkBits2Float(0x42c80000), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 100, 100, 100, 50, 0.707107f -path.close(); -path.moveTo(SkBits2Float(0x42c84964), SkBits2Float(0x42480000)); // 100.143f, 50 -path.conicTo(SkBits2Float(0x42c84964), SkBits2Float(0x00000000), SkBits2Float(0x424892c8), SkBits2Float(0x00000000), SkBits2Float(0x3f3504f3)); // 100.143f, 0, 50.1433f, 0, 0.707107f -path.conicTo(SkBits2Float(0x3e12c788), SkBits2Float(0x00000000), SkBits2Float(0x3e12c788), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 0.143339f, 0, 0.143339f, 50, 0.707107f -path.conicTo(SkBits2Float(0x3e12c788), SkBits2Float(0x42c80000), SkBits2Float(0x424892c8), SkBits2Float(0x42c80000), SkBits2Float(0x3f3504f3)); // 0.143339f, 100, 50.1433f, 100, 0.707107f -path.conicTo(SkBits2Float(0x42c84964), SkBits2Float(0x42c80000), SkBits2Float(0x42c84964), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 100.143f, 100, 100.143f, 50, 0.707107f -path.close(); -path.moveTo(SkBits2Float(0x42c80000), SkBits2Float(0x42480000)); // 100, 50 -path.conicTo(SkBits2Float(0x42c80000), SkBits2Float(0x00000000), SkBits2Float(0x42480000), SkBits2Float(0x00000000), SkBits2Float(0x3f3504f3)); // 100, 0, 50, 0, 0.707107f -path.conicTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000), SkBits2Float(0x00000000), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 0, 0, 0, 50, 0.707107f -path.conicTo(SkBits2Float(0x00000000), SkBits2Float(0x42c80000), SkBits2Float(0x42480000), SkBits2Float(0x42c80000), SkBits2Float(0x3f3504f3)); // 0, 100, 50, 100, 0.707107f -path.conicTo(SkBits2Float(0x42c80000), SkBits2Float(0x42c80000), SkBits2Float(0x42c80000), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 100, 100, 100, 50, 0.707107f -path.close(); -path.moveTo(SkBits2Float(0x4c00006b), SkBits2Float(0x424c0000)); // 3.35549e+07f, 51 -path.conicTo(SkBits2Float(0x4c00006b), SkBits2Float(0xcbffffe5), SkBits2Float(0x43d6e720), SkBits2Float(0xcbffffe5), SkBits2Float(0x3f3504f3)); // 3.35549e+07f, -3.35544e+07f, 429.806f, -3.35544e+07f, 0.707107f -path.conicTo(SkBits2Float(0xcbffff28), SkBits2Float(0xcbffffe5), SkBits2Float(0xcbffff28), SkBits2Float(0x424c0000), SkBits2Float(0x3f3504f3)); // -3.3554e+07f, -3.35544e+07f, -3.3554e+07f, 51, 0.707107f -path.conicTo(SkBits2Float(0xcbffff28), SkBits2Float(0x4c00000c), SkBits2Float(0x43d6e720), SkBits2Float(0x4c00000c), SkBits2Float(0x3f3504f3)); // -3.3554e+07f, 3.35545e+07f, 429.806f, 3.35545e+07f, 0.707107f -path.conicTo(SkBits2Float(0x4c00006b), SkBits2Float(0x4c00000c), SkBits2Float(0x4c00006b), SkBits2Float(0x424c0000), SkBits2Float(0x3f3504f3)); // 3.35549e+07f, 3.35545e+07f, 3.35549e+07f, 51, 0.707107f -path.close(); -path.moveTo(SkBits2Float(0x43ef6720), SkBits2Float(0x42480000)); // 478.806f, 50 -path.conicTo(SkBits2Float(0x43ef6720), SkBits2Float(0x00000000), SkBits2Float(0x43d66720), SkBits2Float(0x00000000), SkBits2Float(0x3f3504f3)); // 478.806f, 0, 428.806f, 0, 0.707107f -path.conicTo(SkBits2Float(0x43bd6720), SkBits2Float(0x00000000), SkBits2Float(0x43bd6720), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 378.806f, 0, 378.806f, 50, 0.707107f -path.conicTo(SkBits2Float(0x43bd6720), SkBits2Float(0x42c80000), SkBits2Float(0x43d66720), SkBits2Float(0x42c80000), SkBits2Float(0x3f3504f3)); // 378.806f, 100, 428.806f, 100, 0.707107f -path.conicTo(SkBits2Float(0x43ef6720), SkBits2Float(0x42c80000), SkBits2Float(0x43ef6720), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 478.806f, 100, 478.806f, 50, 0.707107f -path.close(); - - testSimplify(reporter, path, filename); -} - -static void fuzz763_4713_b(skiatest::Reporter* reporter, const char* filename) { - SkPath path; - path.setFillType((SkPath::FillType) 0); -path.moveTo(SkBits2Float(0x42240000), SkBits2Float(0x42040000)); -path.quadTo(SkBits2Float(0x42240000), SkBits2Float(0x4211413d), SkBits2Float(0x421aa09e), SkBits2Float(0x421aa09e)); -path.quadTo(SkBits2Float(0x4211413d), SkBits2Float(0x42240000), SkBits2Float(0x42040000), SkBits2Float(0x42240000)); -path.quadTo(SkBits2Float(0x41ed7d86), SkBits2Float(0x42240000), SkBits2Float(0x41dabec3), SkBits2Float(0x421aa09e)); -path.quadTo(SkBits2Float(0x41c80000), SkBits2Float(0x4211413d), SkBits2Float(0x41c80000), SkBits2Float(0x42040000)); -path.quadTo(SkBits2Float(0x41c80000), SkBits2Float(0x41ed7d86), SkBits2Float(0x41dabec3), SkBits2Float(0x41dabec3)); -path.quadTo(SkBits2Float(0x41ed7d86), SkBits2Float(0x41c80000), SkBits2Float(0x42040000), SkBits2Float(0x41c80000)); -path.quadTo(SkBits2Float(0x4211413d), SkBits2Float(0x41c80000), SkBits2Float(0x421aa09e), SkBits2Float(0x41dabec3)); -path.quadTo(SkBits2Float(0x42240000), SkBits2Float(0x41ed7d86), SkBits2Float(0x42240000), SkBits2Float(0x42040000)); -path.close(); - -path.moveTo(SkBits2Float(0x4204f72e), SkBits2Float(0x41c56cd2)); -path.quadTo(SkBits2Float(0x42123842), SkBits2Float(0x41c52adf), SkBits2Float(0x421baed7), SkBits2Float(0x41d7bac6)); -path.quadTo(SkBits2Float(0x4225256d), SkBits2Float(0x41ea4aad), SkBits2Float(0x42254667), SkBits2Float(0x4202666b)); -path.quadTo(SkBits2Float(0x42256760), SkBits2Float(0x420fa77f), SkBits2Float(0x421c1f6c), SkBits2Float(0x42191e14)); -path.quadTo(SkBits2Float(0x421bff97), SkBits2Float(0x42193e89), SkBits2Float(0x421bdf6b), SkBits2Float(0x42195eb8)); -path.quadTo(SkBits2Float(0x421bbff6), SkBits2Float(0x42197f32), SkBits2Float(0x421ba03b), SkBits2Float(0x42199f57)); -path.quadTo(SkBits2Float(0x421b605e), SkBits2Float(0x4219e00a), SkBits2Float(0x421b1fa8), SkBits2Float(0x421a1f22)); -path.quadTo(SkBits2Float(0x421ae0f1), SkBits2Float(0x421a604b), SkBits2Float(0x421aa09e), SkBits2Float(0x421aa09e)); -path.quadTo(SkBits2Float(0x4211413d), SkBits2Float(0x42240000), SkBits2Float(0x42040000), SkBits2Float(0x42240000)); -path.quadTo(SkBits2Float(0x41ed7d86), SkBits2Float(0x42240000), SkBits2Float(0x41dabec3), SkBits2Float(0x421aa09e)); -path.quadTo(SkBits2Float(0x41c80000), SkBits2Float(0x4211413d), SkBits2Float(0x41c80000), SkBits2Float(0x42040000)); -path.quadTo(SkBits2Float(0x41c80000), SkBits2Float(0x41ed7d86), SkBits2Float(0x41dabec3), SkBits2Float(0x41dabec3)); -path.quadTo(SkBits2Float(0x41db19b1), SkBits2Float(0x41da63d5), SkBits2Float(0x41db755b), SkBits2Float(0x41da0a9b)); -path.quadTo(SkBits2Float(0x41dbce01), SkBits2Float(0x41d9ae59), SkBits2Float(0x41dc285e), SkBits2Float(0x41d952ce)); -path.quadTo(SkBits2Float(0x41dc55b6), SkBits2Float(0x41d924df), SkBits2Float(0x41dc82cd), SkBits2Float(0x41d8f7cd)); -path.quadTo(SkBits2Float(0x41dcaf1e), SkBits2Float(0x41d8ca01), SkBits2Float(0x41dcdc4c), SkBits2Float(0x41d89bf0)); -path.quadTo(SkBits2Float(0x41ef6c33), SkBits2Float(0x41c5aec5), SkBits2Float(0x4204f72e), SkBits2Float(0x41c56cd2)); -path.close(); -testSimplify(reporter, path, filename); -} - -static void fuzz864a(skiatest::Reporter* reporter,const char* filename) { - SkPath path; - path.moveTo(10, 90); - path.lineTo(10, 90); - path.lineTo(10, 30); - path.lineTo(10, 30); - path.lineTo(10, 90); - path.close(); - path.moveTo(10, 90); - path.lineTo(10, 90); - path.lineTo(10, 30); - path.lineTo(10, 30); - path.lineTo(10, 90); - path.close(); - path.moveTo(10, 90); - path.lineTo(110, 90); - path.lineTo(110, 30); - path.lineTo(10, 30); - path.lineTo(10, 90); - path.close(); - path.moveTo(10, 30); - path.lineTo(32678, 30); - path.lineTo(32678, 30); - path.lineTo(10, 30); - path.close(); - path.moveTo(10, 3.35545e+07f); - path.lineTo(110, 3.35545e+07f); - path.lineTo(110, 30); - path.lineTo(10, 30); - path.lineTo(10, 3.35545e+07f); - path.close(); - path.moveTo(10, 315); - path.lineTo(110, 315); - path.lineTo(110, 255); - path.lineTo(10, 255); - path.lineTo(10, 315); - path.close(); - path.moveTo(0, 60); - path.lineTo(100, 60); - path.lineTo(100, 0); - path.lineTo(0, 0); - path.lineTo(0, 60); - path.close(); - path.moveTo(10, 90); - path.lineTo(110, 90); - path.lineTo(110, 30); - path.lineTo(10, 30); - path.lineTo(10, 90); - path.close(); - path.moveTo(10, 3.35545e+07f); - path.lineTo(110, 3.35545e+07f); - path.lineTo(110, 30); - path.lineTo(10, 30); - path.lineTo(10, 3.35545e+07f); - path.close(); - path.moveTo(10, 90); - path.lineTo(110, 90); - path.lineTo(110, 30); - path.lineTo(10, 30); - path.lineTo(10, 90); - path.close(); - testSimplifyFuzz(reporter, path, filename); -} - #define TEST(test) test(reporter, #test) DEF_TEST(PathOpsSimplifyFail, reporter) { - TEST(fuzz864a); - TEST(fuzz763_4713_b); - TEST(fuzz994s_3414); - TEST(fuzz994s_11); - TEST(fuzz_twister2); - TEST(fuzz_twister); TEST(fuzz763_2); TEST(fuzz763_1); TEST(fuzz_x2); diff --git a/tests/PathOpsSimplifyTest.cpp b/tests/PathOpsSimplifyTest.cpp index 7daa5e0..2de67ff 100644 --- a/tests/PathOpsSimplifyTest.cpp +++ b/tests/PathOpsSimplifyTest.cpp @@ -4871,7 +4871,7 @@ static void fuzz864a(skiatest::Reporter* reporter,const char* filename) { path.lineTo(10, 30); path.lineTo(10, 90); path.close(); - testSimplifyFuzz(reporter, path, filename); + testSimplify(reporter, path, filename); } static void cr514118(skiatest::Reporter* reporter,const char* filename) { @@ -4954,7 +4954,7 @@ path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30 path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90 path.close(); - testSimplifyFuzz(reporter, path, filename); + testSimplify(reporter, path, filename); } static void fuzz994s_3414(skiatest::Reporter* reporter, const char* filename) { @@ -5021,7 +5021,7 @@ path.lineTo(3.35546e+07f, 0); path.lineTo(123, 0); path.lineTo(123, 600); path.close(); - testSimplifyFuzz(reporter, path, filename); + testSimplify(reporter, path, filename); } static void fuzz_twister2(skiatest::Reporter* reporter, const char* filename) { @@ -6919,6 +6919,8 @@ testSimplify(reporter, path, filename); } static void joel_9(skiatest::Reporter* reporter, const char* filename) { +#if DEBUG_UNDER_DEVELOPMENT +// fails with image mismatch SkPath path; path.moveTo(SkBits2Float(0x4310dbe7), SkBits2Float(0x438e9604)); // 144.859f, 285.172f path.lineTo(SkBits2Float(0x4310dbe7), SkBits2Float(0x438e9604)); // 144.859f, 285.172f @@ -6971,10 +6973,13 @@ path.lineTo(SkBits2Float(0x430bbdf4), SkBits2Float(0x43898f1a)); // 139.742f, 2 path.cubicTo(SkBits2Float(0x430fefe0), SkBits2Float(0x438a3f1a), SkBits2Float(0x43123811), SkBits2Float(0x438c7d0e), SkBits2Float(0x4310dbe8), SkBits2Float(0x438e9624)); // 143.937f, 276.493f, 146.219f, 280.977f, 144.859f, 285.173f path.lineTo(SkBits2Float(0x430d67f0), SkBits2Float(0x438e070a)); // 141.406f, 284.055f path.close(); -testSimplifyTry(reporter, path, filename); +testSimplify(reporter, path, filename); +#endif } static void joel_10(skiatest::Reporter* reporter, const char* filename) { +#if DEBUG_UNDER_DEVELOPMENT +// fails with image mismatch SkPath path; path.moveTo(SkBits2Float(0x440fc979), SkBits2Float(0x43d88000)); // 575.148f, 433 path.lineTo(SkBits2Float(0x440fc979), SkBits2Float(0x43d88000)); // 575.148f, 433 @@ -7027,11 +7032,12 @@ path.lineTo(SkBits2Float(0x44111106), SkBits2Float(0x43dd86ea)); // 580.266f, 4 path.cubicTo(SkBits2Float(0x4410048b), SkBits2Float(0x43dcd7f0), SkBits2Float(0x440f720c), SkBits2Float(0x43da99dc), SkBits2Float(0x440fc989), SkBits2Float(0x43d87fe0)); // 576.071f, 441.687f, 573.782f, 437.202f, 575.149f, 432.999f path.lineTo(SkBits2Float(0x4410a687), SkBits2Float(0x43d91000)); // 578.602f, 434.125f path.close(); -// DEBUG_UNDER_DEVELOPMENT fails with angle instability -testSimplifyFuzz(reporter, path, filename); +testSimplify(reporter, path, filename); +#endif } static void joel_11(skiatest::Reporter* reporter, const char* filename) { +#if DEBUG_UNDER_DEVELOPMENT // fails with image mismatch SkPath path; path.moveTo(SkBits2Float(0x43c9d000), SkBits2Float(0x4411977d)); // 403.625f, 582.367f @@ -7086,7 +7092,8 @@ path.lineTo(SkBits2Float(0x43c6bd0e), SkBits2Float(0x4413f591)); // 397.477f, 5 path.cubicTo(SkBits2Float(0x43c64810), SkBits2Float(0x4412e116), SkBits2Float(0x43c7a70a), SkBits2Float(0x4411d28f), SkBits2Float(0x43c9d000), SkBits2Float(0x4411978d)); // 396.563f, 587.517f, 399.305f, 583.29f, 403.625f, 582.368f path.lineTo(SkBits2Float(0x43ca3106), SkBits2Float(0x44127b02)); // 404.383f, 585.922f path.close(); -testSimplifyFuzz(reporter, path, filename); +testSimplify(reporter, path, filename); +#endif } static void make_joel_12(SkPath& path) { diff --git a/tests/skia_test.cpp b/tests/skia_test.cpp index 969c1ff..4cb55d0 100644 --- a/tests/skia_test.cpp +++ b/tests/skia_test.cpp @@ -29,6 +29,7 @@ using namespace sk_gpu_test; DEFINE_bool2(dumpOp, d, false, "dump the pathOps to a file to recover mid-crash."); DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps."); +DEFINE_bool2(runFail, f, false, "check for success on tests known to fail."); DEFINE_bool2(verifyOp, y, false, "compare the pathOps result against a region."); #if DEBUG_COIN @@ -140,6 +141,7 @@ int test_main() { SkPathOpsDebug::gDumpOp = FLAGS_dumpOp; SkPathOpsDebug::gVerifyOp = FLAGS_verifyOp; #endif + SkPathOpsDebug::gRunFail = FLAGS_runFail; SkPathOpsDebug::gVeryVerbose = FLAGS_veryVerbose; SetupCrashHandler(); @@ -169,6 +171,11 @@ int test_main() { if (FLAGS_dumpOp) { header.appendf(" -d"); } +#ifdef SK_DEBUG + if (FLAGS_runFail) { + header.appendf(" -f"); + } +#endif if (FLAGS_verbose) { header.appendf(" -v"); } diff --git a/tools/pathops_sorter.htm b/tools/pathops_sorter.htm index e31a196..967ac31 100644 --- a/tools/pathops_sorter.htm +++ b/tools/pathops_sorter.htm @@ -6,16 +6,28 @@
-
-ccwOf {{{380.294464,140.44487}, {379.597463,140.82048}}} id=1 -ccwOf {{{380.294495,140.444855}, {378.965302,141.103577}}} id=2 +
+{{{403.28299,497.196991}, {403.424011,497.243988}, {391.110992,495.556}, {391.110992,495.556}}} +{{{398.375,501.976013}, {403.28299,497.196991}}} +{{{403.42401123046875, 497.243988037109375}, {378.7979736328125, 493.868011474609375}}}, id=0 +{{{415.5605946972181641, 498.8838844379989155}, {378.8318672594865006, 493.8897667505245295}}}, id=1 +{{{403.2954048004600622, 497.117149457477467}, {403.2729768294798873, 497.2781265045034615}}}, id=2 +{{{403.42401123046875, 497.243988037109375}, {378.7979736328125, 493.868011474609375}}}, id=3 + +
+ +
+{{{403.28299f, 497.196991f}, {403.284241f, 497.197388f}, {403.28418f, 497.197632f}}} +{{{403.28418f, 497.197632f}, {403.280487f, 497.224304f}, {391.110992f, 495.556f}, {391.110992f, 495.556f}}} +