static const SimplifyFindNextTest::Segment* testCommon( int contourWinding, int spanWinding, int startIndex, int endIndex, SkTArray<SimplifyFindNextTest::Contour>& contours) { SkTDArray<SimplifyFindNextTest::Contour*> contourList; makeContourList(contours, contourList, false, false); addIntersectTs(contourList[0], contourList[0]); if (contours.count() > 1) { SkASSERT(contours.count() == 2); addIntersectTs(contourList[0], contourList[1]); addIntersectTs(contourList[1], contourList[1]); } fixOtherTIndex(contourList); SimplifyFindNextTest::Segment& segment = contours[0].debugSegments()[0]; SkPoint pts[2]; pts[0] = segment.xyAtT(&segment.span(endIndex)); int nextStart = startIndex; int nextEnd = endIndex; SkTDArray<SimplifyFindNextTest::Span*> chaseArray; bool unsortable = false; SimplifyFindNextTest::Segment* next = segment.findNextWinding(chaseArray, true, nextStart, nextEnd, contourWinding, spanWinding, unsortable); pts[1] = next->xyAtT(&next->span(nextStart)); SkASSERT(pts[0] == pts[1]); return next; }
void operate(const SkPath& one, const SkPath& two, ShapeOp op, SkPath& result) { result.reset(); result.setFillType(SkPath::kEvenOdd_FillType); // turn path into list of segments SkTArray<Op::Contour> contours; // FIXME: add self-intersecting cubics' T values to segment Op::EdgeBuilder builder(one, contours); const int aXorMask = builder.xorMask(); builder.addOperand(two); const int bXorMask = builder.xorMask(); builder.finish(); SkTDArray<Op::Contour*> contourList; makeContourList(contours, contourList); Op::Contour** currentPtr = contourList.begin(); if (!currentPtr) { return; } Op::Contour** listEnd = contourList.end(); // find all intersections between segments do { Op::Contour** nextPtr = currentPtr; Op::Contour* current = *currentPtr++; Op::Contour* next; do { next = *nextPtr++; } while (addIntersectTs(current, next) && nextPtr != listEnd); } while (currentPtr != listEnd); // eat through coincident edges coincidenceCheck(contourList); fixOtherTIndex(contourList); // construct closed contours Op::PathWrapper wrapper(result); bridgeOp(contourList, op, aXorMask, bXorMask, wrapper); }
static const SimplifyFindTopTest::Segment* testCommon( SkTArray<SimplifyFindTopTest::Contour>& contours, int& index, int& end) { SkTDArray<SimplifyFindTopTest::Contour*> contourList; makeContourList(contours, contourList, false, false); addIntersectTs(contourList[0], contourList[0]); if (contours.count() > 1) { SkASSERT(contours.count() == 2); addIntersectTs(contourList[0], contourList[1]); addIntersectTs(contourList[1], contourList[1]); } fixOtherTIndex(contourList); #if SORTABLE_CONTOURS // old way SimplifyFindTopTest::Segment* topStart = findTopContour(contourList); const SimplifyFindTopTest::Segment* topSegment = topStart->findTop(index, end); #else SkPoint bestXY = {SK_ScalarMin, SK_ScalarMin}; bool done, unsortable = false; const SimplifyFindTopTest::Segment* topSegment = findSortableTop(contourList, index, end, bestXY, unsortable, done, true); #endif return topSegment; }