aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/pathops/SkAddIntersections.cpp2
-rw-r--r--src/pathops/SkAddIntersections.h4
-rw-r--r--src/pathops/SkDCubicIntersection.cpp15
-rw-r--r--src/pathops/SkDCubicToQuads.cpp12
-rw-r--r--src/pathops/SkDQuadIntersection.cpp10
-rw-r--r--src/pathops/SkOpAngle.h2
-rw-r--r--src/pathops/SkOpContour.cpp8
-rw-r--r--src/pathops/SkOpContour.h10
-rw-r--r--src/pathops/SkOpEdgeBuilder.cpp22
-rw-r--r--src/pathops/SkOpEdgeBuilder.h9
-rw-r--r--src/pathops/SkOpSegment.cpp83
-rw-r--r--src/pathops/SkOpSegment.h33
-rw-r--r--src/pathops/SkPathOpsCommon.cpp44
-rw-r--r--src/pathops/SkPathOpsCommon.h14
-rw-r--r--src/pathops/SkPathOpsCubic.cpp9
-rw-r--r--src/pathops/SkPathOpsCubic.h4
-rw-r--r--src/pathops/SkPathOpsOp.cpp8
-rw-r--r--src/pathops/SkPathOpsSimplify.cpp6
-rw-r--r--src/pathops/SkReduceOrder.cpp16
-rw-r--r--src/pathops/SkReduceOrder.h6
-rw-r--r--tests/PathOpsCubicIntersectionTest.cpp4
-rw-r--r--tests/PathOpsCubicToQuadsTest.cpp10
-rw-r--r--tests/PathOpsTestCommon.cpp8
-rw-r--r--tests/PathOpsTestCommon.h4
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