| Index: src/pathops/SkOpEdgeBuilder.cpp
|
| diff --git a/src/pathops/SkOpEdgeBuilder.cpp b/src/pathops/SkOpEdgeBuilder.cpp
|
| index e3dc1398655273d6236da70e086433c5d82d0bc8..24ca9b1f5687626ddde4f194b1fe3bda47330506 100644
|
| --- a/src/pathops/SkOpEdgeBuilder.cpp
|
| +++ b/src/pathops/SkOpEdgeBuilder.cpp
|
| @@ -73,8 +73,6 @@ int SkOpEdgeBuilder::preFetch() {
|
| fUnparseable = true;
|
| return 0;
|
| }
|
| - SkAutoConicToQuads quadder;
|
| - const SkScalar quadderTol = SK_Scalar1 / 16;
|
| SkPath::RawIter iter(*fPath);
|
| SkPoint curveStart;
|
| SkPoint curve[4];
|
| @@ -114,18 +112,16 @@ int SkOpEdgeBuilder::preFetch() {
|
| 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.append() = SkPath::kQuad_Verb;
|
| - }
|
| - fPathPts.append(nQuads * 2, &quadPts[1]);
|
| - curve[0] = pts[2];
|
| - lastCurve = true;
|
| + 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::Conic(curve, iter.conicWeight(), pts);
|
| + if (verb == SkPath::kMove_Verb) {
|
| + continue; // skip degenerate points
|
| }
|
| - continue;
|
| + break;
|
| case SkPath::kCubic_Verb:
|
| force_small_to_zero(&pts[1]);
|
| force_small_to_zero(&pts[2]);
|
| @@ -148,6 +144,9 @@ int SkOpEdgeBuilder::preFetch() {
|
| *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);
|
| @@ -167,6 +166,7 @@ bool SkOpEdgeBuilder::walk(SkChunkAlloc* allocator) {
|
| uint8_t* verbPtr = fPathVerbs.begin();
|
| uint8_t* endOfFirstHalf = &verbPtr[fSecondHalf];
|
| SkPoint* pointsPtr = fPathPts.begin() - 1;
|
| + SkScalar* weightPtr = fWeights.begin();
|
| SkPath::Verb verb;
|
| while ((verb = (SkPath::Verb) *verbPtr) != SkPath::kDone_Verb) {
|
| if (verbPtr == endOfFirstHalf) {
|
| @@ -195,6 +195,9 @@ bool SkOpEdgeBuilder::walk(SkChunkAlloc* allocator) {
|
| case SkPath::kQuad_Verb:
|
| fCurrentContour->addQuad(pointsPtr, fAllocator);
|
| break;
|
| + case SkPath::kConic_Verb:
|
| + fCurrentContour->addConic(pointsPtr, *weightPtr++, fAllocator);
|
| + break;
|
| case SkPath::kCubic_Verb: {
|
| // split self-intersecting cubics in two before proceeding
|
| // if the cubic is convex, it doesn't self intersect.
|
| @@ -202,6 +205,9 @@ bool SkOpEdgeBuilder::walk(SkChunkAlloc* allocator) {
|
| if (SkDCubic::ComplexBreak(pointsPtr, &loopT)) {
|
| SkPoint cubicPair[7];
|
| SkChopCubicAt(pointsPtr, cubicPair, loopT);
|
| + 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]);
|
|
|