diff options
24 files changed, 181 insertions, 162 deletions
diff --git a/src/pathops/SkAddIntersections.cpp b/src/pathops/SkAddIntersections.cpp index 1884d4e4a1..0d65446713 100644 --- a/src/pathops/SkAddIntersections.cpp +++ b/src/pathops/SkAddIntersections.cpp @@ -413,7 +413,7 @@ void AddSelfIntersectTs(SkOpContour* test) { // resolve any coincident pairs found while intersecting, and // see if coincidence is formed by clipping non-concident segments -void CoincidenceCheck(SkTDArray<SkOpContour*>* contourList, int total) { +void CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total) { int contourCount = (*contourList).count(); for (int cIndex = 0; cIndex < contourCount; ++cIndex) { SkOpContour* contour = (*contourList)[cIndex]; diff --git a/src/pathops/SkAddIntersections.h b/src/pathops/SkAddIntersections.h index b5727a440c..94ea436b73 100644 --- a/src/pathops/SkAddIntersections.h +++ b/src/pathops/SkAddIntersections.h @@ -9,10 +9,10 @@ #include "SkIntersectionHelper.h" #include "SkIntersections.h" -#include "SkTDArray.h" +#include "SkTArray.h" bool AddIntersectTs(SkOpContour* test, SkOpContour* next); void AddSelfIntersectTs(SkOpContour* test); -void CoincidenceCheck(SkTDArray<SkOpContour*>* contourList, int total); +void CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total); #endif diff --git a/src/pathops/SkDCubicIntersection.cpp b/src/pathops/SkDCubicIntersection.cpp index 5106bbba98..511879cd70 100644 --- a/src/pathops/SkDCubicIntersection.cpp +++ b/src/pathops/SkDCubicIntersection.cpp @@ -12,7 +12,6 @@ #include "SkPathOpsQuad.h" #include "SkPathOpsRect.h" #include "SkReduceOrder.h" -#include "SkTDArray.h" #include "SkTSort.h" #if ONE_OFF_DEBUG @@ -23,6 +22,8 @@ static const double tLimits2[2][2] = {{-0.865211397, -0.865215212}, {-0.86520769 #define DEBUG_QUAD_PART 0 #define SWAP_TOP_DEBUG 0 +static const int kCubicToQuadSubdivisionDepth = 8; // slots reserved for cubic to quads subdivision + static int quadPart(const SkDCubic& cubic, double tStart, double tEnd, SkReduceOrder* reducer) { SkDCubic part = cubic.subDivide(tStart, tEnd); SkDQuad quad = part.toQuad(); @@ -74,10 +75,10 @@ static void intersect(const SkDCubic& cubic1, double t1s, double t1e, const SkDC i.upDepth(); SkDCubic c1 = cubic1.subDivide(t1s, t1e); SkDCubic c2 = cubic2.subDivide(t2s, t2e); - SkTDArray<double> ts1; + SkSTArray<kCubicToQuadSubdivisionDepth, double, true> ts1; // OPTIMIZE: if c1 == c2, call once (happens when detecting self-intersection) c1.toQuadraticTs(c1.calcPrecision() * precisionScale, &ts1); - SkTDArray<double> ts2; + SkSTArray<kCubicToQuadSubdivisionDepth, double, true> ts2; c2.toQuadraticTs(c2.calcPrecision() * precisionScale, &ts2); double t1Start = t1s; int ts1Count = ts1.count(); @@ -264,10 +265,12 @@ static void intersectEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cub int t1Index = start ? 0 : 3; // don't bother if the two cubics are connnected #if 1 - SkTDArray<double> tVals; // OPTIMIZE: replace with hard-sized array + static const int kPointsInCubic = 4; // FIXME: move to DCubic, replace '4' with this + static const int kMaxLineCubicIntersections = 3; + SkSTArray<(kMaxLineCubicIntersections - 1) * kMaxLineCubicIntersections, double, true> tVals; line[0] = cubic1[t1Index]; // this variant looks for intersections with the end point and lines parallel to other points - for (int index = 0; index < 4; ++index) { + for (int index = 0; index < kPointsInCubic; ++index) { if (index == t1Index) { continue; } @@ -296,7 +299,7 @@ static void intersectEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cub i.insert(start ? 0 : 1, foundT, line[0]); } } else { - *tVals.append() = foundT; + tVals.push_back(foundT); } } } diff --git a/src/pathops/SkDCubicToQuads.cpp b/src/pathops/SkDCubicToQuads.cpp index b95053593b..571f1d94ae 100644 --- a/src/pathops/SkDCubicToQuads.cpp +++ b/src/pathops/SkDCubicToQuads.cpp @@ -49,7 +49,7 @@ http://www.caffeineowl.com/graphics/2d/vectorial/cubic2quad01.html #include "SkPathOpsLine.h" #include "SkPathOpsQuad.h" #include "SkReduceOrder.h" -#include "SkTDArray.h" +#include "SkTArray.h" #include "SkTSort.h" #define USE_CUBIC_END_POINTS 1 @@ -88,26 +88,26 @@ SkDQuad SkDCubic::toQuad() const { return quad; } -static bool add_simple_ts(const SkDCubic& cubic, double precision, SkTDArray<double>* ts) { +static bool add_simple_ts(const SkDCubic& cubic, double precision, SkTArray<double, true>* ts) { double tDiv = calc_t_div(cubic, precision, 0); if (tDiv >= 1) { return true; } if (tDiv >= 0.5) { - *ts->append() = 0.5; + ts->push_back(0.5); return true; } return false; } static void addTs(const SkDCubic& cubic, double precision, double start, double end, - SkTDArray<double>* ts) { + SkTArray<double, true>* ts) { double tDiv = calc_t_div(cubic, precision, 0); double parts = ceil(1.0 / tDiv); for (double index = 0; index < parts; ++index) { double newT = start + (index / parts) * (end - start); if (newT > 0 && newT < 1) { - *ts->append() = newT; + ts->push_back(newT); } } } @@ -116,7 +116,7 @@ static void addTs(const SkDCubic& cubic, double precision, double start, double // FIXME: when called from recursive intersect 2, this could take the original cubic // and do a more precise job when calling chop at and sub divide by computing the fractional ts. // it would still take the prechopped cubic for reduce order and find cubic inflections -void SkDCubic::toQuadraticTs(double precision, SkTDArray<double>* ts) const { +void SkDCubic::toQuadraticTs(double precision, SkTArray<double, true>* ts) const { SkReduceOrder reducer; int order = reducer.reduce(*this, SkReduceOrder::kAllow_Quadratics, SkReduceOrder::kFill_Style); if (order < 3) { diff --git a/src/pathops/SkDQuadIntersection.cpp b/src/pathops/SkDQuadIntersection.cpp index b6a1761781..8b222f725d 100644 --- a/src/pathops/SkDQuadIntersection.cpp +++ b/src/pathops/SkDQuadIntersection.cpp @@ -9,7 +9,7 @@ #include "SkIntersections.h" #include "SkPathOpsLine.h" #include "SkQuarticRoot.h" -#include "SkTDArray.h" +#include "SkTArray.h" #include "SkTSort.h" /* given the implicit form 0 = Ax^2 + Bxy + Cy^2 + Dx + Ey + F @@ -150,9 +150,9 @@ static bool is_linear_inner(const SkDQuad& q1, double t1s, double t1e, const SkD SkDQuad hull = q1.subDivide(t1s, t1e); SkDLine line = {{hull[2], hull[0]}}; const SkDLine* testLines[] = { &line, (const SkDLine*) &hull[0], (const SkDLine*) &hull[1] }; - size_t testCount = SK_ARRAY_COUNT(testLines); - SkTDArray<double> tsFound; - for (size_t index = 0; index < testCount; ++index) { + const size_t kTestCount = SK_ARRAY_COUNT(testLines); + SkSTArray<kTestCount * 2, double, true> tsFound; + for (size_t index = 0; index < kTestCount; ++index) { SkIntersections rootTs; int roots = rootTs.intersect(q2, *testLines[index]); for (int idx2 = 0; idx2 < roots; ++idx2) { @@ -165,7 +165,7 @@ static bool is_linear_inner(const SkDQuad& q1, double t1s, double t1e, const SkD if (approximately_negative(t - t2s) || approximately_positive(t - t2e)) { continue; } - *tsFound.append() = rootTs[0][idx2]; + tsFound.push_back(rootTs[0][idx2]); } } int tCount = tsFound.count(); diff --git a/src/pathops/SkOpAngle.h b/src/pathops/SkOpAngle.h index 2800ff0568..e7e5e1f597 100644 --- a/src/pathops/SkOpAngle.h +++ b/src/pathops/SkOpAngle.h @@ -17,6 +17,8 @@ class SkOpSegment; // given angles of {dx dy ddx ddy dddx dddy} sort them class SkOpAngle { public: + enum { kStackBasedCount = 8 }; // FIXME: determine what this should be + bool operator<(const SkOpAngle& rh) const; bool calcSlop(double x, double y, double rx, double ry, bool* result) const; diff --git a/src/pathops/SkOpContour.cpp b/src/pathops/SkOpContour.cpp index 6266c65cf8..f3861a1e0b 100644 --- a/src/pathops/SkOpContour.cpp +++ b/src/pathops/SkOpContour.cpp @@ -11,7 +11,7 @@ void SkOpContour::addCoincident(int index, SkOpContour* other, int otherIndex, const SkIntersections& ts, bool swap) { - SkCoincidence& coincidence = *fCoincidences.append(); + SkCoincidence& coincidence = fCoincidences.push_back(); coincidence.fContours[0] = this; // FIXME: no need to store coincidence.fContours[1] = other; coincidence.fSegments[0] = index; @@ -152,9 +152,9 @@ void SkOpContour::calcCoincidentWinding() { void SkOpContour::sortSegments() { int segmentCount = fSegments.count(); - fSortedSegments.setReserve(segmentCount); + fSortedSegments.push_back_n(segmentCount); for (int test = 0; test < segmentCount; ++test) { - *fSortedSegments.append() = &fSegments[test]; + fSortedSegments[test] = &fSegments[test]; } SkTQSort<SkOpSegment>(fSortedSegments.begin(), fSortedSegments.end() - 1); fFirstSorted = 0; @@ -229,7 +229,7 @@ int SkOpContour::debugShowWindingValues(int totalSegments, int ofInterest) { return sum; } -static void SkOpContour::debugShowWindingValues(const SkTDArray<SkOpContour*>& contourList) { +static void SkOpContour::debugShowWindingValues(const SkTArray<SkOpContour*, true>& contourList) { // int ofInterest = 1 << 1 | 1 << 5 | 1 << 9 | 1 << 13; // int ofInterest = 1 << 4 | 1 << 8 | 1 << 12 | 1 << 16; int ofInterest = 1 << 5 | 1 << 8; diff --git a/src/pathops/SkOpContour.h b/src/pathops/SkOpContour.h index c57fbac6ca..84f0eb10dd 100644 --- a/src/pathops/SkOpContour.h +++ b/src/pathops/SkOpContour.h @@ -46,7 +46,7 @@ public: SkASSERT(fCrosses[index] != crosser); } #endif - *fCrosses.append() = crosser; + fCrosses.push_back(crosser); } void addCubic(const SkPoint pts[4]) { @@ -214,17 +214,17 @@ public: #if DEBUG_SHOW_WINDING int debugShowWindingValues(int totalSegments, int ofInterest); - static void debugShowWindingValues(const SkTDArray<SkOpContour*>& contourList); + static void debugShowWindingValues(const SkTArray<SkOpContour*, true>& contourList); #endif private: void setBounds(); SkTArray<SkOpSegment> fSegments; - SkTDArray<SkOpSegment*> fSortedSegments; + SkTArray<SkOpSegment*, true> fSortedSegments; int fFirstSorted; - SkTDArray<SkCoincidence> fCoincidences; - SkTDArray<const SkOpContour*> fCrosses; + SkTArray<SkCoincidence, true> fCoincidences; + SkTArray<const SkOpContour*, true> fCrosses; SkPathOpsBounds fBounds; bool fContainsIntercepts; // FIXME: is this used by anybody? bool fContainsCubics; diff --git a/src/pathops/SkOpEdgeBuilder.cpp b/src/pathops/SkOpEdgeBuilder.cpp index 5803afa11c..d7f52752bf 100644 --- a/src/pathops/SkOpEdgeBuilder.cpp +++ b/src/pathops/SkOpEdgeBuilder.cpp @@ -22,7 +22,7 @@ void SkOpEdgeBuilder::init() { void SkOpEdgeBuilder::addOperand(const SkPath& path) { SkASSERT(fPathVerbs.count() > 0 && fPathVerbs.end()[-1] == SkPath::kDone_Verb); - fPathVerbs.pop(); + fPathVerbs.pop_back(); fPath = &path; fXorMask[1] = (fPath->getFillType() & 1) ? kEvenOdd_PathOpsMask : kWinding_PathOpsMask; @@ -72,11 +72,11 @@ int SkOpEdgeBuilder::preFetch() { SkPath::Verb verb; do { verb = iter.next(pts); - *fPathVerbs.append() = verb; + fPathVerbs.push_back(verb); if (verb == SkPath::kMove_Verb) { - *fPathPts.append() = pts[0]; + fPathPts.push_back(pts[0]); } else if (verb >= SkPath::kLine_Verb && verb <= SkPath::kCubic_Verb) { - fPathPts.append(SkPathOpsVerbToPoints(verb), &pts[1]); + fPathPts.push_back_n(SkPathOpsVerbToPoints(verb), &pts[1]); } } while (verb != SkPath::kDone_Verb); return fPathVerbs.count() - 1; @@ -84,10 +84,10 @@ int SkOpEdgeBuilder::preFetch() { bool SkOpEdgeBuilder::close() { if (fFinalCurveStart && fFinalCurveEnd && *fFinalCurveStart != *fFinalCurveEnd) { - *fReducePts.append() = *fFinalCurveStart; - *fReducePts.append() = *fFinalCurveEnd; + fReducePts.push_back(*fFinalCurveStart); + fReducePts.push_back(*fFinalCurveEnd); const SkPoint* lineStart = fReducePts.end() - 2; - *fExtra.append() = fCurrentContour->addLine(lineStart); + fExtra.push_back(fCurrentContour->addLine(lineStart)); } complete(); return true; @@ -119,7 +119,7 @@ bool SkOpEdgeBuilder::walk() { fCurrentContour = fContours.push_back_n(1); fCurrentContour->setOperand(fOperand); fCurrentContour->setXor(fXorMask[fOperand] == kEvenOdd_PathOpsMask); - *fExtra.append() = -1; // start new contour + fExtra.push_back(-1); // start new contour } fFinalCurveEnd = pointsPtr++; continue; @@ -139,7 +139,7 @@ bool SkOpEdgeBuilder::walk() { } if (reducedVerb == SkPath::kLine_Verb) { const SkPoint* lineStart = fReducePts.end() - 2; - *fExtra.append() = fCurrentContour->addLine(lineStart); + fExtra.push_back(fCurrentContour->addLine(lineStart)); break; } fCurrentContour->addQuad(quadStart); @@ -152,12 +152,12 @@ bool SkOpEdgeBuilder::walk() { } if (reducedVerb == SkPath::kLine_Verb) { const SkPoint* lineStart = fReducePts.end() - 2; - *fExtra.append() = fCurrentContour->addLine(lineStart); + fExtra.push_back(fCurrentContour->addLine(lineStart)); break; } if (reducedVerb == SkPath::kQuad_Verb) { const SkPoint* quadStart = fReducePts.end() - 3; - *fExtra.append() = fCurrentContour->addQuad(quadStart); + fExtra.push_back(fCurrentContour->addQuad(quadStart)); break; } fCurrentContour->addCubic(cubicStart); diff --git a/src/pathops/SkOpEdgeBuilder.h b/src/pathops/SkOpEdgeBuilder.h index b827a2a009..2a2bf034e4 100644 --- a/src/pathops/SkOpEdgeBuilder.h +++ b/src/pathops/SkOpEdgeBuilder.h @@ -10,7 +10,6 @@ #include "SkOpContour.h" #include "SkPathWriter.h" #include "SkTArray.h" -#include "SkTDArray.h" class SkOpEdgeBuilder { public: @@ -49,12 +48,12 @@ private: bool walk(); const SkPath* fPath; - SkTDArray<SkPoint> fPathPts; - SkTDArray<uint8_t> fPathVerbs; + SkTArray<SkPoint, true> fPathPts; + SkTArray<uint8_t, true> fPathVerbs; SkOpContour* fCurrentContour; SkTArray<SkOpContour>& fContours; - SkTDArray<SkPoint> fReducePts; // segments created on the fly - SkTDArray<int> fExtra; // -1 marks new contour, > 0 offsets into contour + SkTArray<SkPoint, true> fReducePts; // segments created on the fly + SkTArray<int, true> fExtra; // -1 marks new contour, > 0 offsets into contour SkPathOpsMask fXorMask[2]; const SkPoint* fFinalCurveStart; const SkPoint* fFinalCurveEnd; diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp index a9e20fd11a..08f4f7eace 100644 --- a/src/pathops/SkOpSegment.cpp +++ b/src/pathops/SkOpSegment.cpp @@ -32,6 +32,8 @@ static const bool gActiveEdge[kXOR_PathOp + 1][2][2][2][2] = { #undef F #undef T +enum { kOutsideTrackedTCount = 16 }; // FIXME: determine what this should be + // OPTIMIZATION: does the following also work, and is it any faster? // return outerWinding * innerWinding > 0 // || ((outerWinding + innerWinding < 0) ^ ((outerWinding - innerWinding) < 0))) @@ -44,7 +46,7 @@ bool SkOpSegment::UseInnerWinding(int outerWinding, int innerWinding) { return result; } -bool SkOpSegment::activeAngle(int index, int* done, SkTDArray<SkOpAngle>* angles) { +bool SkOpSegment::activeAngle(int index, int* done, SkTArray<SkOpAngle, true>* angles) { if (activeAngleInner(index, done, angles)) { return true; } @@ -63,14 +65,14 @@ bool SkOpSegment::activeAngle(int index, int* done, SkTDArray<SkOpAngle>* angles return false; } -bool SkOpSegment::activeAngleOther(int index, int* done, SkTDArray<SkOpAngle>* angles) { +bool SkOpSegment::activeAngleOther(int index, int* done, SkTArray<SkOpAngle, true>* angles) { SkOpSpan* span = &fTs[index]; SkOpSegment* other = span->fOther; int oIndex = span->fOtherIndex; return other->activeAngleInner(oIndex, done, angles); } -bool SkOpSegment::activeAngleInner(int index, int* done, SkTDArray<SkOpAngle>* angles) { +bool SkOpSegment::activeAngleInner(int index, int* done, SkTArray<SkOpAngle, true>* angles) { int next = nextExactSpan(index, 1); if (next > 0) { SkOpSpan& upSpan = fTs[index]; @@ -204,11 +206,11 @@ bool SkOpSegment::activeWinding(int index, int endIndex, int* maxWinding, int* s return result; } -void SkOpSegment::addAngle(SkTDArray<SkOpAngle>* anglesPtr, int start, int end) const { +void SkOpSegment::addAngle(SkTArray<SkOpAngle, true>* anglesPtr, int start, int end) const { SkASSERT(start != end); - SkOpAngle* angle = anglesPtr->append(); + SkOpAngle& angle = anglesPtr->push_back(); #if DEBUG_ANGLE - SkTDArray<SkOpAngle>& angles = *anglesPtr; + SkTArray<SkOpAngle, true>& angles = *anglesPtr; if (angles.count() > 1) { const SkOpSegment* aSeg = angles[0].segment(); int aStart = angles[0].start(); @@ -224,7 +226,7 @@ void SkOpSegment::addAngle(SkTDArray<SkOpAngle>* anglesPtr, int start, int end) } } #endif - angle->set(this, start, end); + angle.set(this, start, end); } void SkOpSegment::addCancelOutsides(double tStart, double oStart, SkOpSegment* other, double oEnd) { @@ -299,7 +301,7 @@ void SkOpSegment::addCancelOutsides(double tStart, double oStart, SkOpSegment* o } } -void SkOpSegment::addCoinOutsides(const SkTDArray<double>& outsideTs, SkOpSegment* other, +void SkOpSegment::addCoinOutsides(const SkTArray<double, true>& outsideTs, SkOpSegment* other, double oEnd) { // walk this to outsideTs[0] // walk other to outsideTs[1] @@ -566,8 +568,8 @@ void SkOpSegment::addTCancel(double startT, double endT, SkOpSegment* other, double tRatio = (oEndT - oStartT) / (endT - startT); SkOpSpan* test = &fTs[index]; SkOpSpan* oTest = &other->fTs[oIndex]; - SkTDArray<double> outsideTs; - SkTDArray<double> oOutsideTs; + SkSTArray<kOutsideTrackedTCount, double, true> outsideTs; + SkSTArray<kOutsideTrackedTCount, double, true> oOutsideTs; do { bool decrement = test->fWindValue && oTest->fWindValue; bool track = test->fWindValue || oTest->fWindValue; @@ -658,7 +660,7 @@ int SkOpSegment::addUnsortableT(SkOpSegment* other, bool start, const SkPoint& p } int SkOpSegment::bumpCoincidentThis(const SkOpSpan& oTest, bool opp, int index, - SkTDArray<double>* outsideTs) { + SkTArray<double, true>* outsideTs) { int oWindValue = oTest.fWindValue; int oOppValue = oTest.fOppValue; if (opp) { @@ -681,7 +683,7 @@ int SkOpSegment::bumpCoincidentThis(const SkOpSpan& oTest, bool opp, int index, // intermediate T values (using this as the master, other as the follower) // and walk other conditionally -- hoping that it catches up in the end int SkOpSegment::bumpCoincidentOther(const SkOpSpan& test, double oEndT, int& oIndex, - SkTDArray<double>* oOutsideTs) { + SkTArray<double, true>* oOutsideTs) { SkOpSpan* const oTest = &fTs[oIndex]; SkOpSpan* oEnd = oTest; const double startT = test.fT; @@ -719,8 +721,8 @@ void SkOpSegment::addTCoincident(double startT, double endT, SkOpSegment* other, } SkOpSpan* test = &fTs[index]; SkOpSpan* oTest = &other->fTs[oIndex]; - SkTDArray<double> outsideTs; - SkTDArray<double> oOutsideTs; + SkSTArray<kOutsideTrackedTCount, double, true> outsideTs; + SkSTArray<kOutsideTrackedTCount, double, true> oOutsideTs; do { // if either span has an opposite value and the operands don't match, resolve first // SkASSERT(!test->fDone || !oTest->fDone); @@ -775,7 +777,7 @@ void SkOpSegment::addTPair(double t, SkOpSegment* other, double otherT, bool bor other->matchWindingValue(otherInsertedAt, otherT, borrowWind); } -void SkOpSegment::addTwoAngles(int start, int end, SkTDArray<SkOpAngle>* angles) const { +void SkOpSegment::addTwoAngles(int start, int end, SkTArray<SkOpAngle, true>* angles) const { // add edge leading into junction int min = SkMin32(end, start); if (fTs[min].fWindValue > 0 || fTs[min].fOppValue != 0) { @@ -817,7 +819,7 @@ bool SkOpSegment::betweenTs(int lesser, double testT, int greater) const { return approximately_between(fTs[lesser].fT, testT, fTs[greater].fT); } -void SkOpSegment::buildAngles(int index, SkTDArray<SkOpAngle>* angles, bool includeOpp) const { +void SkOpSegment::buildAngles(int index, SkTArray<SkOpAngle, true>* angles, bool includeOpp) const { double referenceT = fTs[index].fT; int lesser = index; while (--lesser >= 0 && (includeOpp || fTs[lesser].fOther->fOperand == fOperand) @@ -830,7 +832,7 @@ void SkOpSegment::buildAngles(int index, SkTDArray<SkOpAngle>* angles, bool incl && precisely_negative(fTs[index].fT - referenceT)); } -void SkOpSegment::buildAnglesInner(int index, SkTDArray<SkOpAngle>* angles) const { +void SkOpSegment::buildAnglesInner(int index, SkTArray<SkOpAngle, true>* angles) const { const SkOpSpan* span = &fTs[index]; SkOpSegment* other = span->fOther; // if there is only one live crossing, and no coincidence, continue @@ -850,12 +852,12 @@ void SkOpSegment::buildAnglesInner(int index, SkTDArray<SkOpAngle>* angles) cons } int SkOpSegment::computeSum(int startIndex, int endIndex, bool binary) { - SkTDArray<SkOpAngle> angles; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; addTwoAngles(startIndex, endIndex, &angles); buildAngles(endIndex, &angles, false); // OPTIMIZATION: check all angles to see if any have computed wind sum // before sorting (early exit if none) - SkTDArray<SkOpAngle*> sorted; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; // FIXME?: Not sure if this sort must be ordered or if the relaxed ordering is OK ... bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_SortAngleKind); #if DEBUG_SORT @@ -1137,12 +1139,12 @@ SkOpSegment* SkOpSegment::findNextOp(SkTDArray<SkOpSpan*>* chase, int* nextStart return other; } // more than one viable candidate -- measure angles to find best - SkTDArray<SkOpAngle> angles; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; SkASSERT(startIndex - endIndex != 0); SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); addTwoAngles(startIndex, end, &angles); buildAngles(end, &angles, true); - SkTDArray<SkOpAngle*> sorted; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_SortAngleKind); int angleCount = angles.count(); int firstIndex = findStartingEdge(sorted, startIndex, end); @@ -1259,12 +1261,12 @@ SkOpSegment* SkOpSegment::findNextWinding(SkTDArray<SkOpSpan*>* chase, int* next return other; } // more than one viable candidate -- measure angles to find best - SkTDArray<SkOpAngle> angles; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; SkASSERT(startIndex - endIndex != 0); SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); addTwoAngles(startIndex, end, &angles); buildAngles(end, &angles, true); - SkTDArray<SkOpAngle*> sorted; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_SortAngleKind); int angleCount = angles.count(); int firstIndex = findStartingEdge(sorted, startIndex, end); @@ -1388,12 +1390,12 @@ SkOpSegment* SkOpSegment::findNextXor(int* nextStart, int* nextEnd, bool* unsort SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count()); return other; } - SkTDArray<SkOpAngle> angles; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; SkASSERT(startIndex - endIndex != 0); SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); addTwoAngles(startIndex, end, &angles); buildAngles(end, &angles, false); - SkTDArray<SkOpAngle*> sorted; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_SortAngleKind); if (!sortable) { *unsortable = true; @@ -1449,7 +1451,7 @@ SkOpSegment* SkOpSegment::findNextXor(int* nextStart, int* nextEnd, bool* unsort return nextSegment; } -int SkOpSegment::findStartingEdge(const SkTDArray<SkOpAngle*>& sorted, int start, int end) { +int SkOpSegment::findStartingEdge(const SkTArray<SkOpAngle*, true>& sorted, int start, int end) { int angleCount = sorted.count(); int firstIndex = -1; for (int angleIndex = 0; angleIndex < angleCount; ++angleIndex) { @@ -1631,11 +1633,11 @@ SkOpSegment* SkOpSegment::findTop(int* tIndexPtr, int* endIndexPtr, bool* unsort } // if the topmost T is not on end, or is three-way or more, find left // look for left-ness from tLeft to firstT (matching y of other) - SkTDArray<SkOpAngle> angles; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; SkASSERT(firstT - end != 0); addTwoAngles(end, firstT, &angles); buildAngles(firstT, &angles, true); - SkTDArray<SkOpAngle*> sorted; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMayBeUnordered_SortAngleKind); int first = SK_MaxS32; SkScalar top = SK_ScalarMax; @@ -2343,15 +2345,17 @@ void SkOpSegment::setUpWindings(int index, int endIndex, int* sumMiWinding, int* // exclusion in find top and others. This could be optimized to only mark // adjacent spans that unsortable. However, this makes it difficult to later // determine starting points for edge detection in find top and the like. -bool SkOpSegment::SortAngles(const SkTDArray<SkOpAngle>& angles, SkTDArray<SkOpAngle*>* angleList, +bool SkOpSegment::SortAngles(const SkTArray<SkOpAngle, true>& angles, + SkTArray<SkOpAngle*, true>* angleList, SortAngleKind orderKind) { bool sortable = true; int angleCount = angles.count(); int angleIndex; - angleList->setReserve(angleCount); +// FIXME: caller needs to use SkTArray constructor with reserve count +// angleList->setReserve(angleCount); for (angleIndex = 0; angleIndex < angleCount; ++angleIndex) { const SkOpAngle& angle = angles[angleIndex]; - *angleList->append() = const_cast<SkOpAngle*>(&angle); + angleList->push_back(const_cast<SkOpAngle*>(&angle)); #if DEBUG_ANGLE (*(angleList->end() - 1))->setID(angleIndex); #endif @@ -2470,11 +2474,11 @@ bool SkOpSegment::isTiny(int index) const { return fTs[index].fTiny; } -void SkOpSegment::TrackOutside(SkTDArray<double>* outsideTs, double end, double start) { +void SkOpSegment::TrackOutside(SkTArray<double, true>* outsideTs, double end, double start) { int outCount = outsideTs->count(); if (outCount == 0 || !approximately_negative(end - (*outsideTs)[outCount - 2])) { - *outsideTs->append() = end; - *outsideTs->append() = start; + outsideTs->push_back(end); + outsideTs->push_back(start); } } @@ -2763,8 +2767,9 @@ void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int #endif #if DEBUG_SORT || DEBUG_SWAP_TOP -void SkOpSegment::debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& angles, int first, - const int contourWinding, const int oppContourWinding) const { +void SkOpSegment::debugShowSort(const char* fun, const SkTArray<SkOpAngle*, true>& angles, + int first, const int contourWinding, + const int oppContourWinding) const { if (--gDebugSortCount < 0) { return; } @@ -2872,7 +2877,8 @@ void SkOpSegment::debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& an } while (index != first); } -void SkOpSegment::debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& angles, int first) { +void SkOpSegment::debugShowSort(const char* fun, const SkTArray<SkOpAngle*, true>& angles, + int first) { const SkOpAngle* firstAngle = angles[first]; const SkOpSegment* segment = firstAngle->segment(); int winding = segment->updateWinding(firstAngle); @@ -2888,8 +2894,7 @@ int SkOpSegment::debugShowWindingValues(int slotCount, int ofInterest) const { return 0; } int sum = 0; - SkTDArray<char> slots; - slots.setCount(slotCount * 2); + SkTArray<char, true> slots(slotCount * 2); memset(slots.begin(), ' ', slotCount * 2); for (int i = 0; i < fTs.count(); ++i) { // if (!(1 << fTs[i].fOther->fID & ofInterest)) { diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h index b26bad14a6..94efcb53fe 100644 --- a/src/pathops/SkOpSegment.h +++ b/src/pathops/SkOpSegment.h @@ -11,6 +11,7 @@ #include "SkOpSpan.h" #include "SkPathOpsBounds.h" #include "SkPathOpsCurve.h" +#include "SkTArray.h" #include "SkTDArray.h" class SkPathWriter; @@ -230,7 +231,7 @@ public: return xyAtT(span).fY; } - bool activeAngle(int index, int* done, SkTDArray<SkOpAngle>* angles); + bool activeAngle(int index, int* done, SkTArray<SkOpAngle, true>* angles); SkPoint activeLeftTop(bool onlySortable, int* firstT) const; bool activeOp(int index, int endIndex, int xorMiMask, int xorSuMask, SkPathOp op); bool activeOp(int xorMiMask, int xorSuMask, int index, int endIndex, SkPathOp op, @@ -294,7 +295,8 @@ public: kMustBeOrdered_SortAngleKind, // required for winding calc kMayBeUnordered_SortAngleKind // ok for find top }; - static bool SortAngles(const SkTDArray<SkOpAngle>& angles, SkTDArray<SkOpAngle*>* angleList, + static bool SortAngles(const SkTArray<SkOpAngle, true>& angles, + SkTArray<SkOpAngle*, true>* angleList, SortAngleKind ); bool subDivide(int start, int end, SkPoint edge[4]) const; bool subDivide(int start, int end, SkDCubic* result) const; @@ -315,9 +317,9 @@ public: void debugShowActiveSpans() const; #endif #if DEBUG_SORT || DEBUG_SWAP_TOP - void debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& angles, int first, + void debugShowSort(const char* fun, const SkTArray<SkOpAngle*, true>& angles, int first, const int contourWinding, const int oppContourWinding) const; - void debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& angles, int first); + void debugShowSort(const char* fun, const SkTArray<SkOpAngle*, true>& angles, int first); #endif #if DEBUG_CONCIDENT void debugShowTs() const; @@ -327,25 +329,25 @@ public: #endif private: - bool activeAngleOther(int index, int* done, SkTDArray<SkOpAngle>* angles); - bool activeAngleInner(int index, int* done, SkTDArray<SkOpAngle>* angles); - void addAngle(SkTDArray<SkOpAngle>* angles, int start, int end) const; + bool activeAngleOther(int index, int* done, SkTArray<SkOpAngle, true>* angles); + bool activeAngleInner(int index, int* done, SkTArray<SkOpAngle, true>* angles); + void addAngle(SkTArray<SkOpAngle, true>* angles, int start, int end) const; void addCancelOutsides(double tStart, double oStart, SkOpSegment* other, double oEnd); - void addCoinOutsides(const SkTDArray<double>& outsideTs, SkOpSegment* other, double oEnd); - void addTwoAngles(int start, int end, SkTDArray<SkOpAngle>* angles) const; + void addCoinOutsides(const SkTArray<double, true>& outsideTs, SkOpSegment* other, double oEnd); + void addTwoAngles(int start, int end, SkTArray<SkOpAngle, true>* angles) const; int advanceCoincidentOther(const SkOpSpan* test, double oEndT, int oIndex); int advanceCoincidentThis(const SkOpSpan* oTest, bool opp, int index); - void buildAngles(int index, SkTDArray<SkOpAngle>* angles, bool includeOpp) const; - void buildAnglesInner(int index, SkTDArray<SkOpAngle>* angles) const; + void buildAngles(int index, SkTArray<SkOpAngle, true>* angles, bool includeOpp) const; + void buildAnglesInner(int index, SkTArray<SkOpAngle, true>* angles) const; int bumpCoincidentThis(const SkOpSpan& oTest, bool opp, int index, - SkTDArray<double>* outsideTs); + SkTArray<double, true>* outsideTs); int bumpCoincidentOther(const SkOpSpan& test, double oEndT, int& oIndex, - SkTDArray<double>* oOutsideTs); + SkTArray<double, true>* oOutsideTs); bool bumpSpan(SkOpSpan* span, int windDelta, int oppDelta); bool clockwise(int tStart, int tEnd) const; void decrementSpan(SkOpSpan* span); bool equalPoints(int greaterTIndex, int lesserTIndex); - int findStartingEdge(const SkTDArray<SkOpAngle*>& sorted, int start, int end); + int findStartingEdge(const SkTArray<SkOpAngle*, true>& sorted, int start, int end); void init(const SkPoint pts[], SkPath::Verb verb, bool operand, bool evenOdd); void matchWindingValue(int tIndex, double t, bool borrowWind); SkOpSpan* markAndChaseDone(int index, int endIndex, int winding); @@ -365,7 +367,7 @@ private: SkOpSegment* nextChase(int* index, const int step, int* min, SkOpSpan** last); bool serpentine(int tStart, int tEnd) const; void subDivideBounds(int start, int end, SkPathOpsBounds* bounds) const; - static void TrackOutside(SkTDArray<double>* outsideTs, double end, double start); + static void TrackOutside(SkTArray<double, true>* outsideTs, double end, double start); int updateOppWinding(int index, int endIndex) const; int updateOppWinding(const SkOpAngle* angle) const; int updateWinding(int index, int endIndex) const; @@ -393,6 +395,7 @@ private: const SkPoint* fPts; SkPathOpsBounds fBounds; + // FIXME: can't convert to SkTArray because it uses insert SkTDArray<SkOpSpan> fTs; // two or more (always includes t=0 t=1) // OPTIMIZATION: could pack donespans, verb, operand, xor into 1 int-sized value int fDoneSpans; // quick check that segment is finished diff --git a/src/pathops/SkPathOpsCommon.cpp b/src/pathops/SkPathOpsCommon.cpp index 9215cbc84a..0fa5ce0c92 100644 --- a/src/pathops/SkPathOpsCommon.cpp +++ b/src/pathops/SkPathOpsCommon.cpp @@ -9,7 +9,7 @@ #include "SkPathWriter.h" #include "SkTSort.h" -static int contourRangeCheckY(const SkTDArray<SkOpContour*>& contourList, SkOpSegment** currentPtr, +static int contourRangeCheckY(const SkTArray<SkOpContour*, true>& contourList, SkOpSegment** currentPtr, int* indexPtr, int* endIndexPtr, double* bestHit, SkScalar* bestDx, bool* tryAgain, double* midPtr, bool opp) { const int index = *indexPtr; @@ -97,7 +97,7 @@ abortContours: return result; } -SkOpSegment* FindUndone(SkTDArray<SkOpContour*>& contourList, int* start, int* end) { +SkOpSegment* FindUndone(SkTArray<SkOpContour*, true>& contourList, int* start, int* end) { int contourCount = contourList.count(); SkOpSegment* result; for (int cIndex = 0; cIndex < contourCount; ++cIndex) { @@ -117,7 +117,7 @@ SkOpSegment* FindChase(SkTDArray<SkOpSpan*>& chase, int& tIndex, int& endIndex) const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex); SkOpSegment* segment = backPtr.fOther; tIndex = backPtr.fOtherIndex; - SkTDArray<SkOpAngle> angles; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; int done = 0; if (segment->activeAngle(tIndex, &done, &angles)) { SkOpAngle* last = angles.end() - 1; @@ -133,7 +133,7 @@ SkOpSegment* FindChase(SkTDArray<SkOpSpan*>& chase, int& tIndex, int& endIndex) if (done == angles.count()) { continue; } - SkTDArray<SkOpAngle*> sorted; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; bool sortable = SkOpSegment::SortAngles(angles, &sorted, SkOpSegment::kMayBeUnordered_SortAngleKind); int angleCount = sorted.count(); @@ -208,7 +208,7 @@ SkOpSegment* FindChase(SkTDArray<SkOpSpan*>& chase, int& tIndex, int& endIndex) } #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY -void DebugShowActiveSpans(SkTDArray<SkOpContour*>& contourList) { +void DebugShowActiveSpans(SkTArray<SkOpContour*, true>& contourList) { int index; for (index = 0; index < contourList.count(); ++ index) { contourList[index]->debugShowActiveSpans(); @@ -216,7 +216,7 @@ void DebugShowActiveSpans(SkTDArray<SkOpContour*>& contourList) { } #endif -static SkOpSegment* findSortableTop(const SkTDArray<SkOpContour*>& contourList, +static SkOpSegment* findSortableTop(const SkTArray<SkOpContour*, true>& contourList, int* index, int* endIndex, SkPoint* topLeft, bool* unsortable, bool* done, bool onlySortable) { SkOpSegment* result; @@ -253,7 +253,7 @@ static SkOpSegment* findSortableTop(const SkTDArray<SkOpContour*>& contourList, return result; } -static int rightAngleWinding(const SkTDArray<SkOpContour*>& contourList, +static int rightAngleWinding(const SkTArray<SkOpContour*, true>& contourList, SkOpSegment** current, int* index, int* endIndex, double* tHit, SkScalar* hitDx, bool* tryAgain, bool opp) { double test = 0.9; @@ -270,7 +270,7 @@ static int rightAngleWinding(const SkTDArray<SkOpContour*>& contourList, return contourWinding; } -static void skipVertical(const SkTDArray<SkOpContour*>& contourList, +static void skipVertical(const SkTArray<SkOpContour*, true>& contourList, SkOpSegment** current, int* index, int* endIndex) { if (!(*current)->isVertical(*index, *endIndex)) { return; @@ -288,7 +288,7 @@ static void skipVertical(const SkTDArray<SkOpContour*>& contourList, } } -SkOpSegment* FindSortableTop(const SkTDArray<SkOpContour*>& contourList, bool* firstContour, +SkOpSegment* FindSortableTop(const SkTArray<SkOpContour*, true>& contourList, bool* firstContour, int* indexPtr, int* endIndexPtr, SkPoint* topLeft, bool* unsortable, bool* done, bool binary) { SkOpSegment* current = findSortableTop(contourList, indexPtr, endIndexPtr, topLeft, unsortable, @@ -344,7 +344,7 @@ SkOpSegment* FindSortableTop(const SkTDArray<SkOpContour*>& contourList, bool* f return current; } -void FixOtherTIndex(SkTDArray<SkOpContour*>* contourList) { +void FixOtherTIndex(SkTArray<SkOpContour*, true>* contourList) { int contourCount = (*contourList).count(); for (int cTest = 0; cTest < contourCount; ++cTest) { SkOpContour* contour = (*contourList)[cTest]; @@ -352,7 +352,7 @@ void FixOtherTIndex(SkTDArray<SkOpContour*>* contourList) { } } -void SortSegments(SkTDArray<SkOpContour*>* contourList) { +void SortSegments(SkTArray<SkOpContour*, true>* contourList) { int contourCount = (*contourList).count(); for (int cTest = 0; cTest < contourCount; ++cTest) { SkOpContour* contour = (*contourList)[cTest]; @@ -360,7 +360,7 @@ void SortSegments(SkTDArray<SkOpContour*>* contourList) { } } -void MakeContourList(SkTArray<SkOpContour>& contours, SkTDArray<SkOpContour*>& list, +void MakeContourList(SkTArray<SkOpContour>& contours, SkTArray<SkOpContour*, true>& list, bool evenOdd, bool oppEvenOdd) { int count = contours.count(); if (count == 0) { @@ -369,7 +369,7 @@ void MakeContourList(SkTArray<SkOpContour>& contours, SkTDArray<SkOpContour*>& l for (int index = 0; index < count; ++index) { SkOpContour& contour = contours[index]; contour.setOppXor(contour.operand() ? evenOdd : oppEvenOdd); - *list.append() = &contour; + list.push_back(&contour); } SkTQSort<SkOpContour>(list.begin(), list.end() - 1); } @@ -403,7 +403,7 @@ void Assemble(const SkPathWriter& path, SkPathWriter* simple) { builder.finish(); int count = contours.count(); int outer; - SkTDArray<int> runs; // indices of partial contours + SkTArray<int, true> runs(count); // indices of partial contours for (outer = 0; outer < count; ++outer) { const SkOpContour& eContour = contours[outer]; const SkPoint& eStart = eContour.start(); @@ -422,23 +422,23 @@ void Assemble(const SkPathWriter& path, SkPathWriter* simple) { eContour.toPath(simple); continue; } - *runs.append() = outer; + runs.push_back(outer); } count = runs.count(); if (count == 0) { return; } - SkTDArray<int> sLink, eLink; - sLink.setCount(count); - eLink.setCount(count); + SkTArray<int, true> sLink, eLink; + sLink.push_back_n(count); + eLink.push_back_n(count); int rIndex, iIndex; for (rIndex = 0; rIndex < count; ++rIndex) { sLink[rIndex] = eLink[rIndex] = SK_MaxS32; } - SkTDArray<double> distances; const int ends = count * 2; // all starts and ends const int entries = (ends - 1) * count; // folded triangle : n * (n - 1) / 2 - distances.setCount(entries); + SkTArray<double, true> distances; + distances.push_back_n(entries); for (rIndex = 0; rIndex < ends - 1; ++rIndex) { outer = runs[rIndex >> 1]; const SkOpContour& oContour = contours[outer]; @@ -455,8 +455,8 @@ void Assemble(const SkPathWriter& path, SkPathWriter* simple) { distances[row + iIndex] = dist; // oStart distance from iStart } } - SkTDArray<int> sortedDist; - sortedDist.setCount(entries); + SkTArray<int, true> sortedDist; + sortedDist.push_back_n(entries); for (rIndex = 0; rIndex < entries; ++rIndex) { sortedDist[rIndex] = rIndex; } diff --git a/src/pathops/SkPathOpsCommon.h b/src/pathops/SkPathOpsCommon.h index 8bbe232fc7..569edb7e32 100644 --- a/src/pathops/SkPathOpsCommon.h +++ b/src/pathops/SkPathOpsCommon.h @@ -8,22 +8,24 @@ #define SkPathOpsCommon_DEFINED #include "SkOpContour.h" +#include "SkTDArray.h" class SkPathWriter; void Assemble(const SkPathWriter& path, SkPathWriter* simple); +// FIXME: find chase uses insert, so it can't be converted to SkTArray yet SkOpSegment* FindChase(SkTDArray<SkOpSpan*>& chase, int& tIndex, int& endIndex); -SkOpSegment* FindSortableTop(const SkTDArray<SkOpContour*>& contourList, bool* firstContour, +SkOpSegment* FindSortableTop(const SkTArray<SkOpContour*, true>& contourList, bool* firstContour, int* index, int* endIndex, SkPoint* topLeft, bool* unsortable, bool* done, bool binary); -SkOpSegment* FindUndone(SkTDArray<SkOpContour*>& contourList, int* start, int* end); -void FixOtherTIndex(SkTDArray<SkOpContour*>* contourList); -void MakeContourList(SkTArray<SkOpContour>& contours, SkTDArray<SkOpContour*>& list, +SkOpSegment* FindUndone(SkTArray<SkOpContour*, true>& contourList, int* start, int* end); +void FixOtherTIndex(SkTArray<SkOpContour*, true>* contourList); +void MakeContourList(SkTArray<SkOpContour>& contours, SkTArray<SkOpContour*, true>& list, bool evenOdd, bool oppEvenOdd); -void SortSegments(SkTDArray<SkOpContour*>* contourList); +void SortSegments(SkTArray<SkOpContour*, true>* contourList); #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY -void DebugShowActiveSpans(SkTDArray<SkOpContour*>& contourList); +void DebugShowActiveSpans(SkTArray<SkOpContour*, true>& contourList); #endif #endif diff --git a/src/pathops/SkPathOpsCubic.cpp b/src/pathops/SkPathOpsCubic.cpp index 5d77e5ab89..60dca44a27 100644 --- a/src/pathops/SkPathOpsCubic.cpp +++ b/src/pathops/SkPathOpsCubic.cpp @@ -383,8 +383,13 @@ static double interp_cubic_coords(const double* src, double t) { } SkDCubic SkDCubic::subDivide(double t1, double t2) const { - if (t1 == 0 && t2 == 1) { - return *this; + if (t1 == 0 || t2 == 1) { + if (t1 == 0 && t2 == 1) { + return *this; + } + SkDCubicPair pair = chopAt(t1 == 0 ? t2 : t1); + SkDCubic dst = t1 == 0 ? pair.first() : pair.second(); + return dst; } SkDCubic dst; double ax = dst[0].fX = interp_cubic_coords(&fPts[0].fX, t1); diff --git a/src/pathops/SkPathOpsCubic.h b/src/pathops/SkPathOpsCubic.h index 7be614290d..f07af80dcd 100644 --- a/src/pathops/SkPathOpsCubic.h +++ b/src/pathops/SkPathOpsCubic.h @@ -10,7 +10,7 @@ #include "SkPath.h" #include "SkPathOpsPoint.h" -#include "SkTDArray.h" +#include "SkTArray.h" struct SkDCubicPair { const SkDCubic& first() const { return (const SkDCubic&) pts[0]; } @@ -74,7 +74,7 @@ struct SkDCubic { } SkDPoint top(double startT, double endT) const; - void toQuadraticTs(double precision, SkTDArray<double>* ts) const; + void toQuadraticTs(double precision, SkTArray<double, true>* ts) const; SkDQuad toQuad() const; SkDPoint xyAtT(double t) const; }; diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp index f030765a61..7e1c772893 100644 --- a/src/pathops/SkPathOpsOp.cpp +++ b/src/pathops/SkPathOpsOp.cpp @@ -20,7 +20,7 @@ static SkOpSegment* findChaseOp(SkTDArray<SkOpSpan*>& chase, int& nextStart, int const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex); SkOpSegment* segment = backPtr.fOther; nextStart = backPtr.fOtherIndex; - SkTDArray<SkOpAngle> angles; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; int done = 0; if (segment->activeAngle(nextStart, &done, &angles)) { SkOpAngle* last = angles.end() - 1; @@ -36,7 +36,7 @@ static SkOpSegment* findChaseOp(SkTDArray<SkOpSpan*>& chase, int& nextStart, int if (done == angles.count()) { continue; } - SkTDArray<SkOpAngle*> sorted; + SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; bool sortable = SkOpSegment::SortAngles(angles, &sorted, SkOpSegment::kMayBeUnordered_SortAngleKind); int angleCount = sorted.count(); @@ -126,7 +126,7 @@ static bool windingIsActive(int winding, int oppWinding, int spanWinding, int op } */ -static bool bridgeOp(SkTDArray<SkOpContour*>& contourList, const SkPathOp op, +static bool bridgeOp(SkTArray<SkOpContour*, true>& contourList, const SkPathOp op, const int xorMask, const int xorOpMask, SkPathWriter* simple) { bool firstContour = true; bool unsortable = false; @@ -263,7 +263,7 @@ bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) { result->reset(); result->setFillType(fillType); const int xorOpMask = builder.xorMask(); - SkTDArray<SkOpContour*> contourList; + SkTArray<SkOpContour*, true> contourList; MakeContourList(contours, contourList, xorMask == kEvenOdd_PathOpsMask, xorOpMask == kEvenOdd_PathOpsMask); SkOpContour** currentPtr = contourList.begin(); diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp index 9a319e08ba..f89c4afcc7 100644 --- a/src/pathops/SkPathOpsSimplify.cpp +++ b/src/pathops/SkPathOpsSimplify.cpp @@ -9,7 +9,7 @@ #include "SkPathOpsCommon.h" #include "SkPathWriter.h" -static bool bridgeWinding(SkTDArray<SkOpContour*>& contourList, SkPathWriter* simple) { +static bool bridgeWinding(SkTArray<SkOpContour*, true>& contourList, SkPathWriter* simple) { bool firstContour = true; bool unsortable = false; bool topUnsortable = false; @@ -94,7 +94,7 @@ static bool bridgeWinding(SkTDArray<SkOpContour*>& contourList, SkPathWriter* si } // returns true if all edges were processed -static bool bridgeXor(SkTDArray<SkOpContour*>& contourList, SkPathWriter* simple) { +static bool bridgeXor(SkTArray<SkOpContour*, true>& contourList, SkPathWriter* simple) { SkOpSegment* current; int start, end; bool unsortable = false; @@ -161,7 +161,7 @@ bool Simplify(const SkPath& path, SkPath* result) { if (!builder.finish()) { return false; } - SkTDArray<SkOpContour*> contourList; + SkTArray<SkOpContour*, true> contourList; MakeContourList(contours, contourList, false, false); SkOpContour** currentPtr = contourList.begin(); result->setFillType(fillType); diff --git a/src/pathops/SkReduceOrder.cpp b/src/pathops/SkReduceOrder.cpp index 6d2339c276..ab85f3dd3e 100644 --- a/src/pathops/SkReduceOrder.cpp +++ b/src/pathops/SkReduceOrder.cpp @@ -425,31 +425,31 @@ int SkReduceOrder::reduce(const SkDCubic& cubic, Quadratics allowQuadratics, return 4; } -SkPath::Verb SkReduceOrder::Quad(const SkPoint a[3], SkTDArray<SkPoint>* reducePts) { +SkPath::Verb SkReduceOrder::Quad(const SkPoint a[3], SkTArray<SkPoint, true>* reducePts) { SkDQuad quad; quad.set(a); SkReduceOrder reducer; int order = reducer.reduce(quad, kFill_Style); if (order == 2) { // quad became line for (int index = 0; index < order; ++index) { - SkPoint* pt = reducePts->append(); - pt->fX = SkDoubleToScalar(reducer.fLine[index].fX); - pt->fY = SkDoubleToScalar(reducer.fLine[index].fY); + SkPoint& pt = reducePts->push_back(); + pt.fX = SkDoubleToScalar(reducer.fLine[index].fX); + pt.fY = SkDoubleToScalar(reducer.fLine[index].fY); } } return SkPathOpsPointsToVerb(order - 1); } -SkPath::Verb SkReduceOrder::Cubic(const SkPoint a[4], SkTDArray<SkPoint>* reducePts) { +SkPath::Verb SkReduceOrder::Cubic(const SkPoint a[4], SkTArray<SkPoint, true>* reducePts) { SkDCubic cubic; cubic.set(a); SkReduceOrder reducer; int order = reducer.reduce(cubic, kAllow_Quadratics, kFill_Style); if (order == 2 || order == 3) { // cubic became line or quad for (int index = 0; index < order; ++index) { - SkPoint* pt = reducePts->append(); - pt->fX = SkDoubleToScalar(reducer.fQuad[index].fX); - pt->fY = SkDoubleToScalar(reducer.fQuad[index].fY); + SkPoint& pt = reducePts->push_back(); + pt.fX = SkDoubleToScalar(reducer.fQuad[index].fX); + pt.fY = SkDoubleToScalar(reducer.fQuad[index].fY); } } return SkPathOpsPointsToVerb(order - 1); diff --git a/src/pathops/SkReduceOrder.h b/src/pathops/SkReduceOrder.h index 62b4af9367..82f8ffb143 100644 --- a/src/pathops/SkReduceOrder.h +++ b/src/pathops/SkReduceOrder.h @@ -11,7 +11,7 @@ #include "SkPathOpsCubic.h" #include "SkPathOpsLine.h" #include "SkPathOpsQuad.h" -#include "SkTDArray.h" +#include "SkTArray.h" union SkReduceOrder { enum Quadratics { @@ -27,8 +27,8 @@ union SkReduceOrder { int reduce(const SkDLine& line); int reduce(const SkDQuad& quad, Style); - static SkPath::Verb Cubic(const SkPoint pts[4], SkTDArray<SkPoint>* reducePts); - static SkPath::Verb Quad(const SkPoint pts[3], SkTDArray<SkPoint>* reducePts); + static SkPath::Verb Cubic(const SkPoint pts[4], SkTArray<SkPoint, true>* reducePts); + static SkPath::Verb Quad(const SkPoint pts[3], SkTArray<SkPoint, true>* reducePts); SkDLine fLine; SkDQuad fQuad; diff --git a/tests/PathOpsCubicIntersectionTest.cpp b/tests/PathOpsCubicIntersectionTest.cpp index b0d6bd881b..7f5f4cd040 100644 --- a/tests/PathOpsCubicIntersectionTest.cpp +++ b/tests/PathOpsCubicIntersectionTest.cpp @@ -244,7 +244,7 @@ static void oneOff(skiatest::Reporter* reporter, const SkDCubic& cubic1, const S cubic2[0].fX, cubic2[0].fY, cubic2[1].fX, cubic2[1].fY, cubic2[2].fX, cubic2[2].fY, cubic2[3].fX, cubic2[3].fY); #endif - SkTDArray<SkDQuad> quads1; + SkTArray<SkDQuad, true> quads1; CubicToQuads(cubic1, cubic1.calcPrecision(), quads1); #if ONE_OFF_DEBUG SkDebugf("computed quadratics set 1\n"); @@ -254,7 +254,7 @@ static void oneOff(skiatest::Reporter* reporter, const SkDCubic& cubic1, const S q[1].fX, q[1].fY, q[2].fX, q[2].fY); } #endif - SkTDArray<SkDQuad> quads2; + SkTArray<SkDQuad, true> quads2; CubicToQuads(cubic2, cubic2.calcPrecision(), quads2); #if ONE_OFF_DEBUG SkDebugf("computed quadratics set 2\n"); diff --git a/tests/PathOpsCubicToQuadsTest.cpp b/tests/PathOpsCubicToQuadsTest.cpp index f738e0790d..774fbae67f 100644 --- a/tests/PathOpsCubicToQuadsTest.cpp +++ b/tests/PathOpsCubicToQuadsTest.cpp @@ -18,7 +18,7 @@ static void test(skiatest::Reporter* reporter, const SkDCubic* cubics, const cha for (size_t index = firstTest; index < testCount; ++index) { const SkDCubic& cubic = cubics[index]; double precision = cubic.calcPrecision(); - SkTDArray<SkDQuad> quads; + SkTArray<SkDQuad, true> quads; CubicToQuads(cubic, precision, quads); if (quads.count() != 1 && quads.count() != 2) { SkDebugf("%s [%d] cubic to quadratics failed count=%d\n", name, static_cast<int>(index), @@ -34,7 +34,7 @@ static void test(skiatest::Reporter* reporter, const SkDQuad* quadTests, const c const SkDQuad& quad = quadTests[index]; SkDCubic cubic = quad.toCubic(); double precision = cubic.calcPrecision(); - SkTDArray<SkDQuad> quads; + SkTArray<SkDQuad, true> quads; CubicToQuads(cubic, precision, quads); if (quads.count() != 1 && quads.count() != 2) { SkDebugf("%s [%d] cubic to quadratics failed count=%d\n", name, static_cast<int>(index), @@ -50,7 +50,7 @@ static void testC(skiatest::Reporter* reporter, const SkDCubic* cubics, const ch for (size_t index = firstTest; index < testCount; ++index) { const SkDCubic& cubic = cubics[index]; double precision = cubic.calcPrecision(); - SkTDArray<SkDQuad> quads; + SkTArray<SkDQuad, true> quads; CubicToQuads(cubic, precision, quads); if (!AlmostEqualUlps(cubic[0].fX, quads[0][0].fX) || !AlmostEqualUlps(cubic[0].fY, quads[0][0].fY)) { @@ -72,7 +72,7 @@ static void testC(skiatest::Reporter* reporter, const SkDCubic(* cubics)[2], con for (int idx2 = 0; idx2 < 2; ++idx2) { const SkDCubic& cubic = cubics[index][idx2]; double precision = cubic.calcPrecision(); - SkTDArray<SkDQuad> quads; + SkTArray<SkDQuad, true> quads; CubicToQuads(cubic, precision, quads); if (!AlmostEqualUlps(cubic[0].fX, quads[0][0].fX) || !AlmostEqualUlps(cubic[0].fY, quads[0][0].fY)) { @@ -176,7 +176,7 @@ static void oneOff(skiatest::Reporter* reporter, size_t x) { SkScalar skinflect[2]; int skin = SkFindCubicInflections(skcubic, skinflect); if (false) SkDebugf("%s %d %1.9g\n", __FUNCTION__, skin, skinflect[0]); - SkTDArray<SkDQuad> quads; + SkTArray<SkDQuad, true> quads; double precision = cubic.calcPrecision(); CubicToQuads(cubic, precision, quads); if (false) SkDebugf("%s quads=%d\n", __FUNCTION__, quads.count()); diff --git a/tests/PathOpsTestCommon.cpp b/tests/PathOpsTestCommon.cpp index aab7d6ea25..4356b42414 100644 --- a/tests/PathOpsTestCommon.cpp +++ b/tests/PathOpsTestCommon.cpp @@ -7,12 +7,12 @@ #include "PathOpsTestCommon.h" #include "SkPathOpsCubic.h" -void CubicToQuads(const SkDCubic& cubic, double precision, SkTDArray<SkDQuad>& quads) { - SkTDArray<double> ts; +void CubicToQuads(const SkDCubic& cubic, double precision, SkTArray<SkDQuad, true>& quads) { + SkTArray<double, true> ts; cubic.toQuadraticTs(precision, &ts); if (ts.count() <= 0) { SkDQuad quad = cubic.toQuad(); - *quads.append() = quad; + quads.push_back(quad); return; } double tStart = 0; @@ -20,7 +20,7 @@ void CubicToQuads(const SkDCubic& cubic, double precision, SkTDArray<SkDQuad>& q const double tEnd = i1 < ts.count() ? ts[i1] : 1; SkDCubic part = cubic.subDivide(tStart, tEnd); SkDQuad quad = part.toQuad(); - *quads.append() = quad; + quads.push_back(quad); tStart = tEnd; } } diff --git a/tests/PathOpsTestCommon.h b/tests/PathOpsTestCommon.h index e4ab829577..5072ad67ae 100644 --- a/tests/PathOpsTestCommon.h +++ b/tests/PathOpsTestCommon.h @@ -8,8 +8,8 @@ #define PathOpsTestCommon_DEFINED #include "SkPathOpsQuad.h" -#include "SkTDArray.h" +#include "SkTArray.h" -void CubicToQuads(const SkDCubic& cubic, double precision, SkTDArray<SkDQuad>& quads); +void CubicToQuads(const SkDCubic& cubic, double precision, SkTArray<SkDQuad, true>& quads); #endif |