diff options
-rw-r--r-- | src/pathops/SkAddIntersections.cpp | 3 | ||||
-rwxr-xr-x | src/pathops/SkOpCoincidence.cpp | 3 | ||||
-rw-r--r-- | src/pathops/SkOpContour.cpp | 6 | ||||
-rw-r--r-- | src/pathops/SkOpContour.h | 2 | ||||
-rw-r--r-- | src/pathops/SkOpEdgeBuilder.cpp | 140 | ||||
-rw-r--r-- | src/pathops/SkOpSegment.cpp | 2 | ||||
-rw-r--r-- | src/pathops/SkPathOpsDebug.cpp | 2 | ||||
-rw-r--r-- | src/pathops/SkPathOpsDebug.h | 4 | ||||
-rw-r--r-- | src/pathops/SkPathOpsOp.cpp | 2 | ||||
-rw-r--r-- | src/pathops/SkPathOpsTSect.h | 3 | ||||
-rw-r--r-- | src/pathops/SkReduceOrder.cpp | 7 | ||||
-rw-r--r-- | src/pathops/SkReduceOrder.h | 4 | ||||
-rw-r--r-- | tests/PathOpsConicLineIntersectionTest.cpp | 5 | ||||
-rw-r--r-- | tests/PathOpsCubicIntersectionTest.cpp | 5 | ||||
-rw-r--r-- | tests/PathOpsOpTest.cpp | 22 | ||||
-rw-r--r-- | tests/PathOpsQuadIntersectionTest.cpp | 3 | ||||
-rw-r--r-- | tests/PathOpsSimplifyFailTest.cpp | 2 | ||||
-rw-r--r-- | tests/PathOpsSimplifyTest.cpp | 8 | ||||
-rw-r--r-- | tests/PathOpsThreeWayTest.cpp | 2 | ||||
-rw-r--r-- | tools/pathops_sorter.htm | 33 | ||||
-rw-r--r-- | tools/pathops_visualizer.htm | 226 |
21 files changed, 329 insertions, 155 deletions
diff --git a/src/pathops/SkAddIntersections.cpp b/src/pathops/SkAddIntersections.cpp index 2abf67a09d..b3a82cdeca 100644 --- a/src/pathops/SkAddIntersections.cpp +++ b/src/pathops/SkAddIntersections.cpp @@ -542,7 +542,8 @@ bool AddIntersectTs(SkOpContour* test, SkOpContour* next, SkOpCoincidence* coinc SkTSwap(coinPtT[0], coinPtT[1]); SkTSwap(testTAt, nextTAt); } - SkASSERT(coinPtT[0]->span()->t() < testTAt->span()->t()); + SkASSERT(coincidence->globalState()->debugSkipAssert() + || coinPtT[0]->span()->t() < testTAt->span()->t()); if (coinPtT[0]->span()->deleted()) { coinIndex = -1; continue; diff --git a/src/pathops/SkOpCoincidence.cpp b/src/pathops/SkOpCoincidence.cpp index 1bbb82a9e0..d2874c3c5e 100755 --- a/src/pathops/SkOpCoincidence.cpp +++ b/src/pathops/SkOpCoincidence.cpp @@ -334,6 +334,9 @@ bool SkOpCoincidence::addEndMovedSpans(const SkOpSpan* base, const SkOpSpanBase* } SkOpSegment* writableSeg = const_cast<SkOpSegment*>(testSeg); SkOpPtT* oppStart = writableSeg->addT(t); + if (oppStart == testPtT) { + continue; + } SkOpSpan* writableBase = const_cast<SkOpSpan*>(base); oppStart->span()->addOpp(writableBase); if (oppStart->deleted()) { diff --git a/src/pathops/SkOpContour.cpp b/src/pathops/SkOpContour.cpp index 3b2318c306..981bd29573 100644 --- a/src/pathops/SkOpContour.cpp +++ b/src/pathops/SkOpContour.cpp @@ -10,7 +10,7 @@ #include "SkReduceOrder.h" #include "SkTSort.h" -SkOpSegment* SkOpContour::addCurve(SkPath::Verb verb, const SkPoint pts[4]) { +SkOpSegment* SkOpContour::addCurve(SkPath::Verb verb, const SkPoint pts[4], SkScalar weight) { SkChunkAlloc* allocator = this->globalState()->allocator(); switch (verb) { case SkPath::kLine_Verb: { @@ -24,7 +24,9 @@ SkOpSegment* SkOpContour::addCurve(SkPath::Verb verb, const SkPoint pts[4]) { return appendSegment().addQuad(ptStorage, this); } break; case SkPath::kConic_Verb: { - SkASSERT(0); // the original curve is a cubic, which will never reduce to a conic + SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3); + memcpy(ptStorage, pts, sizeof(SkPoint) * 3); + return appendSegment().addConic(ptStorage, weight, this); } break; case SkPath::kCubic_Verb: { SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 4); diff --git a/src/pathops/SkOpContour.h b/src/pathops/SkOpContour.h index acc6744f2a..4390fe4e1f 100644 --- a/src/pathops/SkOpContour.h +++ b/src/pathops/SkOpContour.h @@ -41,7 +41,7 @@ public: appendSegment().addCubic(pts, this); } - SkOpSegment* addCurve(SkPath::Verb verb, const SkPoint pts[4]); + SkOpSegment* addCurve(SkPath::Verb verb, const SkPoint pts[4], SkScalar weight = 1); SkOpSegment* addLine(SkPoint pts[2]) { SkASSERT(pts[0] != pts[1]); diff --git a/src/pathops/SkOpEdgeBuilder.cpp b/src/pathops/SkOpEdgeBuilder.cpp index 36fc9ed161..d67ed44ddc 100644 --- a/src/pathops/SkOpEdgeBuilder.cpp +++ b/src/pathops/SkOpEdgeBuilder.cpp @@ -17,6 +17,26 @@ void SkOpEdgeBuilder::init() { fSecondHalf = preFetch(); } +// very tiny points cause numerical instability : don't allow them +static void force_small_to_zero(SkPoint* pt) { + if (SkScalarAbs(pt->fX) < FLT_EPSILON_ORDERABLE_ERR) { + pt->fX = 0; + } + if (SkScalarAbs(pt->fY) < FLT_EPSILON_ORDERABLE_ERR) { + pt->fY = 0; + } +} + +static bool can_add_curve(SkPath::Verb verb, SkPoint* curve) { + if (SkPath::kMove_Verb == verb) { + return false; + } + for (int index = 0; index < SkPathOpsVerbToPoints(verb); ++index) { + force_small_to_zero(&curve[index]); + } + return SkPath::kLine_Verb != verb || !SkDPoint::ApproximatelyEqual(curve[0], curve[1]); +} + void SkOpEdgeBuilder::addOperand(const SkPath& path) { SkASSERT(fPathVerbs.count() > 0 && fPathVerbs.end()[-1] == SkPath::kDone_Verb); fPathVerbs.pop(); @@ -48,16 +68,6 @@ void SkOpEdgeBuilder::closeContour(const SkPoint& curveEnd, const SkPoint& curve *fPathVerbs.append() = SkPath::kClose_Verb; } -// very tiny points cause numerical instability : don't allow them -static void force_small_to_zero(SkPoint* pt) { - if (SkScalarAbs(pt->fX) < FLT_EPSILON_ORDERABLE_ERR) { - pt->fX = 0; - } - if (SkScalarAbs(pt->fY) < FLT_EPSILON_ORDERABLE_ERR) { - pt->fY = 0; - } -} - int SkOpEdgeBuilder::preFetch() { if (!fPath->isFinite()) { fUnparseable = true; @@ -107,8 +117,10 @@ int SkOpEdgeBuilder::preFetch() { force_small_to_zero(&pts[2]); curve[1] = pts[1]; curve[2] = pts[2]; - verb = SkReduceOrder::Conic(curve, iter.conicWeight(), pts); - if (verb == SkPath::kMove_Verb) { + verb = SkReduceOrder::Quad(curve, pts); + if (SkPath::kQuad_Verb == verb && 1 != iter.conicWeight()) { + verb = SkPath::kConic_Verb; + } else if (verb == SkPath::kMove_Verb) { continue; // skip degenerate points } break; @@ -183,49 +195,83 @@ bool SkOpEdgeBuilder::walk() { fCurrentContour->addLine(pointsPtr); break; case SkPath::kQuad_Verb: - fCurrentContour->addQuad(pointsPtr); - break; - case SkPath::kConic_Verb: - fCurrentContour->addConic(pointsPtr, *weightPtr++); - break; - case SkPath::kCubic_Verb: { - // Split complex cubics (such as self-intersecting curves or - // ones with difficult curvature) in two before proceeding. - // This can be required for intersection to succeed. - SkScalar splitT; - if (SkDCubic::ComplexBreak(pointsPtr, &splitT)) { - SkPoint cubicPair[7]; - SkChopCubicAt(pointsPtr, cubicPair, splitT); - if (!SkScalarsAreFinite(&cubicPair[0].fX, SK_ARRAY_COUNT(cubicPair) * 2)) { - return false; - } - SkPoint cStorage[2][4]; - SkPath::Verb v1 = SkReduceOrder::Cubic(&cubicPair[0], cStorage[0]); - SkPath::Verb v2 = SkReduceOrder::Cubic(&cubicPair[3], cStorage[1]); - if (v1 != SkPath::kMove_Verb && v2 != SkPath::kMove_Verb) { - SkPoint* curve1 = v1 == SkPath::kCubic_Verb ? &cubicPair[0] : cStorage[0]; - SkPoint* curve2 = v2 == SkPath::kCubic_Verb ? &cubicPair[3] : cStorage[1]; - for (int index = 0; index < SkPathOpsVerbToPoints(v1); ++index) { - force_small_to_zero(&curve1[index]); + { + SkVector v1 = pointsPtr[1] - pointsPtr[0]; + SkVector v2 = pointsPtr[2] - pointsPtr[1]; + if (v1.dot(v2) < 0) { + SkPoint pair[5]; + if (SkChopQuadAtMaxCurvature(pointsPtr, pair) == 1) { + goto addOneQuad; } - for (int index = 0; index < SkPathOpsVerbToPoints(v2); ++index) { - force_small_to_zero(&curve2[index]); + if (!SkScalarsAreFinite(&pair[0].fX, SK_ARRAY_COUNT(pair) * 2)) { + return false; } - if (SkPath::kLine_Verb != v1 || - !SkDPoint::ApproximatelyEqual(curve1[0], curve1[1])) { + SkPoint cStorage[2][2]; + SkPath::Verb v1 = SkReduceOrder::Quad(&pair[0], cStorage[0]); + SkPath::Verb v2 = SkReduceOrder::Quad(&pair[2], cStorage[1]); + SkPoint* curve1 = v1 == SkPath::kQuad_Verb ? &pair[0] : cStorage[0]; + SkPoint* curve2 = v2 == SkPath::kQuad_Verb ? &pair[2] : cStorage[1]; + if (can_add_curve(v1, curve1) && can_add_curve(v2, curve2)) { fCurrentContour->addCurve(v1, curve1); - } - if (SkPath::kLine_Verb != v2 || - !SkDPoint::ApproximatelyEqual(curve2[0], curve2[1])) { fCurrentContour->addCurve(v2, curve2); + break; } - } else { - fCurrentContour->addCubic(pointsPtr); } - } else { - fCurrentContour->addCubic(pointsPtr); } + addOneQuad: + fCurrentContour->addQuad(pointsPtr); + break; + case SkPath::kConic_Verb: { + SkVector v1 = pointsPtr[1] - pointsPtr[0]; + SkVector v2 = pointsPtr[2] - pointsPtr[1]; + SkScalar weight = *weightPtr++; + if (v1.dot(v2) < 0) { + // FIXME: max curvature for conics hasn't been implemented; use placeholder + SkScalar maxCurvature = SkFindQuadMaxCurvature(pointsPtr); + if (maxCurvature > 0) { + SkConic conic(pointsPtr, weight); + SkConic pair[2]; + conic.chopAt(maxCurvature, pair); + SkPoint cStorage[2][3]; + SkPath::Verb v1 = SkReduceOrder::Conic(pair[0], cStorage[0]); + SkPath::Verb v2 = SkReduceOrder::Conic(pair[1], cStorage[1]); + SkPoint* curve1 = v1 == SkPath::kConic_Verb ? pair[0].fPts : cStorage[0]; + SkPoint* curve2 = v2 == SkPath::kConic_Verb ? pair[1].fPts : cStorage[1]; + if (can_add_curve(v1, curve1) && can_add_curve(v2, curve2)) { + fCurrentContour->addCurve(v1, curve1, pair[0].fW); + fCurrentContour->addCurve(v2, curve2, pair[1].fW); + break; + } + } + } + fCurrentContour->addConic(pointsPtr, weight); } break; + case SkPath::kCubic_Verb: + { + // Split complex cubics (such as self-intersecting curves or + // ones with difficult curvature) in two before proceeding. + // This can be required for intersection to succeed. + SkScalar splitT; + if (SkDCubic::ComplexBreak(pointsPtr, &splitT)) { + SkPoint pair[7]; + SkChopCubicAt(pointsPtr, pair, splitT); + if (!SkScalarsAreFinite(&pair[0].fX, SK_ARRAY_COUNT(pair) * 2)) { + return false; + } + SkPoint cStorage[2][4]; + SkPath::Verb v1 = SkReduceOrder::Cubic(&pair[0], cStorage[0]); + SkPath::Verb v2 = SkReduceOrder::Cubic(&pair[3], cStorage[1]); + SkPoint* curve1 = v1 == SkPath::kCubic_Verb ? &pair[0] : cStorage[0]; + SkPoint* curve2 = v2 == SkPath::kCubic_Verb ? &pair[3] : cStorage[1]; + if (can_add_curve(v1, curve1) && can_add_curve(v2, curve2)) { + fCurrentContour->addCurve(v1, curve1); + fCurrentContour->addCurve(v2, curve2); + break; + } + } + } + fCurrentContour->addCubic(pointsPtr); + break; case SkPath::kClose_Verb: SkASSERT(fCurrentContour); if (!close()) { diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp index 1a965c2474..9ab240d2cb 100644 --- a/src/pathops/SkOpSegment.cpp +++ b/src/pathops/SkOpSegment.cpp @@ -249,7 +249,7 @@ SkOpPtT* SkOpSegment::addT(double t) { SkOpSpanBase* spanBase = &fHead; do { SkOpPtT* result = spanBase->ptT(); - if (t == result->fT || this->match(result, this, t, pt)) { + if (t == result->fT || (!zero_or_one(t) && this->match(result, this, t, pt))) { spanBase->bumpSpanAdds(); return result; } diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp index 67bcee4070..5326addf8d 100644 --- a/src/pathops/SkPathOpsDebug.cpp +++ b/src/pathops/SkPathOpsDebug.cpp @@ -1876,7 +1876,7 @@ static void DebugValidate(const SkOpSpanBase* next, const SkOpSpanBase* end, do { const SkOpPtT* ptT = next->ptT(); int index = 0; - bool somethingBetween; + bool somethingBetween = false; do { ++index; ptT = ptT->next(); diff --git a/src/pathops/SkPathOpsDebug.h b/src/pathops/SkPathOpsDebug.h index e390b91b56..f0e384a7e3 100644 --- a/src/pathops/SkPathOpsDebug.h +++ b/src/pathops/SkPathOpsDebug.h @@ -19,6 +19,8 @@ #define FORCE_RELEASE 1 // set force release to 1 for multiple thread -- no debugging #endif +#define DEBUG_UNDER_DEVELOPMENT 1 + #define ONE_OFF_DEBUG 0 #define ONE_OFF_DEBUG_MATHEMATICA 0 @@ -37,8 +39,6 @@ if (!SkPathOpsDebug::ValidWind(x)) strcpy(x##Str, "?"); \ else SK_SNPRINTF(x##Str, sizeof(x##Str), "%d", x) -#define DEBUG_UNDER_DEVELOPMENT 1 - #if FORCE_RELEASE #define DEBUG_ACTIVE_OP 0 diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp index 0f4415bec1..d34c0579e4 100644 --- a/src/pathops/SkPathOpsOp.cpp +++ b/src/pathops/SkPathOpsOp.cpp @@ -207,7 +207,7 @@ static void dump_path(FILE* file, const SkPath& path, bool force, bool dumpAsHex SkDynamicMemoryWStream wStream; path.dump(&wStream, force, dumpAsHex); sk_sp<SkData> data(wStream.detachAsData()); - fprintf(file, "%.*s\n", (int) data->size(), data->data()); + fprintf(file, "%.*s\n", (int) data->size(), (char*) data->data()); } static int dumpID = 0; diff --git a/src/pathops/SkPathOpsTSect.h b/src/pathops/SkPathOpsTSect.h index 6ae6ee528f..f84aaaa6b7 100644 --- a/src/pathops/SkPathOpsTSect.h +++ b/src/pathops/SkPathOpsTSect.h @@ -1531,7 +1531,8 @@ int SkTSect<TCurve, OppCurve>::linesIntersect(SkTSpan<TCurve, OppCurve>* span, workT += tStep; workPt = fCurve.ptAtT(workT); coinW.setPerp(fCurve, workT, workPt, opp->fCurve); - if (coinW.perpT() < 0) { + double perpT = coinW.perpT(); + if (coinW.isCoincident() ? !between(oppSpan->fStartT, perpT, oppSpan->fEndT) : perpT < 0) { continue; } SkDVector perpW = workPt - coinW.perpPt(); diff --git a/src/pathops/SkReduceOrder.cpp b/src/pathops/SkReduceOrder.cpp index 48624baee9..7f7ea11d3b 100644 --- a/src/pathops/SkReduceOrder.cpp +++ b/src/pathops/SkReduceOrder.cpp @@ -4,6 +4,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +#include "SkGeometry.h" #include "SkReduceOrder.h" int SkReduceOrder::reduce(const SkDLine& line) { @@ -255,9 +256,9 @@ SkPath::Verb SkReduceOrder::Quad(const SkPoint a[3], SkPoint* reducePts) { return SkPathOpsPointsToVerb(order - 1); } -SkPath::Verb SkReduceOrder::Conic(const SkPoint a[3], SkScalar weight, SkPoint* reducePts) { - SkPath::Verb verb = SkReduceOrder::Quad(a, reducePts); - if (verb > SkPath::kLine_Verb && weight == 1) { +SkPath::Verb SkReduceOrder::Conic(const SkConic& c, SkPoint* reducePts) { + SkPath::Verb verb = SkReduceOrder::Quad(c.fPts, reducePts); + if (verb > SkPath::kLine_Verb && c.fW == 1) { return SkPath::kQuad_Verb; } return verb == SkPath::kQuad_Verb ? SkPath::kConic_Verb : verb; diff --git a/src/pathops/SkReduceOrder.h b/src/pathops/SkReduceOrder.h index e9e4090deb..7efb71d4fe 100644 --- a/src/pathops/SkReduceOrder.h +++ b/src/pathops/SkReduceOrder.h @@ -11,6 +11,8 @@ #include "SkPathOpsLine.h" #include "SkPathOpsQuad.h" +struct SkConic; + union SkReduceOrder { enum Quadratics { kNo_Quadratics, @@ -21,7 +23,7 @@ union SkReduceOrder { int reduce(const SkDLine& line); int reduce(const SkDQuad& quad); - static SkPath::Verb Conic(const SkPoint pts[3], SkScalar weight, SkPoint* reducePts); + static SkPath::Verb Conic(const SkConic& conic, SkPoint* reducePts); static SkPath::Verb Cubic(const SkPoint pts[4], SkPoint* reducePts); static SkPath::Verb Quad(const SkPoint pts[3], SkPoint* reducePts); diff --git a/tests/PathOpsConicLineIntersectionTest.cpp b/tests/PathOpsConicLineIntersectionTest.cpp index 62195060e9..ecc4a47f17 100644 --- a/tests/PathOpsConicLineIntersectionTest.cpp +++ b/tests/PathOpsConicLineIntersectionTest.cpp @@ -6,6 +6,7 @@ */ #include "PathOpsExtendedTest.h" #include "PathOpsTestCommon.h" +#include "SkGeometry.h" #include "SkIntersections.h" #include "SkPathOpsConic.h" #include "SkPathOpsLine.h" @@ -103,7 +104,9 @@ DEF_TEST(PathOpsConicLineIntersection, reporter) { SkPoint pts[3] = { conic.fPts.fPts[0].asSkPoint(), conic.fPts.fPts[1].asSkPoint(), conic.fPts.fPts[2].asSkPoint() }; SkPoint reduced[3]; - SkPath::Verb order1 = SkReduceOrder::Conic(pts, conic.fWeight, reduced); + SkConic floatConic; + floatConic.set(pts, conic.fWeight); + SkPath::Verb order1 = SkReduceOrder::Conic(floatConic, reduced); if (order1 != SkPath::kConic_Verb) { SkDebugf("%s [%d] conic verb=%d\n", __FUNCTION__, iIndex, order1); REPORTER_ASSERT(reporter, 0); diff --git a/tests/PathOpsCubicIntersectionTest.cpp b/tests/PathOpsCubicIntersectionTest.cpp index dd7a7f7e2f..9bf60b7e39 100644 --- a/tests/PathOpsCubicIntersectionTest.cpp +++ b/tests/PathOpsCubicIntersectionTest.cpp @@ -165,6 +165,9 @@ static const SkDCubic testSet[] = { const int testSetCount = (int) SK_ARRAY_COUNT(testSet); static const SkDCubic newTestSet[] = { +{ { { 130.0427549999999997, 11417.41309999999976 },{ 130.2331240000000037, 11418.3192999999992 },{ 131.0370790000000056, 11419 },{ 132, 11419 } } }, +{ { { 132, 11419 },{ 130.8954319999999996, 11419 },{ 130, 11418.10449999999946 },{ 130, 11417 } } }, + {{{1,3}, {-1.0564518,1.79032254}, {1.45265341,0.229448318}, {1.45381773,0.22913377}}}, {{{1.45381773,0.22913377}, {1.45425761,0.229014933}, {1.0967741,0.451612949}, {0,1}}}, @@ -698,7 +701,7 @@ DEF_TEST(PathOpsCubicCoinOneOff, reporter) { } DEF_TEST(PathOpsCubicIntersectionOneOff, reporter) { - newOneOff(reporter, 66, 70); + newOneOff(reporter, 0, 1); } DEF_TEST(PathOpsCubicIntersectionTestsOneOff, reporter) { diff --git a/tests/PathOpsOpTest.cpp b/tests/PathOpsOpTest.cpp index 8ff0079dd4..9bb3a0fbb6 100644 --- a/tests/PathOpsOpTest.cpp +++ b/tests/PathOpsOpTest.cpp @@ -5375,6 +5375,26 @@ static void cubicOp158(skiatest::Reporter* reporter, const char* filename) { testPathOp(reporter, path, pathB, kDifference_SkPathOp, filename); } +static void loop17(skiatest::Reporter* reporter, const char* filename) { + SkPath path, pathB; + path.moveTo(1, 2); + path.cubicTo(0, 3, -0.333333343f, 3.33333325f, 0.833333373f, 3.5f); + path.close(); + pathB.moveTo(0, 3); + pathB.cubicTo(-0.333333343f, 3.33333325f, 0.833333373f, 3.5f, 1, 2); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_SkPathOp, filename); +} + +static void circlesOp4(skiatest::Reporter* reporter, const char* filename) { + SkPath path, pathB; + path.setFillType(SkPath::kWinding_FillType); + path.addCircle(0, 1, 5, SkPath::kCW_Direction); + pathB.setFillType(SkPath::kWinding_FillType); + pathB.addCircle(0, 1, 0, SkPath::kCW_Direction); + testPathOp(reporter, path, pathB, kDifference_SkPathOp, filename); +} + static void (*skipTest)(skiatest::Reporter* , const char* filename) = 0; static void (*firstTest)(skiatest::Reporter* , const char* filename) = 0; static void (*stopTest)(skiatest::Reporter* , const char* filename) = 0; @@ -5382,6 +5402,8 @@ static void (*stopTest)(skiatest::Reporter* , const char* filename) = 0; #define TEST(name) { name, #name } static struct TestDesc tests[] = { + TEST(circlesOp4), + TEST(loop17), TEST(cubicOp158), TEST(loops_i1), TEST(loops_i2), diff --git a/tests/PathOpsQuadIntersectionTest.cpp b/tests/PathOpsQuadIntersectionTest.cpp index f01262201f..be3d5a86d1 100644 --- a/tests/PathOpsQuadIntersectionTest.cpp +++ b/tests/PathOpsQuadIntersectionTest.cpp @@ -53,6 +53,9 @@ static void standardTestCases(skiatest::Reporter* reporter) { } static const SkDQuad testSet[] = { +{{{-0.001019871095195412636, -0.008523519150912761688}, {-0.005396408028900623322, -0.005396373569965362549}, {-0.02855382487177848816, -0.02855364233255386353}}}, +{{{-0.004567248281091451645, -0.01482933573424816132}, {-0.01142475008964538574, -0.01140109263360500336}, {-0.02852955088019371033, -0.02847047336399555206}}}, + {{{1, 1}, {0, 2}, {3, 3}}}, {{{3, 0}, {0, 1}, {1, 2}}}, diff --git a/tests/PathOpsSimplifyFailTest.cpp b/tests/PathOpsSimplifyFailTest.cpp index 4da43b8532..0166a841fa 100644 --- a/tests/PathOpsSimplifyFailTest.cpp +++ b/tests/PathOpsSimplifyFailTest.cpp @@ -154,7 +154,7 @@ path.quadTo(SkBits2Float(0xe93ae9e9), SkBits2Float(0xe964b6e9), SkBits2Float(0x0 path.moveTo(SkBits2Float(0x64b6b6b6), SkBits2Float(0xe9e9e900)); // 2.69638e+22f, -3.53475e+25f path.quadTo(SkBits2Float(0xb6b6b6e9), SkBits2Float(0xb6b6b6b6), SkBits2Float(0xe9e9b6ce), SkBits2Float(0xe9e93ae9)); // -5.44532e-06f, -5.44529e-06f, -3.53179e+25f, -3.52447e+25f - testSimplify(reporter, path, filename); + testSimplifyFuzz(reporter, path, filename); } diff --git a/tests/PathOpsSimplifyTest.cpp b/tests/PathOpsSimplifyTest.cpp index 07e3720583..55f0447bae 100644 --- a/tests/PathOpsSimplifyTest.cpp +++ b/tests/PathOpsSimplifyTest.cpp @@ -5256,7 +5256,7 @@ static void tiger8a_h_1(skiatest::Reporter* reporter, const char* filename) { #if DEBUG_UNDER_DEVELOPMENT // tiger return; #endif - uint64_t testlines = 0x0000000a01900c00; // best so far: 0x0000001d14c14bb1; + uint64_t testlines = 0x0000000000002008; // best so far: 0x0000001d14c14bb1; tiger8a_x(reporter, filename, testlines); } @@ -5331,7 +5331,7 @@ static void tiger8b_h_1(skiatest::Reporter* reporter, const char* filename) { #if DEBUG_UNDER_DEVELOPMENT // tiger return; #endif - uint64_t testlines = 0x0000001000350204; // best so far: 0x0000000104080223 + uint64_t testlines = 0x000000201304b4a3; // best so far: 0x000000201304b4a3 tiger8b_x(reporter, filename, testlines); } @@ -5870,11 +5870,10 @@ static void testQuads73(skiatest::Reporter* reporter, const char* filename) { } static void (*skipTest)(skiatest::Reporter* , const char* filename) = 0; -static void (*firstTest)(skiatest::Reporter* , const char* filename) = tiger8b_h_1; +static void (*firstTest)(skiatest::Reporter* , const char* filename) = 0; static void (*stopTest)(skiatest::Reporter* , const char* filename) = 0; static TestDesc tests[] = { - TEST(testQuads73), TEST(tiger8a_h_1), TEST(tiger8a_h), TEST(tiger8a), @@ -5882,6 +5881,7 @@ static TestDesc tests[] = { TEST(tiger8b_h), TEST(tiger8b), TEST(tiger8), + TEST(testQuads73), TEST(testQuads72), TEST(testQuads71), TEST(testQuads70), diff --git a/tests/PathOpsThreeWayTest.cpp b/tests/PathOpsThreeWayTest.cpp index bf634f9f7e..6a93bfbc59 100644 --- a/tests/PathOpsThreeWayTest.cpp +++ b/tests/PathOpsThreeWayTest.cpp @@ -75,6 +75,6 @@ DEF_TEST(PathOpsThreeWay, reporter) { } DEF_TEST(PathOpsThreeWayOneOff, reporter) { - int index = 1; + int index = 0; testSetTest(reporter, index); } diff --git a/tools/pathops_sorter.htm b/tools/pathops_sorter.htm index 667e86dac4..0983b704dc 100644 --- a/tools/pathops_sorter.htm +++ b/tools/pathops_sorter.htm @@ -6,9 +6,30 @@ <title></title> <div style="height:0"> -<div id="lineconic"> -{{{{494.348663330078125, 224.583770751953125}, {494.365142822265625, 224.6331939697265625}, {494.37640380859375, 224.6840667724609375}}}, 0.998645842f}, -{{{494.371185302734375, 224.66168212890625}, {494.375213623046875, 224.6787261962890625}}}, +<div id="perp"> +{{{130.0427549999999997, 11417.41309999999976}, {130.2331240000000037, 11418.3192999999992}, {131.0370790000000056, 11419}, {132, 11419}}}, +{{{132, 11419}, {130.8954319999999996, 11419}, {130, 11418.10449999999946}, {130, 11417}}}, +</div> + +<div id="quads"> +{{{-0.001019871095195412636, -0.008523519150912761688}, {-0.005396408028900623322, -0.005396373569965362549}, {-0.02855382487177848816, -0.02855364233255386353}}}, +{{{-0.004567248281091451645, -0.01482933573424816132}, {-0.01142475008964538574, -0.01140109263360500336}, {-0.02852955088019371033, -0.02847047336399555206}}}, + </div> + +<div id="both"> +{{fX=0.000000000 fY=0.000000000 }, {fX=494.350159 fY=228.773712 }, {fX=493.191650 fY=226.887451 }} +{{fX=0.000000000 fY=0.000000000 } {fX=492.680206 fY=228.000900 } {fX=493.193817 fY=226.897568 } +{{fX=493.193817 fY=226.897568 } {fX=493.195557 fY=226.893829 } {fX=493.191650 fY=226.887451 } + </div> + +<div id="startguy"> +{{fX=0.000000000 fY=0.000000000 }, {fX=494.350159 fY=228.773712 }, {fX=493.191650 fY=226.887451 }} +{{fX=0.000000000 fY=0.000000000 }, {fX=494.350159 fY=228.773712 }, {fX=493.191650 fY=226.887451 }} + </div> + +<div id="splitted"> +{{fX=0.000000000 fY=0.000000000 } {fX=492.680206 fY=228.000900 } {fX=493.193817 fY=226.897568 } +{{fX=493.193817 fY=226.897568 } {fX=493.195557 fY=226.893829 } {fX=493.191650 fY=226.887451 } </div> </div> @@ -16,7 +37,11 @@ <script type="text/javascript"> var testDivs = [ - lineconic, + perp, + quads, + both, + startguy, + splitted ]; var decimal_places = 3; diff --git a/tools/pathops_visualizer.htm b/tools/pathops_visualizer.htm index 945a6a9e6c..5cec64f5bf 100644 --- a/tools/pathops_visualizer.htm +++ b/tools/pathops_visualizer.htm @@ -2,88 +2,150 @@ <head> <div height="0" hidden="true"> -<div id="tiger8b_h_1"> -seg=1 {{{{494.348663f, 224.583771f}, {494.365143f, 224.633194f}, {494.376404f, 224.684067f}}}, 0.998645842f} -seg=2 {{{494.376404f, 224.684067f}, {492.527069f, 224.218475f}, {492.952789f, 224.005585f}}} -seg=3 {{{492.952789f, 224.005585f}, {494.375336f, 224.679337f}, {494.376038f, 224.682449f}}} -seg=4 {{{494.376038f, 224.682449f}, {494.37619f, 224.68309f}}} -seg=5 {{{494.37619f, 224.68309f}, {494.634338f, 225.414886f}, {494.895874f, 225.840698f}}} -seg=6 {{{494.895874f, 225.840698f}, {494.348663f, 224.583771f}}} -debugShowConicQuadIntersection wtTs[0]=1 {{{{494.348663,224.583771}, {494.365143,224.633194}, {494.376404,224.684067}}}, 0.998645842} {{494.376404,224.684067}} wnTs[0]=0 {{{494.376404,224.684067}, {492.527069,224.218475}, {492.952789,224.005585}}} -id=1 1=(0,1) [4] id=2 4=(0.5,1) [1] -id=1 1=(0,1) [6] id=2 6=(0.75,1) [1] -id=1 3=(0.5,1) [6] id=2 6=(0.75,1) [3] -id=1 3=(0.5,1) [8] id=2 8=(0.875,1) [3] -id=1 5=(0.75,1) [8] id=2 8=(0.875,1) [5] -id=1 7=(0.875,1) [8] id=2 8=(0.875,1) [7] -id=1 7=(0.875,1) [10] id=2 10=(0.9375,1) [7] -id=1 (empty) id=2 (empty) -debugShowConicQuadIntersection no intersect {{{{494.348663,224.583771}, {494.365143,224.633194}, {494.376404,224.684067}}}, 0.998645842} {{{492.952789,224.005585}, {494.375336,224.679337}, {494.376038,224.682449}}} -debugShowConicLineIntersection wtTs[0]=0.988457533 {{{{494.348663,224.583771}, {494.365143,224.633194}, {494.376404,224.684067}}}, 0.998645842} {{494.376038,224.682449}} wnTs[0]=0 {{{494.376038,224.682449}, {494.37619,224.68309}}} -SkOpSegment::addT insert t=0.988457533 segID=1 spanID=13 -debugShowConicQuadIntersection no intersect {{{{494.348663,224.583771}, {494.365143,224.633194}, {494.376404,224.684067}}}, 0.998645842} {{{494.37619,224.68309}, {494.634338,225.414886}, {494.895874,225.840698}}} -debugShowConicLineIntersection wtTs[0]=0 {{{{494.348663,224.583771}, {494.365143,224.633194}, {494.376404,224.684067}}}, 0.998645842} {{494.348663,224.583771}} wnTs[0]=1 {{{494.895874,225.840698}, {494.348663,224.583771}}} -debugShowQuadIntersection wtTs[0]=1 {{{494.376404,224.684067}, {492.527069,224.218475}, {492.952789,224.005585}}} {{492.952789,224.005585}} wnTs[0]=0 {{{492.952789,224.005585}, {494.375336,224.679337}, {494.376038,224.682449}}} -debugShowQuadLineIntersection no intersect {{{494.376404,224.684067}, {492.527069,224.218475}, {492.952789,224.005585}}} {{{494.376038,224.682449}, {494.37619,224.68309}}} -id=1 1=(0,0.5) [2] id=2 2=(0,1) [1] -id=1 1=(0,0.25) [2] id=2 2=(0,1) [1] -id=1 (empty) id=2 (empty) -debugShowQuadIntersection no intersect {{{494.376404,224.684067}, {492.527069,224.218475}, {492.952789,224.005585}}} {{{494.37619,224.68309}, {494.634338,225.414886}, {494.895874,225.840698}}} -debugShowQuadLineIntersection no intersect {{{494.376404,224.684067}, {492.527069,224.218475}, {492.952789,224.005585}}} {{{494.895874,225.840698}, {494.348663,224.583771}}} -debugShowQuadLineIntersection wtTs[0]=1 {{{492.952789,224.005585}, {494.375336,224.679337}, {494.376038,224.682449}}} {{494.376038,224.682449}} wnTs[0]=0 {{{494.376038,224.682449}, {494.37619,224.68309}}} -debugShowQuadLineIntersection no intersect {{{492.952789,224.005585}, {494.375336,224.679337}, {494.376038,224.682449}}} {{{494.895874,225.840698}, {494.348663,224.583771}}} -debugShowQuadLineIntersection wtTs[0]=0 {{{494.37619,224.68309}, {494.634338,225.414886}, {494.895874,225.840698}}} {{494.37619,224.68309}} wnTs[0]=1 {{{494.376038,224.682449}, {494.37619,224.68309}}} -debugShowLineIntersection no intersect {{{494.376038,224.682449}, {494.37619,224.68309}}} {{{494.895874,225.840698}, {494.348663,224.583771}}} -debugShowQuadLineIntersection wtTs[0]=1 {{{494.37619,224.68309}, {494.634338,225.414886}, {494.895874,225.840698}}} {{494.895874,225.840698}} wnTs[0]=0 {{{494.895874,225.840698}, {494.348663,224.583771}}} -SkOpSegment::markDone id=4 (494.376038,224.682449 494.37619,224.68309) t=0 [7] (494.376038,224.682449) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0 -SkOpSegment::sortAngles [1] tStart=0.988457533 [13] -SkOpAngle::after [1/1] 9/9 tStart=0.988457533 tEnd=0 < [3/3] 13/13 tStart=1 tEnd=0 < [1/2] 25/25 tStart=0.988457533 tEnd=1 T 4 -SkOpAngle::afterPart {{{{494.376038,224.682449}, {494.364861,224.63218}, {494.348663,224.583771}}}, 0.998676896} id=1 -SkOpAngle::afterPart {{{494.376038,224.682449}, {492.952789,224.005585}, {492.952789,224.005585}}} id=3 -SkOpAngle::afterPart {{{{494.376038,224.682449}, {494.376312,224.683624}, {494.376404,224.684067}}}, 0.999999821} id=1 +<div id="loop17"> +seg=1 {{{1, 2}, {0, 3}, {-0.333333343f, 3.33333325f}, {0.833333373f, 3.5f}}} +seg=2 {{{0.833333373f, 3.5f}, {1, 2}}} +op sect +seg=3 {{{0, 3}, {-0.333333343f, 3.33333325f}, {0.833333373f, 3.5f}, {1, 2}}} +seg=4 {{{1, 2}, {0, 3}}} +debugShowCubicLineIntersection wtTs[0]=0 {{{0,3}, {-0.333333343,3.33333325}, {0.833333373,3.5}, {1,2}}} {{0,3}} wtTs[1]=1 {{1,2}} wnTs[0]=1 {{{1,2}, {0,3}}} wnTs[1]=0 +id=1 1=(0,1) [4,2] id=2 2=(0,0.5) [1] 4=(0.5,1) [1] +id=1 1=(0,0.5) [4] 3=(0.5,1) [2,4] id=2 2=(0,0) [3] 4=(0.5,1) [3,1] +id=1 1=(0,0.5) [4] 3=(0.5,0.75) [4] 5=(1,1) [2] id=2 2=(0,0) [5] 4=(0.5,1) [3,1] +id=1 1=(0,0.5) [4] 5=(1,1) [2] id=2 2=(0,0) [5] 4=(0.5,0.75) [1] +id=1 7=(0.25,0.5) [4] 5=(1,1) [2] id=2 2=(0,0) [5] 4=(0.5,0.75) [7] +id=1 7=(0.25,0.375) [4] 9=(0.375,0.5) [4] 5=(1,1) [2] id=2 2=(0,0) [5] 4=(0.5,0.75) [9,7] +id=1 7=(0.25,0.375) [8,4] 5=(1,1) [2] id=2 2=(0,0) [5] 4=(0.5,0.625) [7] 8=(0.625,0.75) [7] +id=1 7=(0.25,0.375) [10,8] 5=(1,1) [2] id=2 2=(0,0) [5] 10=(0.5625,0.625) [7] 8=(0.625,0.75) [7] +id=1 11=(0.3125,0.375) [8] 5=(1,1) [2] id=2 2=(0,0) [5] 8=(0.625,0.75) [11] +id=1 11=(0.3125,0.375) [8] 5=(1,1) [2] id=2 2=(0,0) [5] 8=(0.625,0.6875) [11] +id=1 13=(0.34375,0.375) [8] 5=(1,1) [2] id=2 2=(0,0) [5] 8=(0.625,0.6875) [13] +id=1 13=(0.34375,0.375) [8] 5=(1,1) [2] id=2 2=(0,0) [5] 8=(0.625,0.65625) [13] +id=1 15=(0.359375,0.375) [8] 5=(1,1) [2] id=2 2=(0,0) [5] 8=(0.625,0.65625) [15] +id=1 15=(0.359375,0.375) [8] 5=(1,1) [2] id=2 2=(0,0) [5] 8=(0.625,0.640625) [15] +id=1 15=(0.359375,0.367188) [8] 17=(0.367188,0.375) [8] 5=(1,1) [2] id=2 2=(0,0) [5] 8=(0.625,0.640625) [17,15] +id=1 15=(0.359375,0.367188) [18] 5=(1,1) [2] id=2 2=(0,0) [5] 18=(0.632813,0.640625) [15] +id=1 19=(0.363281,0.367188) [18] 5=(1,1) [2] id=2 2=(0,0) [5] 18=(0.632813,0.640625) [19] +setPerp t=0.36328125 cPt=(0.110739922,3.22537946) != oppT=0.627603681 fPerpPt=(0.110965509,3.21864052) +setPerp t=0.3671875 cPt=(0.115765816,3.22551414) != oppT=0.636601379 fPerpPt=(0.115710094,3.22827643) +setPerp t=0.6328125 cPt=(0.113641506,3.22423955) != oppT=0.363729545 fPerpPt=(0.111313976,3.22539824) +setPerp t=0.63470694 cPt=(0.114662928,3.22626175) != oppT=0.367452497 fPerpPt=(0.116108709,3.2255209) +setPerp t=0.635654159 cPt=(0.115183291,3.22727003) != oppT=0.369275918 fPerpPt=(0.118474752,3.22555923) +setPerp t=0.636127769 cPt=(0.115445887,3.22777346) != oppT=0.370178237 fPerpPt=(0.119649848,3.22557288) +setPerp t=0.636364574 cPt=(0.115577789,3.228025) != oppT=0.370627065 fPerpPt=(0.120235406,3.22557836) +setPerp t=0.636482977 cPt=(0.115643891,3.22815073) != oppT=0.370850898 fPerpPt=(0.120527686,3.22558077) +setPerp t=0.636542178 cPt=(0.11567698,3.22821358) != oppT=0.370962669 fPerpPt=(0.120673701,3.22558189) +setPerp t=0.636571779 cPt=(0.115693534,3.22824501) != oppT=0.371018519 fPerpPt=(0.120746678,3.22558243) +setPerp t=0.636586579 cPt=(0.115701813,3.22826072) != oppT=0.371046435 fPerpPt=(0.120783158,3.22558269) +setPerp t=0.636593979 cPt=(0.115705954,3.22826857) != oppT=0.37106039 fPerpPt=(0.120801396,3.22558282) +setPerp t=0.636597679 cPt=(0.115708024,3.2282725) != oppT=0.371067368 fPerpPt=(0.120810515,3.22558289) +setPerp t=0.636599529 cPt=(0.115709059,3.22827446) != oppT=0.371070856 fPerpPt=(0.120815074,3.22558292) +setPerp t=0.636600454 cPt=(0.115709577,3.22827545) != oppT=0.3710726 fPerpPt=(0.120817354,3.22558294) +setPerp t=0.636600917 cPt=(0.115709835,3.22827594) != oppT=0.371073472 fPerpPt=(0.120818494,3.22558294) +setPerp t=0.636601148 cPt=(0.115709965,3.22827618) != oppT=0.371073908 fPerpPt=(0.120819063,3.22558295) +setPerp t=0.636601264 cPt=(0.11571003,3.2282763) != oppT=0.371074126 fPerpPt=(0.120819348,3.22558295) +setPerp t=0.636601322 cPt=(0.115710062,3.22827637) != oppT=0.371074235 fPerpPt=(0.120819491,3.22558295) +setPerp t=0.63660135 cPt=(0.115710078,3.2282764) != oppT=0.37107429 fPerpPt=(0.120819562,3.22558295) +setPerp t=0.636601365 cPt=(0.115710086,3.22827641) != oppT=0.371074317 fPerpPt=(0.120819598,3.22558295) +setPerp t=0.636601372 cPt=(0.11571009,3.22827642) != oppT=0.371074331 fPerpPt=(0.120819616,3.22558295) +setPerp t=0.636601376 cPt=(0.115710092,3.22827642) != oppT=0.371074338 fPerpPt=(0.120819624,3.22558295) +setPerp t=0.636601378 cPt=(0.115710093,3.22827643) != oppT=0.371074341 fPerpPt=(0.120819629,3.22558295) +setPerp t=0.636601378 cPt=(0.115710094,3.22827643) != oppT=0.371074343 fPerpPt=(0.120819631,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819632,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +setPerp t=0.636601379 cPt=(0.115710094,3.22827643) != oppT=0.371074344 fPerpPt=(0.120819633,3.22558295) +id=1 5=(1,1) [2] id=2 2=(0,0) [5] +debugShowCubicIntersection wtTs[0]=1 {{{0,3}, {-0.333333343,3.33333325}, {0.833333373,3.5}, {1,2}}} {{1,2}} wnTs[0]=0 {{{1,2}, {0,3}, {-0.333333343,3.33333325}, {0.833333373,3.5}}} +debugShowCubicLineIntersection wtTs[0]=1 {{{0,3}, {-0.333333343,3.33333325}, {0.833333373,3.5}, {1,2}}} {{1,2}} wnTs[0]=1 {{{0.833333373,3.5}, {1,2}}} +debugShowCubicLineIntersection wtTs[0]=0 {{{1,2}, {0,3}, {-0.333333343,3.33333325}, {0.833333373,3.5}}} {{1,2}} wnTs[0]=0 {{{1,2}, {0,3}}} +debugShowLineIntersection wtTs[0]=0 {{{1,2}, {0,3}}} {{1,2}} wnTs[0]=1 {{{0.833333373,3.5}, {1,2}}} +debugShowCubicLineIntersection wtTs[0]=0 {{{1,2}, {0,3}, {-0.333333343,3.33333325}, {0.833333373,3.5}}} {{1,2}} wtTs[1]=1 {{0.833333373,3.5}} wnTs[0]=1 {{{0.833333373,3.5}, {1,2}}} wnTs[1]=0 +----------------------------------- start +----------------------------------- addExpanded +----------------------------------- moveMultiples +----------------------------------- moveNearby +----------------------------------- addEndMovedSpans +----------------------------------- addMissing2 +----------------------------------- moveNearby2 +----------------------------------- expand2 +----------------------------------- addExpanded3 +----------------------------------- mark1 +----------------------------------- missingCoincidence2 +----------------------------------- missingCoincidence3 +----------------------------------- coincidence.reorder +----------------------------------- pairs->apply +----------------------------------- pairs->findOverlaps SkOpSegment::sortAngles [3] tStart=1 [6] -SkOpSegment::debugShowActiveSpans id=1 (494.348663,224.583771 494.364952,224.632623 494.376129,224.682892 0.998676896f) t=0 tEnd=0.988457533 windSum=? windValue=1 -SkOpSegment::debugShowActiveSpans id=1 (494.376129,224.682892 494.376274,224.68348 494.376404,224.684067 0.999999821f) t=0.988457533 tEnd=1 windSum=? windValue=1 -SkOpSegment::debugShowActiveSpans id=2 (494.376404,224.684067 492.527069,224.218475 492.952789,224.005585) t=0 tEnd=1 windSum=? windValue=1 -SkOpSegment::debugShowActiveSpans id=3 (492.952789,224.005585 494.375336,224.679337 494.376038,224.682449) t=0 tEnd=1 windSum=? windValue=1 -SkOpSegment::debugShowActiveSpans id=5 (494.37619,224.68309 494.634338,225.414886 494.895874,225.840698) t=0 tEnd=1 windSum=? windValue=1 -SkOpSegment::debugShowActiveSpans id=6 (494.895874,225.840698 494.348663,224.583771) t=0 tEnd=1 windSum=? windValue=1 -SkOpSpan::sortableTop dir=kLeft seg=1 t=0.494228767 pt=(494.363678,224.63298) -SkOpSpan::sortableTop [0] valid=1 operand=0 span=3 ccw=1 seg=2 {{{494.376404f, 224.684067f}, {492.527069f, 224.218475f}, {492.952789f, 224.005585f}}} t=0.0557039225 pt=(494.177429,224.63298) slope=(-1.72260523,-0.451515005) -SkOpSpan::sortableTop [1] valid=1 operand=0 span=5 ccw=0 seg=3 {{{492.952789f, 224.005585f}, {494.375336f, 224.679337f}, {494.376038f, 224.682449f}}} t=0.733006652 pt=(494.274292,224.63298) slope=(0.380324923,0.182168955) -SkOpSpan::sortableTop [2] valid=1 operand=0 span=1 ccw=0 seg=1 {{{{494.348663f, 224.583771f}, {494.365143f, 224.633194f}, {494.376404f, 224.684067f}}}, 0.998645842f} t=0.494228767 pt=(494.363678,224.63298) slope=(0.0138909232,0.050105697) -SkOpSegment::markWinding id=2 (494.376404,224.684067 492.527069,224.218475 492.952789,224.005585) t=0 [3] (494.376404,224.684067) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0 -SkOpSegment::markWinding id=3 (492.952789,224.005585 494.375336,224.679337 494.376038,224.682449) t=0 [5] (492.952789,224.005585) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0 -SkOpSegment::markWinding id=2 (494.376404,224.684067 492.527069,224.218475 492.952789,224.005585) t=0 [3] (494.376404,224.684067) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0 -SkOpSegment::markWinding id=1 (494.348663,224.583771 494.365143,224.633194 494.376404,224.684067) t=0.988457533 [13] (494.376129,224.682892) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0 -SkOpSegment::markWinding id=1 (494.348663,224.583771 494.365143,224.633194 494.376404,224.684067) t=0 [1] (494.348663,224.583771) tEnd=0.988457533 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0 -SkOpSegment::markWinding id=1 (494.348663,224.583771 494.365143,224.633194 494.376404,224.684067) t=0 [1] (494.348663,224.583771) tEnd=0.988457533 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0 -SkOpSegment::markWinding id=6 (494.895874,225.840698 494.348663,224.583771) t=0 [11] (494.895874,225.840698) tEnd=1 newWindSum=1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0 -SkOpSegment::markWinding id=5 (494.37619,224.68309 494.634338,225.414886 494.895874,225.840698) t=0 [9] (494.37619,224.68309) tEnd=1 newWindSum=1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0 -SkOpSegment::findNextWinding simple -SkOpSegment::markDone id=1 (494.348663,224.583771 494.365143,224.633194 494.376404,224.684067) t=0 [1] (494.348663,224.583771) tEnd=0.988457533 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0 -bridgeWinding current id=1 from=(494.376129,224.682892) to=(494.348663,224.583771) -path.moveTo(494.376129,224.682892); -path.conicTo(494.36496,224.632629, 494.348663,224.583771, 0.998676896); -SkOpSegment::findNextWinding simple -SkOpSegment::markDone id=6 (494.895874,225.840698 494.348663,224.583771) t=0 [11] (494.895874,225.840698) tEnd=1 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0 -bridgeWinding current id=6 from=(494.348663,224.583771) to=(494.895874,225.840698) -SkOpSegment::markDone id=5 (494.37619,224.68309 494.634338,225.414886 494.895874,225.840698) t=0 [9] (494.37619,224.68309) tEnd=1 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0 -path.lineTo(494.895874,225.840698); -SkOpSegment::debugShowActiveSpans id=1 (494.376129,224.682892 494.376274,224.68348 494.376404,224.684067 0.999999821f) t=0.988457533 tEnd=1 windSum=-1 oppSum=0 windValue=1 oppValue=0 -SkOpSegment::debugShowActiveSpans id=2 (494.376404,224.684067 492.527069,224.218475 492.952789,224.005585) t=0 tEnd=1 windSum=-1 oppSum=0 windValue=1 oppValue=0 -SkOpSegment::debugShowActiveSpans id=3 (492.952789,224.005585 494.375336,224.679337 494.376038,224.682449) t=0 tEnd=1 windSum=-1 oppSum=0 windValue=1 oppValue=0 -SkOpSegment::findNextWinding -SkOpAngle::dumpOne [1/2] next=1/1 sect=25/25 s=0.988457533 [13] e=1 [2] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=0 -SkOpAngle::dumpOne [1/1] next=3/3 sect=9/9 s=0.988457533 [13] e=0 [1] sgn=1 windVal=1 windSum=1 oppVal=0 oppSum=0 done -SkOpAngle::dumpOne [3/3] next=1/2 sect=13/13 s=1 [6] e=0 [5] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=0 -SkOpSegment::markDone id=3 (492.952789,224.005585 494.375336,224.679337 494.376038,224.682449) t=0 [5] (492.952789,224.005585) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0 -SkOpSegment::markDone id=2 (494.376404,224.684067 492.527069,224.218475 492.952789,224.005585) t=0 [3] (494.376404,224.684067) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0 -SkOpSegment::markDone id=1 (494.348663,224.583771 494.365143,224.633194 494.376404,224.684067) t=0.988457533 [13] (494.376129,224.682892) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0 -SkOpSegment::findNextWinding from:[1] to:[1] start=13259432 end=18937312 -bridgeWinding current id=1 from=(494.376404,224.684067) to=(494.376129,224.682892) -path.moveTo(494.376404,224.684067); -path.lineTo(494.376129,224.682892); +SkOpAngle::after [3/1] 21/20 tStart=1 tEnd=0 < [1/3] 20/21 tStart=0 tEnd=1 < [2/4] 21/21 tStart=1 tEnd=0 F 7 +SkOpAngle::afterPart {{{1,2}, {0.833333373,3.5}, {-0.333333343,3.33333325}, {0,3}}} id=3 +SkOpAngle::afterPart {{{1,2}, {0,3}, {-0.333333343,3.33333325}, {0.833333373,3.5}}} id=1 +SkOpAngle::afterPart {{{1,2}, {0.833333373,3.5}}} id=2 +SkOpAngle::after [3/1] 21/20 tStart=1 tEnd=0 < [4/2] 19/19 tStart=0 tEnd=1 < [2/4] 21/21 tStart=1 tEnd=0 F 5 +SkOpAngle::afterPart {{{1,2}, {0.833333373,3.5}, {-0.333333343,3.33333325}, {0,3}}} id=3 +SkOpAngle::afterPart {{{1,2}, {0,3}}} id=4 +SkOpAngle::afterPart {{{1,2}, {0.833333373,3.5}}} id=2 +SkOpAngle::after [2/4] 21/21 tStart=1 tEnd=0 < [4/2] 19/19 tStart=0 tEnd=1 < [1/3] 20/21 tStart=0 tEnd=1 T 5 +SkOpAngle::afterPart {{{1,2}, {0.833333373,3.5}}} id=2 +SkOpAngle::afterPart {{{1,2}, {0,3}}} id=4 +SkOpAngle::afterPart {{{1,2}, {0,3}, {-0.333333343,3.33333325}, {0.833333373,3.5}}} id=1 +SkOpSegment::sortAngles [4] tStart=0 [7] +SkOpSegment::sortAngles [1] tStart=0 [1] +SkOpSegment::sortAngles [2] tStart=1 [4] +SkOpSegment::debugShowActiveSpans id=3 (0,3 -0.333333343,3.33333325 0.833333373,3.5 1,2) t=0 tEnd=1 windSum=? windValue=1 +SkOpSegment::debugShowActiveSpans id=4 (1,2 0,3) t=0 tEnd=1 windSum=? windValue=1 +SkOpSegment::debugShowActiveSpans id=1 (1,2 0,3 -0.333333343,3.33333325 0.833333373,3.5) t=0 tEnd=1 windSum=? windValue=1 +SkOpSegment::debugShowActiveSpans id=2 (0.833333373,3.5 1,2) t=0 tEnd=1 windSum=? windValue=1 +SkOpSpan::sortableTop dir=kTop seg=3 t=0.5 pt=(0.3125,3.1875) +SkOpSpan::sortableTop [0] valid=1 operand=1 span=7 ccw=0 seg=4 {{{1, 2}, {0, 3}}} t=0.6875 pt=(0.3125,2.6875) slope=(-1,1) +SkOpSpan::sortableTop [1] valid=1 operand=0 span=1 ccw=0 seg=1 {{{1, 2}, {0, 3}, {-0.333333343f, 3.33333325f}, {0.833333373f, 3.5f}}} t=0.293719533 pt=(0.3125,2.72128606) slope=(-1.60944396,1.95452854) +SkOpSpan::sortableTop [2] valid=1 operand=1 span=5 ccw=1 seg=3 {{{0, 3}, {-0.333333343f, 3.33333325f}, {0.833333373f, 3.5f}, {1, 2}}} t=0.5 pt=(0.3125,3.1875) slope=(1.62500004,-0.62499994) +SkOpSegment::markWinding id=4 (1,2 0,3) t=0 [7] (1,2) tEnd=1 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0 +SkOpSegment::markWinding id=3 (0,3 -0.333333343,3.33333325 0.833333373,3.5 1,2) t=0 [5] (0,3) tEnd=1 newWindSum=1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0 +SkOpSegment::markWinding id=4 (1,2 0,3) t=0 [7] (1,2) tEnd=1 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0 +SkOpSegment::markWinding id=1 (1,2 0,3 -0.333333343,3.33333325 0.833333373,3.5) t=0 [1] (1,2) tEnd=1 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=0 +SkOpSegment::markWinding id=2 (0.833333373,3.5 1,2) t=0 [3] (0.833333373,3.5) tEnd=1 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=0 +SkOpSegment::markWinding id=1 (1,2 0,3 -0.333333343,3.33333325 0.833333373,3.5) t=0 [1] (1,2) tEnd=1 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=0 +SkOpSegment::activeOp id=3 t=1 tEnd=0 op=sect miFrom=0 miTo=0 suFrom=1 suTo=0 result=0 +SkOpSegment::markDone id=3 (0,3 -0.333333343,3.33333325 0.833333373,3.5 1,2) t=0 [5] (0,3) tEnd=1 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0 +SkOpSegment::markDone id=4 (1,2 0,3) t=0 [7] (1,2) tEnd=1 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0 +bridgeOp chase.append id=4 windSum=1 +SkOpSegment::debugShowActiveSpans id=1 (1,2 0,3 -0.333333343,3.33333325 0.833333373,3.5) t=0 tEnd=1 windSum=1 oppSum=1 windValue=1 oppValue=0 +SkOpSegment::debugShowActiveSpans id=2 (0.833333373,3.5 1,2) t=0 tEnd=1 windSum=1 oppSum=1 windValue=1 oppValue=0 +SkOpSegment::activeOp id=1 t=0 tEnd=1 op=sect miFrom=0 miTo=1 suFrom=1 suTo=1 result=1 +SkOpSegment::findNextOp simple +SkOpSegment::markDone id=1 (1,2 0,3 -0.333333343,3.33333325 0.833333373,3.5) t=0 [1] (1,2) tEnd=1 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=0 +bridgeOp current id=1 from=(1,2) to=(0.833333373,3.5) +path.moveTo(1,2); +path.cubicTo(0,3, -0.333333343,3.33333325, 0.833333373,3.5); +SkOpSegment::findNextOp +SkOpAngle::dumpOne [2/4] next=4/2 sect=21/21 s=1 [4] e=0 [3] sgn=1 windVal=1 windSum=1 oppVal=0 oppSum=1 +SkOpAngle::dumpOne [4/2] next=1/3 sect=19/19 s=0 [7] e=1 [8] sgn=-1 windVal=1 windSum=1 oppVal=0 oppSum=0 done operand +SkOpAngle::dumpOne [1/3] next=3/1 sect=20/21 s=0 [1] e=1 [2] sgn=-1 windVal=1 windSum=1 oppVal=0 oppSum=1 done +SkOpAngle::dumpOne [3/1] next=2/4 sect=21/20 s=1 [6] e=0 [5] sgn=1 windVal=1 windSum=1 oppVal=0 oppSum=0 done operand +SkOpSegment::activeOp id=4 t=0 tEnd=1 op=sect miFrom=0 miTo=0 suFrom=1 suTo=1 result=0 +SkOpSegment::activeOp id=1 t=0 tEnd=1 op=sect miFrom=0 miTo=1 suFrom=1 suTo=1 result=1 +SkOpSegment::activeOp id=3 t=1 tEnd=0 op=sect miFrom=1 miTo=1 suFrom=1 suTo=1 result=0 +SkOpSegment::markDone id=2 (0.833333373,3.5 1,2) t=0 [3] (0.833333373,3.5) tEnd=1 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=0 +SkOpSegment::findNextOp from:[2] to:[1] start=20180984 end=20181096 +bridgeOp current id=2 from=(0.833333373,3.5) to=(1,2) +path.lineTo(1,2); +path.close(); </div> </div> @@ -91,7 +153,7 @@ path.lineTo(494.376129,224.682892); <script type="text/javascript"> var testDivs = [ - tiger8b_h_1, + loop17, ]; var decimal_places = 3; // make this 3 to show more precision |