SkPath makePath() { SkPath path; for (uint32_t cIndex = 0; cIndex < fPathContourCount; ++cIndex) { uint32_t segments = makeSegmentCount(); for (uint32_t sIndex = 0; sIndex < segments; ++sIndex) { RandomAddPath addPathType = makeAddPathType(); ++fAddCount; if (fPrintName) { SkDebugf("%.*s%s\n", fPathDepth * 3, fTab, gRandomAddPathNames[addPathType]); } switch (addPathType) { case kAddArc: { SkRect oval = makeRect(); SkScalar startAngle = makeAngle(); SkScalar sweepAngle = makeAngle(); path.addArc(oval, startAngle, sweepAngle); validate(path); } break; case kAddRoundRect1: { SkRect rect = makeRect(); SkScalar rx = makeScalar(), ry = makeScalar(); SkPath::Direction dir = makeDirection(); path.addRoundRect(rect, rx, ry, dir); validate(path); } break; case kAddRoundRect2: { SkRect rect = makeRect(); SkScalar radii[8]; makeScalarArray(SK_ARRAY_COUNT(radii), radii); SkPath::Direction dir = makeDirection(); path.addRoundRect(rect, radii, dir); validate(path); } break; case kAddRRect: { SkRRect rrect = makeRRect(); SkPath::Direction dir = makeDirection(); path.addRRect(rrect, dir); validate(path); } break; case kAddPoly: { SkTDArray<SkPoint> points; makePointArray(&points); bool close = makeBool(); path.addPoly(&points[0], points.count(), close); validate(path); } break; case kAddPath1: if (fPathDepth < fPathDepthLimit) { ++fPathDepth; SkPath src = makePath(); validate(src); SkScalar dx = makeScalar(); SkScalar dy = makeScalar(); SkPath::AddPathMode mode = makeAddPathMode(); path.addPath(src, dx, dy, mode); --fPathDepth; validate(path); } break; case kAddPath2: if (fPathDepth < fPathDepthLimit) { ++fPathDepth; SkPath src = makePath(); validate(src); SkPath::AddPathMode mode = makeAddPathMode(); path.addPath(src, mode); --fPathDepth; validate(path); } break; case kAddPath3: if (fPathDepth < fPathDepthLimit) { ++fPathDepth; SkPath src = makePath(); validate(src); SkMatrix matrix = makeMatrix(); SkPath::AddPathMode mode = makeAddPathMode(); path.addPath(src, matrix, mode); --fPathDepth; validate(path); } break; case kReverseAddPath: if (fPathDepth < fPathDepthLimit) { ++fPathDepth; SkPath src = makePath(); validate(src); path.reverseAddPath(src); --fPathDepth; validate(path); } break; case kMoveToPath: { SkScalar x = makeScalar(); SkScalar y = makeScalar(); path.moveTo(x, y); validate(path); } break; case kRMoveToPath: { SkScalar x = makeScalar(); SkScalar y = makeScalar(); path.rMoveTo(x, y); validate(path); } break; case kLineToPath: { SkScalar x = makeScalar(); SkScalar y = makeScalar(); path.lineTo(x, y); validate(path); } break; case kRLineToPath: { SkScalar x = makeScalar(); SkScalar y = makeScalar(); path.rLineTo(x, y); validate(path); } break; case kQuadToPath: { SkPoint pt[2]; makePointArray(SK_ARRAY_COUNT(pt), pt); path.quadTo(pt[0], pt[1]); validate(path); } break; case kRQuadToPath: { SkPoint pt[2]; makePointArray(SK_ARRAY_COUNT(pt), pt); path.rQuadTo(pt[0].fX, pt[0].fY, pt[1].fX, pt[1].fY); validate(path); } break; case kConicToPath: { SkPoint pt[2]; makePointArray(SK_ARRAY_COUNT(pt), pt); SkScalar weight = makeScalar(); path.conicTo(pt[0], pt[1], weight); validate(path); } break; case kRConicToPath: { SkPoint pt[2]; makePointArray(SK_ARRAY_COUNT(pt), pt); SkScalar weight = makeScalar(); path.rConicTo(pt[0].fX, pt[0].fY, pt[1].fX, pt[1].fY, weight); validate(path); } break; case kCubicToPath: { SkPoint pt[3]; makePointArray(SK_ARRAY_COUNT(pt), pt); path.cubicTo(pt[0], pt[1], pt[2]); validate(path); } break; case kRCubicToPath: { SkPoint pt[3]; makePointArray(SK_ARRAY_COUNT(pt), pt); path.rCubicTo(pt[0].fX, pt[0].fY, pt[1].fX, pt[1].fY, pt[2].fX, pt[2].fY); validate(path); } break; case kArcToPath: { SkPoint pt[2]; makePointArray(SK_ARRAY_COUNT(pt), pt); SkScalar radius = makeScalar(); path.arcTo(pt[0], pt[1], radius); validate(path); } break; case kArcTo2Path: { SkRect oval = makeRect(); SkScalar startAngle = makeAngle(); SkScalar sweepAngle = makeAngle(); bool forceMoveTo = makeBool(); path.arcTo(oval, startAngle, sweepAngle, forceMoveTo); validate(path); } break; case kClosePath: path.close(); validate(path); break; } } } return path; }
void onOnceBeforeDraw() override { { const SkScalar w = SkScalarSqrt(2)/2; SkPath* conicCirlce = &fPaths.push_back(); conicCirlce->moveTo(0, 0); conicCirlce->conicTo(0, 50, 50, 50, w); conicCirlce->rConicTo(50, 0, 50, -50, w); conicCirlce->rConicTo(0, -50, -50, -50, w); conicCirlce->rConicTo(-50, 0, -50, 50, w); } { SkPath* hyperbola = &fPaths.push_back(); hyperbola->moveTo(0, 0); hyperbola->conicTo(0, 100, 100, 100, 2); } { SkPath* thinHyperbola = &fPaths.push_back(); thinHyperbola->moveTo(0, 0); thinHyperbola->conicTo(100, 100, 5, 0, 2); } { SkPath* veryThinHyperbola = &fPaths.push_back(); veryThinHyperbola->moveTo(0, 0); veryThinHyperbola->conicTo(100, 100, 1, 0, 2); } { SkPath* closedHyperbola = &fPaths.push_back(); closedHyperbola->moveTo(0, 0); closedHyperbola->conicTo(100, 100, 0, 0, 2); } { // using 1 as weight defaults to using quadTo SkPath* nearParabola = &fPaths.push_back(); nearParabola->moveTo(0, 0); nearParabola->conicTo(0, 100, 100, 100, 0.999f); } { SkPath* thinEllipse = &fPaths.push_back(); thinEllipse->moveTo(0, 0); thinEllipse->conicTo(100, 100, 5, 0, SK_ScalarHalf); } { SkPath* veryThinEllipse = &fPaths.push_back(); veryThinEllipse->moveTo(0, 0); veryThinEllipse->conicTo(100, 100, 1, 0, SK_ScalarHalf); } { SkPath* closedEllipse = &fPaths.push_back(); closedEllipse->moveTo(0, 0); closedEllipse->conicTo(100, 100, 0, 0, SK_ScalarHalf); } { const SkScalar w = SkScalarSqrt(2)/2; fGiantCircle.moveTo(2.1e+11f, -1.05e+11f); fGiantCircle.conicTo(2.1e+11f, 0, 1.05e+11f, 0, w); fGiantCircle.conicTo(0, 0, 0, -1.05e+11f, w); fGiantCircle.conicTo(0, -2.1e+11f, 1.05e+11f, -2.1e+11f, w); fGiantCircle.conicTo(2.1e+11f, -2.1e+11f, 2.1e+11f, -1.05e+11f, w); } }