From d892bd8ba676d34d4ce4a73ac7aad88e102fad70 Mon Sep 17 00:00:00 2001 From: "caryclark@google.com" Date: Mon, 17 Jun 2013 14:10:36 +0000 Subject: [PATCH] convert pathops to use SkSTArray where possible. Replace SkTDArray with SkTArray and use SkSTArray when the probable array size is known. In a couple of places (spans, chases) the arrays are constructed using insert() so SkTArrays can't be used for now. Also, add an optimization to cubic subdivide if either end is zero or one. BUG= Review URL: https://codereview.chromium.org/16951017 git-svn-id: http://skia.googlecode.com/svn/trunk@9635 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/pathops/SkAddIntersections.cpp | 2 +- src/pathops/SkAddIntersections.h | 4 +- src/pathops/SkDCubicIntersection.cpp | 15 +++--- src/pathops/SkDCubicToQuads.cpp | 12 ++--- src/pathops/SkDQuadIntersection.cpp | 10 ++-- src/pathops/SkOpAngle.h | 2 + src/pathops/SkOpContour.cpp | 8 ++-- src/pathops/SkOpContour.h | 10 ++-- src/pathops/SkOpEdgeBuilder.cpp | 22 ++++----- src/pathops/SkOpEdgeBuilder.h | 9 ++-- src/pathops/SkOpSegment.cpp | 83 ++++++++++++++++++---------------- src/pathops/SkOpSegment.h | 33 ++++++++------ src/pathops/SkPathOpsCommon.cpp | 44 +++++++++--------- src/pathops/SkPathOpsCommon.h | 14 +++--- src/pathops/SkPathOpsCubic.cpp | 9 +++- src/pathops/SkPathOpsCubic.h | 4 +- src/pathops/SkPathOpsOp.cpp | 8 ++-- src/pathops/SkPathOpsSimplify.cpp | 6 +-- src/pathops/SkReduceOrder.cpp | 16 +++---- src/pathops/SkReduceOrder.h | 6 +-- tests/PathOpsCubicIntersectionTest.cpp | 4 +- tests/PathOpsCubicToQuadsTest.cpp | 10 ++-- tests/PathOpsTestCommon.cpp | 8 ++-- tests/PathOpsTestCommon.h | 4 +- 24 files changed, 181 insertions(+), 162 deletions(-) diff --git a/src/pathops/SkAddIntersections.cpp b/src/pathops/SkAddIntersections.cpp index 1884d4e..0d65446 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* contourList, int total) { +void CoincidenceCheck(SkTArray* 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 b5727a4..94ea436 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* contourList, int total); +void CoincidenceCheck(SkTArray* contourList, int total); #endif diff --git a/src/pathops/SkDCubicIntersection.cpp b/src/pathops/SkDCubicIntersection.cpp index 5106bbb..511879c 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 ts1; + SkSTArray ts1; // OPTIMIZE: if c1 == c2, call once (happens when detecting self-intersection) c1.toQuadraticTs(c1.calcPrecision() * precisionScale, &ts1); - SkTDArray ts2; + SkSTArray 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 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 b950535..571f1d9 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* ts) { +static bool add_simple_ts(const SkDCubic& cubic, double precision, SkTArray* 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* ts) { + SkTArray* 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* ts) const { +void SkDCubic::toQuadraticTs(double precision, SkTArray* 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 b6a1761..8b222f7 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 tsFound; - for (size_t index = 0; index < testCount; ++index) { + const size_t kTestCount = SK_ARRAY_COUNT(testLines); + SkSTArray 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 2800ff0..e7e5e1f 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 6266c65..f3861a1 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(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& contourList) { +static void SkOpContour::debugShowWindingValues(const SkTArray& 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 c57fbac..84f0eb1 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& contourList); + static void debugShowWindingValues(const SkTArray& contourList); #endif private: void setBounds(); SkTArray fSegments; - SkTDArray fSortedSegments; + SkTArray fSortedSegments; int fFirstSorted; - SkTDArray fCoincidences; - SkTDArray fCrosses; + SkTArray fCoincidences; + SkTArray 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 5803afa..d7f5275 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 b827a2a..2a2bf03 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 fPathPts; - SkTDArray fPathVerbs; + SkTArray fPathPts; + SkTArray fPathVerbs; SkOpContour* fCurrentContour; SkTArray& fContours; - SkTDArray fReducePts; // segments created on the fly - SkTDArray fExtra; // -1 marks new contour, > 0 offsets into contour + SkTArray fReducePts; // segments created on the fly + SkTArray 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 a9e20fd..08f4f7e 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* angles) { +bool SkOpSegment::activeAngle(int index, int* done, SkTArray* angles) { if (activeAngleInner(index, done, angles)) { return true; } @@ -63,14 +65,14 @@ bool SkOpSegment::activeAngle(int index, int* done, SkTDArray* angles return false; } -bool SkOpSegment::activeAngleOther(int index, int* done, SkTDArray* angles) { +bool SkOpSegment::activeAngleOther(int index, int* done, SkTArray* 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* angles) { +bool SkOpSegment::activeAngleInner(int index, int* done, SkTArray* 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* anglesPtr, int start, int end) const { +void SkOpSegment::addAngle(SkTArray* anglesPtr, int start, int end) const { SkASSERT(start != end); - SkOpAngle* angle = anglesPtr->append(); + SkOpAngle& angle = anglesPtr->push_back(); #if DEBUG_ANGLE - SkTDArray& angles = *anglesPtr; + SkTArray& 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* 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& outsideTs, SkOpSegment* other, +void SkOpSegment::addCoinOutsides(const SkTArray& 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 outsideTs; - SkTDArray oOutsideTs; + SkSTArray outsideTs; + SkSTArray 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* outsideTs) { + SkTArray* 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* oOutsideTs) { + SkTArray* 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 outsideTs; - SkTDArray oOutsideTs; + SkSTArray outsideTs; + SkSTArray 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* angles) const { +void SkOpSegment::addTwoAngles(int start, int end, SkTArray* 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* angles, bool includeOpp) const { +void SkOpSegment::buildAngles(int index, SkTArray* 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* angles, bool incl && precisely_negative(fTs[index].fT - referenceT)); } -void SkOpSegment::buildAnglesInner(int index, SkTDArray* angles) const { +void SkOpSegment::buildAnglesInner(int index, SkTArray* 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* angles) cons } int SkOpSegment::computeSum(int startIndex, int endIndex, bool binary) { - SkTDArray angles; + SkSTArray 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 sorted; + SkSTArray 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* chase, int* nextStart return other; } // more than one viable candidate -- measure angles to find best - SkTDArray angles; + SkSTArray angles; SkASSERT(startIndex - endIndex != 0); SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); addTwoAngles(startIndex, end, &angles); buildAngles(end, &angles, true); - SkTDArray sorted; + SkSTArray 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* chase, int* next return other; } // more than one viable candidate -- measure angles to find best - SkTDArray angles; + SkSTArray angles; SkASSERT(startIndex - endIndex != 0); SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); addTwoAngles(startIndex, end, &angles); buildAngles(end, &angles, true); - SkTDArray sorted; + SkSTArray 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 angles; + SkSTArray angles; SkASSERT(startIndex - endIndex != 0); SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); addTwoAngles(startIndex, end, &angles); buildAngles(end, &angles, false); - SkTDArray sorted; + SkSTArray 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& sorted, int start, int end) { +int SkOpSegment::findStartingEdge(const SkTArray& 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 angles; + SkSTArray angles; SkASSERT(firstT - end != 0); addTwoAngles(end, firstT, &angles); buildAngles(firstT, &angles, true); - SkTDArray sorted; + SkSTArray 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& angles, SkTDArray* angleList, +bool SkOpSegment::SortAngles(const SkTArray& angles, + SkTArray* 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(&angle); + angleList->push_back(const_cast(&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* outsideTs, double end, double start) { +void SkOpSegment::TrackOutside(SkTArray* 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& angles, int first, - const int contourWinding, const int oppContourWinding) const { +void SkOpSegment::debugShowSort(const char* fun, const SkTArray& 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& an } while (index != first); } -void SkOpSegment::debugShowSort(const char* fun, const SkTDArray& angles, int first) { +void SkOpSegment::debugShowSort(const char* fun, const SkTArray& 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 slots; - slots.setCount(slotCount * 2); + SkTArray 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 b26bad1..94efcb5 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* angles); + bool activeAngle(int index, int* done, SkTArray* 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& angles, SkTDArray* angleList, + static bool SortAngles(const SkTArray& angles, + SkTArray* 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& angles, int first, + void debugShowSort(const char* fun, const SkTArray& angles, int first, const int contourWinding, const int oppContourWinding) const; - void debugShowSort(const char* fun, const SkTDArray& angles, int first); + void debugShowSort(const char* fun, const SkTArray& angles, int first); #endif #if DEBUG_CONCIDENT void debugShowTs() const; @@ -327,25 +329,25 @@ public: #endif private: - bool activeAngleOther(int index, int* done, SkTDArray* angles); - bool activeAngleInner(int index, int* done, SkTDArray* angles); - void addAngle(SkTDArray* angles, int start, int end) const; + bool activeAngleOther(int index, int* done, SkTArray* angles); + bool activeAngleInner(int index, int* done, SkTArray* angles); + void addAngle(SkTArray* angles, int start, int end) const; void addCancelOutsides(double tStart, double oStart, SkOpSegment* other, double oEnd); - void addCoinOutsides(const SkTDArray& outsideTs, SkOpSegment* other, double oEnd); - void addTwoAngles(int start, int end, SkTDArray* angles) const; + void addCoinOutsides(const SkTArray& outsideTs, SkOpSegment* other, double oEnd); + void addTwoAngles(int start, int end, SkTArray* 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* angles, bool includeOpp) const; - void buildAnglesInner(int index, SkTDArray* angles) const; + void buildAngles(int index, SkTArray* angles, bool includeOpp) const; + void buildAnglesInner(int index, SkTArray* angles) const; int bumpCoincidentThis(const SkOpSpan& oTest, bool opp, int index, - SkTDArray* outsideTs); + SkTArray* outsideTs); int bumpCoincidentOther(const SkOpSpan& test, double oEndT, int& oIndex, - SkTDArray* oOutsideTs); + SkTArray* 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& sorted, int start, int end); + int findStartingEdge(const SkTArray& 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* outsideTs, double end, double start); + static void TrackOutside(SkTArray* 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 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 9215cbc..0fa5ce0 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& contourList, SkOpSegment** currentPtr, +static int contourRangeCheckY(const SkTArray& 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& contourList, int* start, int* end) { +SkOpSegment* FindUndone(SkTArray& 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& chase, int& tIndex, int& endIndex) const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex); SkOpSegment* segment = backPtr.fOther; tIndex = backPtr.fOtherIndex; - SkTDArray angles; + SkSTArray angles; int done = 0; if (segment->activeAngle(tIndex, &done, &angles)) { SkOpAngle* last = angles.end() - 1; @@ -133,7 +133,7 @@ SkOpSegment* FindChase(SkTDArray& chase, int& tIndex, int& endIndex) if (done == angles.count()) { continue; } - SkTDArray sorted; + SkSTArray sorted; bool sortable = SkOpSegment::SortAngles(angles, &sorted, SkOpSegment::kMayBeUnordered_SortAngleKind); int angleCount = sorted.count(); @@ -208,7 +208,7 @@ SkOpSegment* FindChase(SkTDArray& chase, int& tIndex, int& endIndex) } #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY -void DebugShowActiveSpans(SkTDArray& contourList) { +void DebugShowActiveSpans(SkTArray& contourList) { int index; for (index = 0; index < contourList.count(); ++ index) { contourList[index]->debugShowActiveSpans(); @@ -216,7 +216,7 @@ void DebugShowActiveSpans(SkTDArray& contourList) { } #endif -static SkOpSegment* findSortableTop(const SkTDArray& contourList, +static SkOpSegment* findSortableTop(const SkTArray& contourList, int* index, int* endIndex, SkPoint* topLeft, bool* unsortable, bool* done, bool onlySortable) { SkOpSegment* result; @@ -253,7 +253,7 @@ static SkOpSegment* findSortableTop(const SkTDArray& contourList, return result; } -static int rightAngleWinding(const SkTDArray& contourList, +static int rightAngleWinding(const SkTArray& 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& contourList, return contourWinding; } -static void skipVertical(const SkTDArray& contourList, +static void skipVertical(const SkTArray& contourList, SkOpSegment** current, int* index, int* endIndex) { if (!(*current)->isVertical(*index, *endIndex)) { return; @@ -288,7 +288,7 @@ static void skipVertical(const SkTDArray& contourList, } } -SkOpSegment* FindSortableTop(const SkTDArray& contourList, bool* firstContour, +SkOpSegment* FindSortableTop(const SkTArray& 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& contourList, bool* f return current; } -void FixOtherTIndex(SkTDArray* contourList) { +void FixOtherTIndex(SkTArray* contourList) { int contourCount = (*contourList).count(); for (int cTest = 0; cTest < contourCount; ++cTest) { SkOpContour* contour = (*contourList)[cTest]; @@ -352,7 +352,7 @@ void FixOtherTIndex(SkTDArray* contourList) { } } -void SortSegments(SkTDArray* contourList) { +void SortSegments(SkTArray* contourList) { int contourCount = (*contourList).count(); for (int cTest = 0; cTest < contourCount; ++cTest) { SkOpContour* contour = (*contourList)[cTest]; @@ -360,7 +360,7 @@ void SortSegments(SkTDArray* contourList) { } } -void MakeContourList(SkTArray& contours, SkTDArray& list, +void MakeContourList(SkTArray& contours, SkTArray& list, bool evenOdd, bool oppEvenOdd) { int count = contours.count(); if (count == 0) { @@ -369,7 +369,7 @@ void MakeContourList(SkTArray& contours, SkTDArray& 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(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 runs; // indices of partial contours + SkTArray 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 sLink, eLink; - sLink.setCount(count); - eLink.setCount(count); + SkTArray 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 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 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 sortedDist; - sortedDist.setCount(entries); + SkTArray 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 8bbe232..569edb7 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& chase, int& tIndex, int& endIndex); -SkOpSegment* FindSortableTop(const SkTDArray& contourList, bool* firstContour, +SkOpSegment* FindSortableTop(const SkTArray& contourList, bool* firstContour, int* index, int* endIndex, SkPoint* topLeft, bool* unsortable, bool* done, bool binary); -SkOpSegment* FindUndone(SkTDArray& contourList, int* start, int* end); -void FixOtherTIndex(SkTDArray* contourList); -void MakeContourList(SkTArray& contours, SkTDArray& list, +SkOpSegment* FindUndone(SkTArray& contourList, int* start, int* end); +void FixOtherTIndex(SkTArray* contourList); +void MakeContourList(SkTArray& contours, SkTArray& list, bool evenOdd, bool oppEvenOdd); -void SortSegments(SkTDArray* contourList); +void SortSegments(SkTArray* contourList); #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY -void DebugShowActiveSpans(SkTDArray& contourList); +void DebugShowActiveSpans(SkTArray& contourList); #endif #endif diff --git a/src/pathops/SkPathOpsCubic.cpp b/src/pathops/SkPathOpsCubic.cpp index 5d77e5a..60dca44 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 7be6142..f07af80 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* ts) const; + void toQuadraticTs(double precision, SkTArray* ts) const; SkDQuad toQuad() const; SkDPoint xyAtT(double t) const; }; diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp index f030765..7e1c772 100644 --- a/src/pathops/SkPathOpsOp.cpp +++ b/src/pathops/SkPathOpsOp.cpp @@ -20,7 +20,7 @@ static SkOpSegment* findChaseOp(SkTDArray& chase, int& nextStart, int const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex); SkOpSegment* segment = backPtr.fOther; nextStart = backPtr.fOtherIndex; - SkTDArray angles; + SkSTArray angles; int done = 0; if (segment->activeAngle(nextStart, &done, &angles)) { SkOpAngle* last = angles.end() - 1; @@ -36,7 +36,7 @@ static SkOpSegment* findChaseOp(SkTDArray& chase, int& nextStart, int if (done == angles.count()) { continue; } - SkTDArray sorted; + SkSTArray 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& contourList, const SkPathOp op, +static bool bridgeOp(SkTArray& 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 contourList; + SkTArray 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 9a319e0..f89c4af 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& contourList, SkPathWriter* simple) { +static bool bridgeWinding(SkTArray& contourList, SkPathWriter* simple) { bool firstContour = true; bool unsortable = false; bool topUnsortable = false; @@ -94,7 +94,7 @@ static bool bridgeWinding(SkTDArray& contourList, SkPathWriter* si } // returns true if all edges were processed -static bool bridgeXor(SkTDArray& contourList, SkPathWriter* simple) { +static bool bridgeXor(SkTArray& 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 contourList; + SkTArray 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 6d2339c..ab85f3d 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* reducePts) { +SkPath::Verb SkReduceOrder::Quad(const SkPoint a[3], SkTArray* 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* reducePts) { +SkPath::Verb SkReduceOrder::Cubic(const SkPoint a[4], SkTArray* 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 62b4af9..82f8ffb 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* reducePts); - static SkPath::Verb Quad(const SkPoint pts[3], SkTDArray* reducePts); + static SkPath::Verb Cubic(const SkPoint pts[4], SkTArray* reducePts); + static SkPath::Verb Quad(const SkPoint pts[3], SkTArray* reducePts); SkDLine fLine; SkDQuad fQuad; diff --git a/tests/PathOpsCubicIntersectionTest.cpp b/tests/PathOpsCubicIntersectionTest.cpp index b0d6bd8..7f5f4cd 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 quads1; + SkTArray 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 quads2; + SkTArray 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 f738e07..774fbae 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 quads; + SkTArray 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(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 quads; + SkTArray 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(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 quads; + SkTArray 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 quads; + SkTArray 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 quads; + SkTArray 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 aab7d6e..4356b42 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& quads) { - SkTDArray ts; +void CubicToQuads(const SkDCubic& cubic, double precision, SkTArray& quads) { + SkTArray 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& 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 e4ab829..5072ad6 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& quads); +void CubicToQuads(const SkDCubic& cubic, double precision, SkTArray& quads); #endif -- 2.7.4