int SkOpEdgeBuilder::preFetch() { if (!fPath->isFinite()) { fUnparseable = true; return 0; } SkAutoConicToQuads quadder; const SkScalar quadderTol = SK_Scalar1 / 16; SkPath::RawIter iter(*fPath); SkPoint curveStart; SkPoint curve[4]; SkPoint pts[4]; SkPath::Verb verb; bool lastCurve = false; do { verb = iter.next(pts); switch (verb) { case SkPath::kMove_Verb: if (!fAllowOpenContours && lastCurve) { closeContour(curve[0], curveStart); } fPathVerbs.push_back(verb); force_small_to_zero(&pts[0]); fPathPts.push_back(pts[0]); curveStart = curve[0] = pts[0]; lastCurve = false; continue; case SkPath::kLine_Verb: force_small_to_zero(&pts[1]); if (SkDPoint::ApproximatelyEqual(curve[0], pts[1])) { uint8_t lastVerb = fPathVerbs.back(); if (lastVerb != SkPath::kLine_Verb && lastVerb != SkPath::kMove_Verb) { fPathPts.back() = pts[1]; } continue; // skip degenerate points } break; case SkPath::kQuad_Verb: force_small_to_zero(&pts[1]); force_small_to_zero(&pts[2]); curve[1] = pts[1]; curve[2] = pts[2]; verb = SkReduceOrder::Quad(curve, pts); if (verb == SkPath::kMove_Verb) { continue; // skip degenerate points } break; case SkPath::kConic_Verb: { const SkPoint* quadPts = quadder.computeQuads(pts, iter.conicWeight(), quadderTol); const int nQuads = quadder.countQuads(); for (int i = 0; i < nQuads; ++i) { fPathVerbs.push_back(SkPath::kQuad_Verb); } fPathPts.push_back_n(nQuads * 2, &quadPts[1]); curve[0] = pts[2]; lastCurve = true; } continue; case SkPath::kCubic_Verb: force_small_to_zero(&pts[1]); force_small_to_zero(&pts[2]); force_small_to_zero(&pts[3]); curve[1] = pts[1]; curve[2] = pts[2]; curve[3] = pts[3]; verb = SkReduceOrder::Cubic(curve, pts); if (verb == SkPath::kMove_Verb) { continue; // skip degenerate points } break; case SkPath::kClose_Verb: closeContour(curve[0], curveStart); lastCurve = false; continue; case SkPath::kDone_Verb: continue; } fPathVerbs.push_back(verb); int ptCount = SkPathOpsVerbToPoints(verb); fPathPts.push_back_n(ptCount, &pts[1]); curve[0] = pts[ptCount]; lastCurve = true; } while (verb != SkPath::kDone_Verb); if (!fAllowOpenContours && lastCurve) { closeContour(curve[0], curveStart); } fPathVerbs.push_back(SkPath::kDone_Verb); return fPathVerbs.count() - 1; }
int SkOpEdgeBuilder::preFetch() { if (!fPath->isFinite()) { fUnparseable = true; return 0; } SkPath::RawIter iter(*fPath); SkPoint curveStart; SkPoint curve[4]; SkPoint pts[4]; SkPath::Verb verb; bool lastCurve = false; do { verb = iter.next(pts); switch (verb) { case SkPath::kMove_Verb: if (!fAllowOpenContours && lastCurve) { closeContour(curve[0], curveStart); } *fPathVerbs.append() = verb; force_small_to_zero(&pts[0]); *fPathPts.append() = pts[0]; curveStart = curve[0] = pts[0]; lastCurve = false; continue; case SkPath::kLine_Verb: force_small_to_zero(&pts[1]); if (SkDPoint::ApproximatelyEqual(curve[0], pts[1])) { uint8_t lastVerb = fPathVerbs.top(); if (lastVerb != SkPath::kLine_Verb && lastVerb != SkPath::kMove_Verb) { fPathPts.top() = pts[1]; } continue; // skip degenerate points } break; case SkPath::kQuad_Verb: force_small_to_zero(&pts[1]); force_small_to_zero(&pts[2]); curve[1] = pts[1]; curve[2] = pts[2]; verb = SkReduceOrder::Quad(curve, pts); if (verb == SkPath::kMove_Verb) { continue; // skip degenerate points } break; case SkPath::kConic_Verb: force_small_to_zero(&pts[1]); force_small_to_zero(&pts[2]); curve[1] = pts[1]; curve[2] = pts[2]; 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; case SkPath::kCubic_Verb: force_small_to_zero(&pts[1]); force_small_to_zero(&pts[2]); force_small_to_zero(&pts[3]); curve[1] = pts[1]; curve[2] = pts[2]; curve[3] = pts[3]; verb = SkReduceOrder::Cubic(curve, pts); if (verb == SkPath::kMove_Verb) { continue; // skip degenerate points } break; case SkPath::kClose_Verb: closeContour(curve[0], curveStart); lastCurve = false; continue; case SkPath::kDone_Verb: continue; } *fPathVerbs.append() = verb; int ptCount = SkPathOpsVerbToPoints(verb); fPathPts.append(ptCount, &pts[1]); if (verb == SkPath::kConic_Verb) { *fWeights.append() = iter.conicWeight(); } curve[0] = pts[ptCount]; lastCurve = true; } while (verb != SkPath::kDone_Verb); if (!fAllowOpenContours && lastCurve) { closeContour(curve[0], curveStart); } *fPathVerbs.append() = SkPath::kDone_Verb; return fPathVerbs.count() - 1; }