| Index: src/pathops/SkOpAngle.cpp
|
| diff --git a/src/pathops/SkOpAngle.cpp b/src/pathops/SkOpAngle.cpp
|
| index 6bc510e5ee133f85345c646016d592b2e8d1cf53..db86077769c143e95a6bb7688df84a0bf5df0606 100644
|
| --- a/src/pathops/SkOpAngle.cpp
|
| +++ b/src/pathops/SkOpAngle.cpp
|
| @@ -62,11 +62,11 @@ bool SkOpAngle::after(SkOpAngle* test) {
|
| SkOpAngle* lh = test;
|
| SkOpAngle* rh = lh->fNext;
|
| SkASSERT(lh != rh);
|
| - fCurvePart = fOriginalCurvePart;
|
| - lh->fCurvePart = lh->fOriginalCurvePart;
|
| - lh->fCurvePart.offset(lh->segment()->verb(), fCurvePart[0] - lh->fCurvePart[0]);
|
| - rh->fCurvePart = rh->fOriginalCurvePart;
|
| - rh->fCurvePart.offset(rh->segment()->verb(), fCurvePart[0] - rh->fCurvePart[0]);
|
| + fPart.fCurve = fOriginalCurvePart;
|
| + lh->fPart.fCurve = lh->fOriginalCurvePart;
|
| + lh->fPart.fCurve.offset(lh->segment()->verb(), fPart.fCurve[0] - lh->fPart.fCurve[0]);
|
| + rh->fPart.fCurve = rh->fOriginalCurvePart;
|
| + rh->fPart.fCurve.offset(rh->segment()->verb(), fPart.fCurve[0] - rh->fPart.fCurve[0]);
|
|
|
| #if DEBUG_ANGLE
|
| SkString bugOut;
|
| @@ -177,15 +177,15 @@ bool SkOpAngle::after(SkOpAngle* test) {
|
| // given a line, see if the opposite curve's convex hull is all on one side
|
| // returns -1=not on one side 0=this CW of test 1=this CCW of test
|
| int SkOpAngle::allOnOneSide(const SkOpAngle* test) {
|
| - SkASSERT(!fIsCurve);
|
| - SkASSERT(test->fIsCurve);
|
| - SkDPoint origin = fCurvePart[0];
|
| - SkDVector line = fCurvePart[1] - origin;
|
| + SkASSERT(!fPart.isCurve());
|
| + SkASSERT(test->fPart.isCurve());
|
| + SkDPoint origin = fPart.fCurve[0];
|
| + SkDVector line = fPart.fCurve[1] - origin;
|
| double crosses[3];
|
| SkPath::Verb testVerb = test->segment()->verb();
|
| int iMax = SkPathOpsVerbToPoints(testVerb);
|
| // SkASSERT(origin == test.fCurveHalf[0]);
|
| - const SkDCurve& testCurve = test->fCurvePart;
|
| + const SkDCurve& testCurve = test->fPart.fCurve;
|
| for (int index = 1; index <= iMax; ++index) {
|
| double xy1 = line.fX * (testCurve[index].fY - origin.fY);
|
| double xy2 = line.fY * (testCurve[index].fX - origin.fX);
|
| @@ -222,16 +222,16 @@ bool SkOpAngle::checkCrossesZero() const {
|
| bool SkOpAngle::checkParallel(SkOpAngle* rh) {
|
| SkDVector scratch[2];
|
| const SkDVector* sweep, * tweep;
|
| - if (!this->fUnorderedSweep) {
|
| - sweep = this->fSweep;
|
| + if (this->fPart.isOrdered()) {
|
| + sweep = this->fPart.fSweep;
|
| } else {
|
| - scratch[0] = this->fCurvePart[1] - this->fCurvePart[0];
|
| + scratch[0] = this->fPart.fCurve[1] - this->fPart.fCurve[0];
|
| sweep = &scratch[0];
|
| }
|
| - if (!rh->fUnorderedSweep) {
|
| - tweep = rh->fSweep;
|
| + if (rh->fPart.isOrdered()) {
|
| + tweep = rh->fPart.fSweep;
|
| } else {
|
| - scratch[1] = rh->fCurvePart[1] - rh->fCurvePart[0];
|
| + scratch[1] = rh->fPart.fCurve[1] - rh->fPart.fCurve[0];
|
| tweep = &scratch[1];
|
| }
|
| double s0xt0 = sweep->crossCheck(*tweep);
|
| @@ -256,8 +256,8 @@ bool SkOpAngle::checkParallel(SkOpAngle* rh) {
|
| return !inside;
|
| }
|
| // compute the cross check from the mid T values (last resort)
|
| - SkDVector m0 = segment()->dPtAtT(this->midT()) - this->fCurvePart[0];
|
| - SkDVector m1 = rh->segment()->dPtAtT(rh->midT()) - rh->fCurvePart[0];
|
| + SkDVector m0 = segment()->dPtAtT(this->midT()) - this->fPart.fCurve[0];
|
| + SkDVector m1 = rh->segment()->dPtAtT(rh->midT()) - rh->fPart.fCurve[0];
|
| double m0xm1 = m0.crossCheck(m1);
|
| if (m0xm1 == 0) {
|
| this->fUnorderable = true;
|
| @@ -321,8 +321,8 @@ recomputeSector:
|
| }
|
|
|
| int SkOpAngle::convexHullOverlaps(const SkOpAngle* rh) const {
|
| - const SkDVector* sweep = this->fSweep;
|
| - const SkDVector* tweep = rh->fSweep;
|
| + const SkDVector* sweep = this->fPart.fSweep;
|
| + const SkDVector* tweep = rh->fPart.fSweep;
|
| double s0xs1 = sweep[0].crossCheck(sweep[1]);
|
| double s0xt0 = sweep[0].crossCheck(tweep[0]);
|
| double s1xt0 = sweep[1].crossCheck(tweep[0]);
|
| @@ -352,8 +352,8 @@ int SkOpAngle::convexHullOverlaps(const SkOpAngle* rh) const {
|
| // if the outside sweeps are greater than 180 degress:
|
| // first assume the inital tangents are the ordering
|
| // if the midpoint direction matches the inital order, that is enough
|
| - SkDVector m0 = this->segment()->dPtAtT(this->midT()) - this->fCurvePart[0];
|
| - SkDVector m1 = rh->segment()->dPtAtT(rh->midT()) - rh->fCurvePart[0];
|
| + SkDVector m0 = this->segment()->dPtAtT(this->midT()) - this->fPart.fCurve[0];
|
| + SkDVector m1 = rh->segment()->dPtAtT(rh->midT()) - rh->fPart.fCurve[0];
|
| double m0xm1 = m0.crossCheck(m1);
|
| if (s0xt0 > 0 && m0xm1 > 0) {
|
| return 0;
|
| @@ -392,8 +392,8 @@ bool SkOpAngle::endsIntersect(SkOpAngle* rh) {
|
| SkPath::Verb rVerb = rh->segment()->verb();
|
| int lPts = SkPathOpsVerbToPoints(lVerb);
|
| int rPts = SkPathOpsVerbToPoints(rVerb);
|
| - SkDLine rays[] = {{{this->fCurvePart[0], rh->fCurvePart[rPts]}},
|
| - {{this->fCurvePart[0], this->fCurvePart[lPts]}}};
|
| + SkDLine rays[] = {{{this->fPart.fCurve[0], rh->fPart.fCurve[rPts]}},
|
| + {{this->fPart.fCurve[0], this->fPart.fCurve[lPts]}}};
|
| if (this->fEnd->contains(rh->fEnd)) {
|
| return checkParallel(rh);
|
| }
|
| @@ -464,7 +464,7 @@ bool SkOpAngle::endsIntersect(SkOpAngle* rh) {
|
| double minX, minY, maxX, maxY;
|
| minX = minY = SK_ScalarInfinity;
|
| maxX = maxY = -SK_ScalarInfinity;
|
| - const SkDCurve& curve = index ? rh->fCurvePart : this->fCurvePart;
|
| + const SkDCurve& curve = index ? rh->fPart.fCurve : this->fPart.fCurve;
|
| int ptCount = index ? rPts : lPts;
|
| for (int idx2 = 0; idx2 <= ptCount; ++idx2) {
|
| minX = SkTMin(minX, curve[idx2].fX);
|
| @@ -482,7 +482,7 @@ bool SkOpAngle::endsIntersect(SkOpAngle* rh) {
|
| }
|
| }
|
| if (useIntersect) {
|
| - const SkDCurve& curve = sIndex ? rh->fCurvePart : this->fCurvePart;
|
| + const SkDCurve& curve = sIndex ? rh->fPart.fCurve : this->fPart.fCurve;
|
| const SkOpSegment& segment = sIndex ? *rh->segment() : *this->segment();
|
| double tStart = sIndex ? rh->fStart->t() : fStart->t();
|
| SkDVector mid = segment.dPtAtT(tStart + (sCeptT - tStart) / 2) - curve[0];
|
| @@ -524,7 +524,7 @@ bool SkOpAngle::endToSide(const SkOpAngle* rh, bool* inside) const {
|
| double minX, minY, maxX, maxY;
|
| minX = minY = SK_ScalarInfinity;
|
| maxX = maxY = -SK_ScalarInfinity;
|
| - const SkDCurve& curve = rh->fCurvePart;
|
| + const SkDCurve& curve = rh->fPart.fCurve;
|
| int oppPts = SkPathOpsVerbToPoints(oppVerb);
|
| for (int idx2 = 0; idx2 <= oppPts; ++idx2) {
|
| minX = SkTMin(minX, curve[idx2].fX);
|
| @@ -764,8 +764,8 @@ bool SkOpAngle::oppositePlanes(const SkOpAngle* rh) const {
|
|
|
| bool SkOpAngle::orderable(SkOpAngle* rh) {
|
| int result;
|
| - if (!fIsCurve) {
|
| - if (!rh->fIsCurve) {
|
| + if (!fPart.isCurve()) {
|
| + if (!rh->fPart.isCurve()) {
|
| double leftX = fTangentHalf.dx();
|
| double leftY = fTangentHalf.dy();
|
| double rightX = rh->fTangentHalf.dx();
|
| @@ -787,7 +787,7 @@ bool SkOpAngle::orderable(SkOpAngle* rh) {
|
| if (fUnorderable || approximately_zero(rh->fSide)) {
|
| goto unorderable;
|
| }
|
| - } else if (!rh->fIsCurve) {
|
| + } else if (!rh->fPart.isCurve()) {
|
| if ((result = rh->allOnOneSide(this)) >= 0) {
|
| return !result;
|
| }
|
| @@ -832,59 +832,6 @@ void SkOpAngle::set(SkOpSpanBase* start, SkOpSpanBase* end) {
|
| SkDEBUGCODE(fID = start ? start->globalState()->nextAngleID() : -1);
|
| }
|
|
|
| -void SkOpAngle::setCurveHullSweep() {
|
| - fUnorderedSweep = false;
|
| - fSweep[0] = fCurvePart[1] - fCurvePart[0];
|
| - const SkOpSegment* segment = fStart->segment();
|
| - if (SkPath::kLine_Verb == segment->verb()) {
|
| - fSweep[1] = fSweep[0];
|
| - return;
|
| - }
|
| - fSweep[1] = fCurvePart[2] - fCurvePart[0];
|
| - // OPTIMIZE: I do the following float check a lot -- probably need a
|
| - // central place for this val-is-small-compared-to-curve check
|
| - double maxVal = 0;
|
| - for (int index = 0; index < SkPathOpsVerbToPoints(segment->verb()); ++index) {
|
| - maxVal = SkTMax(maxVal, SkTMax(SkTAbs(fCurvePart[index].fX),
|
| - SkTAbs(fCurvePart[index].fY)));
|
| - }
|
| -
|
| - if (SkPath::kCubic_Verb != segment->verb()) {
|
| - if (roughly_zero_when_compared_to(fSweep[0].fX, maxVal)
|
| - && roughly_zero_when_compared_to(fSweep[0].fY, maxVal)) {
|
| - fSweep[0] = fSweep[1];
|
| - }
|
| - return;
|
| - }
|
| - SkDVector thirdSweep = fCurvePart[3] - fCurvePart[0];
|
| - if (fSweep[0].fX == 0 && fSweep[0].fY == 0) {
|
| - fSweep[0] = fSweep[1];
|
| - fSweep[1] = thirdSweep;
|
| - if (roughly_zero_when_compared_to(fSweep[0].fX, maxVal)
|
| - && roughly_zero_when_compared_to(fSweep[0].fY, maxVal)) {
|
| - fSweep[0] = fSweep[1];
|
| - fCurvePart[1] = fCurvePart[3];
|
| - fIsCurve = false;
|
| - }
|
| - return;
|
| - }
|
| - double s1x3 = fSweep[0].crossCheck(thirdSweep);
|
| - double s3x2 = thirdSweep.crossCheck(fSweep[1]);
|
| - if (s1x3 * s3x2 >= 0) { // if third vector is on or between first two vectors
|
| - return;
|
| - }
|
| - double s2x1 = fSweep[1].crossCheck(fSweep[0]);
|
| - // FIXME: If the sweep of the cubic is greater than 180 degrees, we're in trouble
|
| - // probably such wide sweeps should be artificially subdivided earlier so that never happens
|
| - SkASSERT(s1x3 * s2x1 < 0 || s1x3 * s3x2 < 0);
|
| - if (s3x2 * s2x1 < 0) {
|
| - SkASSERT(s2x1 * s1x3 > 0);
|
| - fSweep[0] = fSweep[1];
|
| - fUnorderedSweep = true;
|
| - }
|
| - fSweep[1] = thirdSweep;
|
| -}
|
| -
|
| void SkOpAngle::setSpans() {
|
| fUnorderable = false;
|
| fLastMarked = nullptr;
|
| @@ -894,21 +841,20 @@ void SkOpAngle::setSpans() {
|
| }
|
| const SkOpSegment* segment = fStart->segment();
|
| const SkPoint* pts = segment->pts();
|
| - SkDEBUGCODE(fCurvePart.fVerb = SkPath::kCubic_Verb);
|
| - SkDEBUGCODE(fCurvePart[2].fX = fCurvePart[2].fY = fCurvePart[3].fX = fCurvePart[3].fY
|
| + SkDEBUGCODE(fPart.fCurve.fVerb = SkPath::kCubic_Verb);
|
| + SkDEBUGCODE(fPart.fCurve[2].fX = fPart.fCurve[2].fY = fPart.fCurve[3].fX = fPart.fCurve[3].fY
|
| = SK_ScalarNaN);
|
| - SkDEBUGCODE(fCurvePart.fVerb = segment->verb());
|
| - segment->subDivide(fStart, fEnd, &fCurvePart);
|
| - fOriginalCurvePart = fCurvePart;
|
| - setCurveHullSweep();
|
| + SkDEBUGCODE(fPart.fCurve.fVerb = segment->verb());
|
| + segment->subDivide(fStart, fEnd, &fPart.fCurve);
|
| + fOriginalCurvePart = fPart.fCurve;
|
| const SkPath::Verb verb = segment->verb();
|
| - if (verb != SkPath::kLine_Verb
|
| - && !(fIsCurve = fSweep[0].crossCheck(fSweep[1]) != 0)) {
|
| + fPart.setCurveHullSweep(verb);
|
| + if (SkPath::kLine_Verb != verb && !fPart.isCurve()) {
|
| SkDLine lineHalf;
|
| - fCurvePart[1] = fCurvePart[SkPathOpsVerbToPoints(verb)];
|
| - fOriginalCurvePart[1] = fCurvePart[1];
|
| - lineHalf[0].set(fCurvePart[0].asSkPoint());
|
| - lineHalf[1].set(fCurvePart[1].asSkPoint());
|
| + fPart.fCurve[1] = fPart.fCurve[SkPathOpsVerbToPoints(verb)];
|
| + fOriginalCurvePart[1] = fPart.fCurve[1];
|
| + lineHalf[0].set(fPart.fCurve[0].asSkPoint());
|
| + lineHalf[1].set(fPart.fCurve[1].asSkPoint());
|
| fTangentHalf.lineEndPoints(lineHalf);
|
| fSide = 0;
|
| }
|
| @@ -921,18 +867,17 @@ void SkOpAngle::setSpans() {
|
| lineHalf[1].set(cP1);
|
| fTangentHalf.lineEndPoints(lineHalf);
|
| fSide = 0;
|
| - fIsCurve = false;
|
| } return;
|
| case SkPath::kQuad_Verb:
|
| case SkPath::kConic_Verb: {
|
| SkLineParameters tangentPart;
|
| - (void) tangentPart.quadEndPoints(fCurvePart.fQuad);
|
| - fSide = -tangentPart.pointDistance(fCurvePart[2]); // not normalized -- compare sign only
|
| + (void) tangentPart.quadEndPoints(fPart.fCurve.fQuad);
|
| + fSide = -tangentPart.pointDistance(fPart.fCurve[2]); // not normalized -- compare sign only
|
| } break;
|
| case SkPath::kCubic_Verb: {
|
| SkLineParameters tangentPart;
|
| - (void) tangentPart.cubicPart(fCurvePart.fCubic);
|
| - fSide = -tangentPart.pointDistance(fCurvePart[3]);
|
| + (void) tangentPart.cubicPart(fPart.fCurve.fCubic);
|
| + fSide = -tangentPart.pointDistance(fPart.fCurve[3]);
|
| double testTs[4];
|
| // OPTIMIZATION: keep inflections precomputed with cubic segment?
|
| int testCount = SkDCubic::FindInflections(pts, testTs);
|
| @@ -964,7 +909,7 @@ void SkOpAngle::setSpans() {
|
| // OPTIMIZE: could avoid call for t == startT, endT
|
| SkDPoint pt = dcubic_xy_at_t(pts, segment->weight(), testT);
|
| SkLineParameters tangentPart;
|
| - tangentPart.cubicEndPoints(fCurvePart.fCubic);
|
| + tangentPart.cubicEndPoints(fPart.fCurve.fCubic);
|
| double testSide = tangentPart.pointDistance(pt);
|
| if (fabs(bestSide) < fabs(testSide)) {
|
| bestSide = testSide;
|
| @@ -984,18 +929,18 @@ void SkOpAngle::setSector() {
|
| }
|
| const SkOpSegment* segment = fStart->segment();
|
| SkPath::Verb verb = segment->verb();
|
| - fSectorStart = this->findSector(verb, fSweep[0].fX, fSweep[0].fY);
|
| + fSectorStart = this->findSector(verb, fPart.fSweep[0].fX, fPart.fSweep[0].fY);
|
| if (fSectorStart < 0) {
|
| goto deferTilLater;
|
| }
|
| - if (!fIsCurve) { // if it's a line or line-like, note that both sectors are the same
|
| + if (!fPart.isCurve()) { // if it's a line or line-like, note that both sectors are the same
|
| SkASSERT(fSectorStart >= 0);
|
| fSectorEnd = fSectorStart;
|
| fSectorMask = 1 << fSectorStart;
|
| return;
|
| }
|
| SkASSERT(SkPath::kLine_Verb != verb);
|
| - fSectorEnd = this->findSector(verb, fSweep[1].fX, fSweep[1].fY);
|
| + fSectorEnd = this->findSector(verb, fPart.fSweep[1].fX, fPart.fSweep[1].fY);
|
| if (fSectorEnd < 0) {
|
| deferTilLater:
|
| fSectorStart = fSectorEnd = -1;
|
| @@ -1045,8 +990,8 @@ bool SkOpAngle::tangentsDiverge(const SkOpAngle* rh, double s0xt0) const {
|
| // - m * (v2.x * v1.x + v2.y * v1.y) == v2.x * v1.y - v2.y * v1.x
|
| // m = (v2.y * v1.x - v2.x * v1.y) / (v2.x * v1.x + v2.y * v1.y)
|
| // m = v1.cross(v2) / v1.dot(v2)
|
| - const SkDVector* sweep = fSweep;
|
| - const SkDVector* tweep = rh->fSweep;
|
| + const SkDVector* sweep = fPart.fSweep;
|
| + const SkDVector* tweep = rh->fPart.fSweep;
|
| double s0dt0 = sweep[0].dot(tweep[0]);
|
| if (!s0dt0) {
|
| return true;
|
|
|