aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pathops/SkDCubicIntersection.cpp2
-rw-r--r--src/pathops/SkDCubicToQuads.cpp8
-rw-r--r--src/pathops/SkOpSegment.h22
-rw-r--r--src/pathops/SkReduceOrder.cpp199
-rw-r--r--src/pathops/SkReduceOrder.h8
5 files changed, 35 insertions, 204 deletions
diff --git a/src/pathops/SkDCubicIntersection.cpp b/src/pathops/SkDCubicIntersection.cpp
index 27b16341a8..bb734e19da 100644
--- a/src/pathops/SkDCubicIntersection.cpp
+++ b/src/pathops/SkDCubicIntersection.cpp
@@ -30,7 +30,7 @@ static int quadPart(const SkDCubic& cubic, double tStart, double tEnd, SkReduceO
SkDQuad quad = part.toQuad();
// FIXME: should reduceOrder be looser in this use case if quartic is going to blow up on an
// extremely shallow quadratic?
- int order = reducer->reduce(quad, SkReduceOrder::kFill_Style);
+ int order = reducer->reduce(quad);
#if DEBUG_QUAD_PART
SkDebugf("%s cubic=(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)"
" t=(%1.9g,%1.9g)\n", __FUNCTION__, cubic[0].fX, cubic[0].fY,
diff --git a/src/pathops/SkDCubicToQuads.cpp b/src/pathops/SkDCubicToQuads.cpp
index 571f1d94ae..3cf63f31d0 100644
--- a/src/pathops/SkDCubicToQuads.cpp
+++ b/src/pathops/SkDCubicToQuads.cpp
@@ -118,7 +118,7 @@ static void addTs(const SkDCubic& cubic, double precision, double start, double
// it would still take the prechopped cubic for reduce order and find cubic inflections
void SkDCubic::toQuadraticTs(double precision, SkTArray<double, true>* ts) const {
SkReduceOrder reducer;
- int order = reducer.reduce(*this, SkReduceOrder::kAllow_Quadratics, SkReduceOrder::kFill_Style);
+ int order = reducer.reduce(*this, SkReduceOrder::kAllow_Quadratics);
if (order < 3) {
return;
}
@@ -153,13 +153,11 @@ void SkDCubic::toQuadraticTs(double precision, SkTArray<double, true>* ts) const
SkDCubicPair pair;
if (inflections == 1) {
pair = chopAt(inflectT[0]);
- int orderP1 = reducer.reduce(pair.first(), SkReduceOrder::kNo_Quadratics,
- SkReduceOrder::kFill_Style);
+ int orderP1 = reducer.reduce(pair.first(), SkReduceOrder::kNo_Quadratics);
if (orderP1 < 2) {
--inflections;
} else {
- int orderP2 = reducer.reduce(pair.second(), SkReduceOrder::kNo_Quadratics,
- SkReduceOrder::kFill_Style);
+ int orderP2 = reducer.reduce(pair.second(), SkReduceOrder::kNo_Quadratics);
if (orderP2 < 2) {
--inflections;
}
diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h
index 55e516e35c..79d83b1155 100644
--- a/src/pathops/SkOpSegment.h
+++ b/src/pathops/SkOpSegment.h
@@ -183,7 +183,6 @@ public:
return result;
}
- // OPTIMIZATION: mark as debugging only if used solely by tests
double t(int tIndex) const {
return fTs[tIndex].fT;
}
@@ -212,13 +211,11 @@ public:
return fTs[tIndex].fWindValue;
}
+#if defined(SK_DEBUG) || DEBUG_WINDING
SkScalar xAtT(int index) const {
return xAtT(&fTs[index]);
}
-
- SkScalar xAtT(const SkOpSpan* span) const {
- return xyAtT(span).fX;
- }
+#endif
const SkPoint& xyAtT(const SkOpSpan* span) const {
return span->fPt;
@@ -228,13 +225,11 @@ public:
return xyAtT(&fTs[index]);
}
+#if defined(SK_DEBUG) || DEBUG_WINDING
SkScalar yAtT(int index) const {
return yAtT(&fTs[index]);
}
-
- SkScalar yAtT(const SkOpSpan* span) const {
- return xyAtT(span).fY;
- }
+#endif
bool activeAngle(int index, int* done, SkTArray<SkOpAngle, true>* angles);
SkPoint activeLeftTop(bool onlySortable, int* firstT) const;
@@ -403,6 +398,15 @@ private:
static bool UseInnerWindingReverse(int outerWinding, int innerWinding);
SkOpSpan* verifyOneWinding(const char* funName, int tIndex);
SkOpSpan* verifyOneWindingU(const char* funName, int tIndex);
+
+ SkScalar xAtT(const SkOpSpan* span) const {
+ return xyAtT(span).fX;
+ }
+
+ SkScalar yAtT(const SkOpSpan* span) const {
+ return xyAtT(span).fY;
+ }
+
void zeroSpan(SkOpSpan* span);
#if DEBUG_SWAP_TOP
diff --git a/src/pathops/SkReduceOrder.cpp b/src/pathops/SkReduceOrder.cpp
index 3dfdc9daee..ada52761b5 100644
--- a/src/pathops/SkReduceOrder.cpp
+++ b/src/pathops/SkReduceOrder.cpp
@@ -13,12 +13,6 @@ int SkReduceOrder::reduce(const SkDLine& line) {
return 1 + different;
}
-static double interp_quad_coords(double a, double b, double c, double t) {
- double ab = SkDInterp(a, b, t);
- double bc = SkDInterp(b, c, t);
- return SkDInterp(ab, bc, t);
-}
-
static int coincident_line(const SkDQuad& quad, SkDQuad& reduction) {
reduction[0] = reduction[1] = quad[0];
return 1;
@@ -28,49 +22,19 @@ static int reductionLineCount(const SkDQuad& reduction) {
return 1 + !reduction[0].approximatelyEqual(reduction[1]);
}
-static int vertical_line(const SkDQuad& quad, SkReduceOrder::Style reduceStyle,
- SkDQuad& reduction) {
- double tValue;
+static int vertical_line(const SkDQuad& quad, SkDQuad& reduction) {
reduction[0] = quad[0];
reduction[1] = quad[2];
- if (reduceStyle == SkReduceOrder::kFill_Style) {
- return reductionLineCount(reduction);
- }
- int smaller = reduction[1].fY > reduction[0].fY;
- int larger = smaller ^ 1;
- if (SkDQuad::FindExtrema(quad[0].fY, quad[1].fY, quad[2].fY, &tValue)) {
- double yExtrema = interp_quad_coords(quad[0].fY, quad[1].fY, quad[2].fY, tValue);
- if (reduction[smaller].fY > yExtrema) {
- reduction[smaller].fY = yExtrema;
- } else if (reduction[larger].fY < yExtrema) {
- reduction[larger].fY = yExtrema;
- }
- }
return reductionLineCount(reduction);
}
-static int horizontal_line(const SkDQuad& quad, SkReduceOrder::Style reduceStyle,
- SkDQuad& reduction) {
- double tValue;
+static int horizontal_line(const SkDQuad& quad, SkDQuad& reduction) {
reduction[0] = quad[0];
reduction[1] = quad[2];
- if (reduceStyle == SkReduceOrder::kFill_Style) {
- return reductionLineCount(reduction);
- }
- int smaller = reduction[1].fX > reduction[0].fX;
- int larger = smaller ^ 1;
- if (SkDQuad::FindExtrema(quad[0].fX, quad[1].fX, quad[2].fX, &tValue)) {
- double xExtrema = interp_quad_coords(quad[0].fX, quad[1].fX, quad[2].fX, tValue);
- if (reduction[smaller].fX > xExtrema) {
- reduction[smaller].fX = xExtrema;
- } else if (reduction[larger].fX < xExtrema) {
- reduction[larger].fX = xExtrema;
- }
- }
return reductionLineCount(reduction);
}
-static int check_linear(const SkDQuad& quad, SkReduceOrder::Style reduceStyle,
+static int check_linear(const SkDQuad& quad,
int minX, int maxX, int minY, int maxY, SkDQuad& reduction) {
int startIndex = 0;
int endIndex = 2;
@@ -87,47 +51,6 @@ static int check_linear(const SkDQuad& quad, SkReduceOrder::Style reduceStyle,
// four are colinear: return line formed by outside
reduction[0] = quad[0];
reduction[1] = quad[2];
- if (reduceStyle == SkReduceOrder::kFill_Style) {
- return reductionLineCount(reduction);
- }
- int sameSide;
- bool useX = quad[maxX].fX - quad[minX].fX >= quad[maxY].fY - quad[minY].fY;
- if (useX) {
- sameSide = SkDSign(quad[0].fX - quad[1].fX) + SkDSign(quad[2].fX - quad[1].fX);
- } else {
- sameSide = SkDSign(quad[0].fY - quad[1].fY) + SkDSign(quad[2].fY - quad[1].fY);
- }
- if ((sameSide & 3) != 2) {
- return reductionLineCount(reduction);
- }
- double tValue;
- int root;
- if (useX) {
- root = SkDQuad::FindExtrema(quad[0].fX, quad[1].fX, quad[2].fX, &tValue);
- } else {
- root = SkDQuad::FindExtrema(quad[0].fY, quad[1].fY, quad[2].fY, &tValue);
- }
- if (root) {
- SkDPoint extrema;
- extrema.fX = interp_quad_coords(quad[0].fX, quad[1].fX, quad[2].fX, tValue);
- extrema.fY = interp_quad_coords(quad[0].fY, quad[1].fY, quad[2].fY, tValue);
- // sameSide > 0 means mid is smaller than either [0] or [2], so replace smaller
- int replace;
- if (useX) {
- if ((extrema.fX < quad[0].fX) ^ (extrema.fX < quad[2].fX)) {
- return reductionLineCount(reduction);
- }
- replace = ((extrema.fX < quad[0].fX) | (extrema.fX < quad[2].fX))
- ^ (quad[0].fX < quad[2].fX);
- } else {
- if ((extrema.fY < quad[0].fY) ^ (extrema.fY < quad[2].fY)) {
- return reductionLineCount(reduction);
- }
- replace = ((extrema.fY < quad[0].fY) | (extrema.fY < quad[2].fY))
- ^ (quad[0].fY < quad[2].fY);
- }
- reduction[replace] = extrema;
- }
return reductionLineCount(reduction);
}
@@ -137,7 +60,7 @@ static int check_linear(const SkDQuad& quad, SkReduceOrder::Style reduceStyle,
// note that three points in a line doesn't simplify a cubic
// look for approximation with single quadratic
// save approximation with multiple quadratics for later
-int SkReduceOrder::reduce(const SkDQuad& quad, Style reduceStyle) {
+int SkReduceOrder::reduce(const SkDQuad& quad) {
int index, minX, maxX, minY, maxY;
int minXSet, minYSet;
minX = maxX = minY = maxY = 0;
@@ -168,12 +91,12 @@ int SkReduceOrder::reduce(const SkDQuad& quad, Style reduceStyle) {
if (minYSet == 0x7) { // return 1 if all four are coincident
return coincident_line(quad, fQuad);
}
- return vertical_line(quad, reduceStyle, fQuad);
+ return vertical_line(quad, fQuad);
}
if (minYSet == 0xF) { // test for horizontal line
- return horizontal_line(quad, reduceStyle, fQuad);
+ return horizontal_line(quad, fQuad);
}
- int result = check_linear(quad, reduceStyle, minX, maxX, minY, maxY, fQuad);
+ int result = check_linear(quad, minX, maxX, minY, maxY, fQuad);
if (result) {
return result;
}
@@ -183,15 +106,6 @@ int SkReduceOrder::reduce(const SkDQuad& quad, Style reduceStyle) {
////////////////////////////////////////////////////////////////////////////////////
-static double interp_cubic_coords(const double* src, double t) {
- double ab = SkDInterp(src[0], src[2], t);
- double bc = SkDInterp(src[2], src[4], t);
- double cd = SkDInterp(src[4], src[6], t);
- double abc = SkDInterp(ab, bc, t);
- double bcd = SkDInterp(bc, cd, t);
- return SkDInterp(abc, bcd, t);
-}
-
static int coincident_line(const SkDCubic& cubic, SkDCubic& reduction) {
reduction[0] = reduction[1] = cubic[0];
return 1;
@@ -201,51 +115,15 @@ static int reductionLineCount(const SkDCubic& reduction) {
return 1 + !reduction[0].approximatelyEqual(reduction[1]);
}
-static int vertical_line(const SkDCubic& cubic, SkReduceOrder::Style reduceStyle,
- SkDCubic& reduction) {
- double tValues[2];
+static int vertical_line(const SkDCubic& cubic, SkDCubic& reduction) {
reduction[0] = cubic[0];
reduction[1] = cubic[3];
- if (reduceStyle == SkReduceOrder::kFill_Style) {
- return reductionLineCount(reduction);
- }
- int smaller = reduction[1].fY > reduction[0].fY;
- int larger = smaller ^ 1;
- int roots = SkDCubic::FindExtrema(cubic[0].fY, cubic[1].fY, cubic[2].fY, cubic[3].fY, tValues);
- for (int index = 0; index < roots; ++index) {
- double yExtrema = interp_cubic_coords(&cubic[0].fY, tValues[index]);
- if (reduction[smaller].fY > yExtrema) {
- reduction[smaller].fY = yExtrema;
- continue;
- }
- if (reduction[larger].fY < yExtrema) {
- reduction[larger].fY = yExtrema;
- }
- }
return reductionLineCount(reduction);
}
-static int horizontal_line(const SkDCubic& cubic, SkReduceOrder::Style reduceStyle,
- SkDCubic& reduction) {
- double tValues[2];
+static int horizontal_line(const SkDCubic& cubic, SkDCubic& reduction) {
reduction[0] = cubic[0];
reduction[1] = cubic[3];
- if (reduceStyle == SkReduceOrder::kFill_Style) {
- return reductionLineCount(reduction);
- }
- int smaller = reduction[1].fX > reduction[0].fX;
- int larger = smaller ^ 1;
- int roots = SkDCubic::FindExtrema(cubic[0].fX, cubic[1].fX, cubic[2].fX, cubic[3].fX, tValues);
- for (int index = 0; index < roots; ++index) {
- double xExtrema = interp_cubic_coords(&cubic[0].fX, tValues[index]);
- if (reduction[smaller].fX > xExtrema) {
- reduction[smaller].fX = xExtrema;
- continue;
- }
- if (reduction[larger].fX < xExtrema) {
- reduction[larger].fX = xExtrema;
- }
- }
return reductionLineCount(reduction);
}
@@ -276,7 +154,7 @@ static int check_quadratic(const SkDCubic& cubic, SkDCubic& reduction) {
return 3;
}
-static int check_linear(const SkDCubic& cubic, SkReduceOrder::Style reduceStyle,
+static int check_linear(const SkDCubic& cubic,
int minX, int maxX, int minY, int maxY, SkDCubic& reduction) {
int startIndex = 0;
int endIndex = 3;
@@ -293,50 +171,6 @@ static int check_linear(const SkDCubic& cubic, SkReduceOrder::Style reduceStyle,
// four are colinear: return line formed by outside
reduction[0] = cubic[0];
reduction[1] = cubic[3];
- if (reduceStyle == SkReduceOrder::kFill_Style) {
- return reductionLineCount(reduction);
- }
- int sameSide1;
- int sameSide2;
- bool useX = cubic[maxX].fX - cubic[minX].fX >= cubic[maxY].fY - cubic[minY].fY;
- if (useX) {
- sameSide1 = SkDSign(cubic[0].fX - cubic[1].fX) + SkDSign(cubic[3].fX - cubic[1].fX);
- sameSide2 = SkDSign(cubic[0].fX - cubic[2].fX) + SkDSign(cubic[3].fX - cubic[2].fX);
- } else {
- sameSide1 = SkDSign(cubic[0].fY - cubic[1].fY) + SkDSign(cubic[3].fY - cubic[1].fY);
- sameSide2 = SkDSign(cubic[0].fY - cubic[2].fY) + SkDSign(cubic[3].fY - cubic[2].fY);
- }
- if (sameSide1 == sameSide2 && (sameSide1 & 3) != 2) {
- return reductionLineCount(reduction);
- }
- double tValues[2];
- int roots;
- if (useX) {
- roots = SkDCubic::FindExtrema(cubic[0].fX, cubic[1].fX, cubic[2].fX, cubic[3].fX, tValues);
- } else {
- roots = SkDCubic::FindExtrema(cubic[0].fY, cubic[1].fY, cubic[2].fY, cubic[3].fY, tValues);
- }
- for (int index = 0; index < roots; ++index) {
- SkDPoint extrema;
- extrema.fX = interp_cubic_coords(&cubic[0].fX, tValues[index]);
- extrema.fY = interp_cubic_coords(&cubic[0].fY, tValues[index]);
- // sameSide > 0 means mid is smaller than either [0] or [3], so replace smaller
- int replace;
- if (useX) {
- if ((extrema.fX < cubic[0].fX) ^ (extrema.fX < cubic[3].fX)) {
- continue;
- }
- replace = ((extrema.fX < cubic[0].fX) | (extrema.fX < cubic[3].fX))
- ^ (cubic[0].fX < cubic[3].fX);
- } else {
- if ((extrema.fY < cubic[0].fY) ^ (extrema.fY < cubic[3].fY)) {
- continue;
- }
- replace = ((extrema.fY < cubic[0].fY) | (extrema.fY < cubic[3].fY))
- ^ (cubic[0].fY < cubic[3].fY);
- }
- reduction[replace] = extrema;
- }
return reductionLineCount(reduction);
}
@@ -366,8 +200,7 @@ http://kaba.hilvi.org
// note that three points in a line doesn't simplify a cubic
// look for approximation with single quadratic
// save approximation with multiple quadratics for later
-int SkReduceOrder::reduce(const SkDCubic& cubic, Quadratics allowQuadratics,
- Style reduceStyle) {
+int SkReduceOrder::reduce(const SkDCubic& cubic, Quadratics allowQuadratics) {
int index, minX, maxX, minY, maxY;
int minXSet, minYSet;
minX = maxX = minY = maxY = 0;
@@ -408,12 +241,12 @@ int SkReduceOrder::reduce(const SkDCubic& cubic, Quadratics allowQuadratics,
if (minYSet == 0xF) { // return 1 if all four are coincident
return coincident_line(cubic, fCubic);
}
- return vertical_line(cubic, reduceStyle, fCubic);
+ return vertical_line(cubic, fCubic);
}
if (minYSet == 0xF) { // test for horizontal line
- return horizontal_line(cubic, reduceStyle, fCubic);
+ return horizontal_line(cubic, fCubic);
}
- int result = check_linear(cubic, reduceStyle, minX, maxX, minY, maxY, fCubic);
+ int result = check_linear(cubic, minX, maxX, minY, maxY, fCubic);
if (result) {
return result;
}
@@ -429,7 +262,7 @@ SkPath::Verb SkReduceOrder::Quad(const SkPoint a[3], SkPoint* reducePts) {
SkDQuad quad;
quad.set(a);
SkReduceOrder reducer;
- int order = reducer.reduce(quad, kFill_Style);
+ int order = reducer.reduce(quad);
if (order == 2) { // quad became line
for (int index = 0; index < order; ++index) {
*reducePts++ = reducer.fLine[index].asSkPoint();
@@ -442,7 +275,7 @@ SkPath::Verb SkReduceOrder::Cubic(const SkPoint a[4], SkPoint* reducePts) {
SkDCubic cubic;
cubic.set(a);
SkReduceOrder reducer;
- int order = reducer.reduce(cubic, kAllow_Quadratics, kFill_Style);
+ int order = reducer.reduce(cubic, kAllow_Quadratics);
if (order == 2 || order == 3) { // cubic became line or quad
for (int index = 0; index < order; ++index) {
*reducePts++ = reducer.fQuad[index].asSkPoint();
diff --git a/src/pathops/SkReduceOrder.h b/src/pathops/SkReduceOrder.h
index c167951f8b..4ff9a1d127 100644
--- a/src/pathops/SkReduceOrder.h
+++ b/src/pathops/SkReduceOrder.h
@@ -18,14 +18,10 @@ union SkReduceOrder {
kNo_Quadratics,
kAllow_Quadratics
};
- enum Style {
- kStroke_Style,
- kFill_Style
- };
- int reduce(const SkDCubic& cubic, Quadratics, Style);
+ int reduce(const SkDCubic& cubic, Quadratics);
int reduce(const SkDLine& line);
- int reduce(const SkDQuad& quad, Style);
+ int reduce(const SkDQuad& quad);
static SkPath::Verb Cubic(const SkPoint pts[4], SkPoint* reducePts);
static SkPath::Verb Quad(const SkPoint pts[3], SkPoint* reducePts);