aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-06-17 14:10:36 +0000
committerGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-06-17 14:10:36 +0000
commitd892bd8ba676d34d4ce4a73ac7aad88e102fad70 (patch)
treef8b35e6d7582800ef622fc796ef4077163763a05
parentacb3d88cf84adf367c173a7a33cd3b0c379291dc (diff)
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
-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