aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-31 15:17:50 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-31 15:17:50 +0000
commit277c3f87656c44e0a651ed0dd56efa16c0ab07b4 (patch)
tree863b9897fe1ab6263150dfbd8d391cb0f28ea655 /src/pathops
parent2d76d933ff8ba2090229599f32bdb2b17fb7ad50 (diff)
bump picture version since SkPath has changed (conics)
enable conics in SkPath git-svn-id: http://skia.googlecode.com/svn/trunk@9370 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/pathops')
-rw-r--r--src/pathops/SkOpAngle.cpp16
-rw-r--r--src/pathops/SkOpContour.h4
-rw-r--r--src/pathops/SkOpEdgeBuilder.cpp12
-rw-r--r--src/pathops/SkOpSegment.cpp38
-rw-r--r--src/pathops/SkOpSegment.h6
-rw-r--r--src/pathops/SkPathOpsTypes.h44
-rw-r--r--src/pathops/SkReduceOrder.cpp4
7 files changed, 84 insertions, 40 deletions
diff --git a/src/pathops/SkOpAngle.cpp b/src/pathops/SkOpAngle.cpp
index aa72394043..dee2906b7f 100644
--- a/src/pathops/SkOpAngle.cpp
+++ b/src/pathops/SkOpAngle.cpp
@@ -113,11 +113,11 @@ bool SkOpAngle::operator<(const SkOpAngle& rh) const {
SkPath::Verb partVerb = useThis ? fVerb : rh.fVerb;
ray[0] = partVerb == SkPath::kCubic_Verb && part[0].approximatelyEqual(part[1]) ?
part[2] : part[1];
- ray[1].fX = (part[0].fX + part[partVerb].fX) / 2;
- ray[1].fY = (part[0].fY + part[partVerb].fY) / 2;
+ ray[1].fX = (part[0].fX + part[SkPathOpsVerbToPoints(partVerb)].fX) / 2;
+ ray[1].fY = (part[0].fY + part[SkPathOpsVerbToPoints(partVerb)].fY) / 2;
SkASSERT(ray[0] != ray[1]);
- roots = (i.*CurveRay[fVerb])(fPts, ray);
- rroots = (ri.*CurveRay[rh.fVerb])(rh.fPts, ray);
+ roots = (i.*CurveRay[SkPathOpsVerbToPoints(fVerb)])(fPts, ray);
+ rroots = (ri.*CurveRay[SkPathOpsVerbToPoints(rh.fVerb)])(rh.fPts, ray);
} while ((roots == 0 || rroots == 0) && (flip ^= true));
if (roots == 0 || rroots == 0) {
// FIXME: we don't have a solution in this case. The interim solution
@@ -314,8 +314,8 @@ void SkOpAngle::setSpans() {
fUnsortable = step > 0 ? thisSpan.fUnsortableStart : nextSpan.fUnsortableEnd;
#if DEBUG_UNSORTABLE
if (fUnsortable) {
- SkPoint iPt = (*CurvePointAtT[fVerb])(fPts, thisSpan.fT);
- SkPoint ePt = (*CurvePointAtT[fVerb])(fPts, nextSpan.fT);
+ SkPoint iPt = (*CurvePointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, thisSpan.fT);
+ SkPoint ePt = (*CurvePointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, nextSpan.fT);
SkDebugf("%s unsortable [%d] (%1.9g,%1.9g) [%d] (%1.9g,%1.9g)\n", __FUNCTION__,
index, iPt.fX, iPt.fY, fEnd, ePt.fX, ePt.fY);
}
@@ -330,8 +330,8 @@ void SkOpAngle::setSpans() {
}
#if 1
#if DEBUG_UNSORTABLE
- SkPoint iPt = (*CurvePointAtT[fVerb])(fPts, startT);
- SkPoint ePt = (*CurvePointAtT[fVerb])(fPts, endT);
+ SkPoint iPt = (*CurvePointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, startT);
+ SkPoint ePt = (*CurvePointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, endT);
SkDebugf("%s all tiny unsortable [%d] (%1.9g,%1.9g) [%d] (%1.9g,%1.9g)\n", __FUNCTION__,
fStart, iPt.fX, iPt.fY, fEnd, ePt.fX, ePt.fY);
#endif
diff --git a/src/pathops/SkOpContour.h b/src/pathops/SkOpContour.h
index c90c218344..c57fbac6ca 100644
--- a/src/pathops/SkOpContour.h
+++ b/src/pathops/SkOpContour.h
@@ -114,7 +114,7 @@ public:
const SkPoint& end() const {
const SkOpSegment& segment = fSegments.back();
- return segment.pts()[segment.verb()];
+ return segment.pts()[SkPathOpsVerbToPoints(segment.verb())];
}
void findTooCloseToCall() {
@@ -195,7 +195,7 @@ public:
int updateSegment(int index, const SkPoint* pts) {
SkOpSegment& segment = fSegments[index];
segment.updatePts(pts);
- return segment.verb() + 1;
+ return SkPathOpsVerbToPoints(segment.verb()) + 1;
}
#if DEBUG_TEST
diff --git a/src/pathops/SkOpEdgeBuilder.cpp b/src/pathops/SkOpEdgeBuilder.cpp
index 57e3b41912..5803afa11c 100644
--- a/src/pathops/SkOpEdgeBuilder.cpp
+++ b/src/pathops/SkOpEdgeBuilder.cpp
@@ -76,7 +76,7 @@ int SkOpEdgeBuilder::preFetch() {
if (verb == SkPath::kMove_Verb) {
*fPathPts.append() = pts[0];
} else if (verb >= SkPath::kLine_Verb && verb <= SkPath::kCubic_Verb) {
- fPathPts.append(verb, &pts[1]);
+ fPathPts.append(SkPathOpsVerbToPoints(verb), &pts[1]);
}
} while (verb != SkPath::kDone_Verb);
return fPathVerbs.count() - 1;
@@ -137,7 +137,7 @@ bool SkOpEdgeBuilder::walk() {
if (reducedVerb == 0) {
break; // skip degenerate points
}
- if (reducedVerb == 1) {
+ if (reducedVerb == SkPath::kLine_Verb) {
const SkPoint* lineStart = fReducePts.end() - 2;
*fExtra.append() = fCurrentContour->addLine(lineStart);
break;
@@ -150,12 +150,12 @@ bool SkOpEdgeBuilder::walk() {
if (reducedVerb == 0) {
break; // skip degenerate points
}
- if (reducedVerb == 1) {
+ if (reducedVerb == SkPath::kLine_Verb) {
const SkPoint* lineStart = fReducePts.end() - 2;
*fExtra.append() = fCurrentContour->addLine(lineStart);
break;
}
- if (reducedVerb == 2) {
+ if (reducedVerb == SkPath::kQuad_Verb) {
const SkPoint* quadStart = fReducePts.end() - 3;
*fExtra.append() = fCurrentContour->addQuad(quadStart);
break;
@@ -172,8 +172,8 @@ bool SkOpEdgeBuilder::walk() {
SkDEBUGFAIL("bad verb");
return false;
}
- fFinalCurveStart = &pointsPtr[verb - 1];
- pointsPtr += verb;
+ fFinalCurveStart = &pointsPtr[SkPathOpsVerbToPoints(verb) - 1];
+ pointsPtr += SkPathOpsVerbToPoints(verb);
SkASSERT(fCurrentContour);
}
if (fCurrentContour && !fAllowOpenContours && !close()) {
diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp
index bcefd71d60..817732e0e5 100644
--- a/src/pathops/SkOpSegment.cpp
+++ b/src/pathops/SkOpSegment.cpp
@@ -133,7 +133,7 @@ SkPoint SkOpSegment::activeLeftTop(bool onlySortable, int* firstT) const {
}
}
if (fVerb != SkPath::kLine_Verb && !lastDone) {
- SkPoint curveTop = (*CurveTop[fVerb])(fPts, lastT, span.fT);
+ SkPoint curveTop = (*CurveTop[SkPathOpsVerbToPoints(fVerb)])(fPts, lastT, span.fT);
if (topPt.fY > curveTop.fY || (topPt.fY == curveTop.fY
&& topPt.fX > curveTop.fX)) {
topPt = curveTop;
@@ -210,9 +210,9 @@ void SkOpSegment::addAngle(SkTDArray<SkOpAngle>* anglesPtr, int start, int end)
#if DEBUG_ANGLE
SkTDArray<SkOpAngle>& angles = *anglesPtr;
if (angles.count() > 1 && !fTs[start].fTiny) {
- SkPoint angle0Pt = (*CurvePointAtT[angles[0].verb()])(angles[0].pts(),
+ SkPoint angle0Pt = (*CurvePointAtT[SkPathOpsVerbToPoints(angles[0].verb())])(angles[0].pts(),
(*angles[0].spans())[angles[0].start()].fT);
- SkPoint newPt = (*CurvePointAtT[fVerb])(fPts, fTs[start].fT);
+ SkPoint newPt = (*CurvePointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, fTs[start].fT);
bool match = AlmostEqualUlps(angle0Pt.fX, newPt.fX);
match &= AlmostEqualUlps(angle0Pt.fY, newPt.fY);
if (!match) {
@@ -354,7 +354,7 @@ void SkOpSegment::addCurveTo(int start, int end, SkPathWriter* path, bool active
if (active) {
bool reverse = ePtr == fPts && start != 0;
if (reverse) {
- path->deferredMoveLine(ePtr[fVerb]);
+ path->deferredMoveLine(ePtr[SkPathOpsVerbToPoints(fVerb)]);
switch (fVerb) {
case SkPath::kLine_Verb:
path->deferredLine(ePtr[0]);
@@ -386,7 +386,7 @@ void SkOpSegment::addCurveTo(int start, int end, SkPathWriter* path, bool active
}
}
}
- // return ePtr[fVerb];
+ // return ePtr[SkPathOpsVerbToPoints(fVerb)];
}
void SkOpSegment::addLine(const SkPoint pts[2], bool operand, bool evenOdd) {
@@ -979,7 +979,7 @@ int SkOpSegment::crossedSpanY(const SkPoint& basePt, SkScalar* bestY, double* hi
SkIntersections intersections;
// OPTIMIZE: use specialty function that intersects ray with curve,
// returning t values only for curve (we don't care about t on ray)
- int pts = (intersections.*CurveVertical[fVerb])(fPts, top, bottom, basePt.fX, false);
+ int pts = (intersections.*CurveVertical[SkPathOpsVerbToPoints(fVerb)])(fPts, top, bottom, basePt.fX, false);
if (pts == 0 || (current && pts == 1)) {
return bestTIndex;
}
@@ -1003,7 +1003,7 @@ int SkOpSegment::crossedSpanY(const SkPoint& basePt, SkScalar* bestY, double* hi
|| approximately_greater_than_one(foundT)) {
continue;
}
- SkScalar testY = (*CurvePointAtT[fVerb])(fPts, foundT).fY;
+ SkScalar testY = (*CurvePointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, foundT).fY;
if (approximately_negative(testY - *bestY)
|| approximately_negative(basePt.fY - testY)) {
continue;
@@ -1012,7 +1012,7 @@ int SkOpSegment::crossedSpanY(const SkPoint& basePt, SkScalar* bestY, double* hi
return SK_MinS32; // if the intersection is edge on, wait for another one
}
if (fVerb > SkPath::kLine_Verb) {
- SkScalar dx = (*CurveSlopeAtT[fVerb])(fPts, foundT).fX;
+ SkScalar dx = (*CurveSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, foundT).fX;
if (approximately_zero(dx)) {
return SK_MinS32; // hit vertical, wait for another one
}
@@ -1738,7 +1738,7 @@ the same winding is shared by both.
void SkOpSegment::initWinding(int start, int end, double tHit, int winding, SkScalar hitDx,
int oppWind, SkScalar hitOppDx) {
SkASSERT(hitDx || !winding);
- SkScalar dx = (*CurveSlopeAtT[fVerb])(fPts, tHit).fX;
+ SkScalar dx = (*CurveSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, tHit).fX;
SkASSERT(dx);
int windVal = windValue(SkMin32(start, end));
#if DEBUG_WINDING_AT_T
@@ -2081,7 +2081,7 @@ bool SkOpSegment::clockwise(int tStart, int tEnd) const {
SkASSERT(fVerb != SkPath::kLine_Verb);
SkPoint edge[4];
subDivide(tStart, tEnd, edge);
- double sum = (edge[0].fX - edge[fVerb].fX) * (edge[0].fY + edge[fVerb].fY);
+ double sum = (edge[0].fX - edge[SkPathOpsVerbToPoints(fVerb)].fX) * (edge[0].fY + edge[SkPathOpsVerbToPoints(fVerb)].fY);
if (fVerb == SkPath::kCubic_Verb) {
SkScalar lesser = SkTMin<SkScalar>(edge[0].fY, edge[3].fY);
if (edge[1].fY < lesser && edge[2].fY < lesser) {
@@ -2095,7 +2095,7 @@ bool SkOpSegment::clockwise(int tStart, int tEnd) const {
}
}
}
- for (int idx = 0; idx < fVerb; ++idx){
+ for (int idx = 0; idx < SkPathOpsVerbToPoints(fVerb); ++idx){
sum += (edge[idx + 1].fX - edge[idx].fX) * (edge[idx + 1].fY + edge[idx].fY);
}
return sum <= 0;
@@ -2365,9 +2365,9 @@ bool SkOpSegment::SortAngles(const SkTDArray<SkOpAngle>& angles,
void SkOpSegment::subDivide(int start, int end, SkPoint edge[4]) const {
edge[0] = fTs[start].fPt;
- edge[fVerb] = fTs[end].fPt;
+ edge[SkPathOpsVerbToPoints(fVerb)] = fTs[end].fPt;
if (fVerb == SkPath::kQuad_Verb || fVerb == SkPath::kCubic_Verb) {
- SkDPoint sub[2] = {{ edge[0].fX, edge[0].fY}, {edge[fVerb].fX, edge[fVerb].fY }};
+ SkDPoint sub[2] = {{ edge[0].fX, edge[0].fY}, {edge[SkPathOpsVerbToPoints(fVerb)].fX, edge[SkPathOpsVerbToPoints(fVerb)].fY }};
if (fVerb == SkPath::kQuad_Verb) {
edge[1] = SkDQuad::SubDivide(fPts, sub[0], sub[1], fTs[start].fT,
fTs[end].fT).asSkPoint();
@@ -2382,7 +2382,7 @@ void SkOpSegment::subDivide(int start, int end, SkPoint edge[4]) const {
void SkOpSegment::subDivideBounds(int start, int end, SkPathOpsBounds* bounds) const {
SkPoint edge[4];
subDivide(start, end, edge);
- (bounds->*SetCurveBounds[fVerb])(edge);
+ (bounds->*SetCurveBounds[SkPathOpsVerbToPoints(fVerb)])(edge);
}
bool SkOpSegment::tiny(const SkOpAngle* angle) const {
@@ -2473,7 +2473,7 @@ int SkOpSegment::windingAtT(double tHit, int tIndex, bool crossOpp, SkScalar* dx
SkDebugf("%s oldWinding=%d windValue=%d", __FUNCTION__, winding, windVal);
#endif
// see if a + change in T results in a +/- change in X (compute x'(T))
- *dx = (*CurveSlopeAtT[fVerb])(fPts, tHit).fX;
+ *dx = (*CurveSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, tHit).fX;
if (fVerb > SkPath::kLine_Verb && approximately_zero(*dx)) {
*dx = fPts[2].fX - fPts[1].fX - *dx;
}
@@ -2611,7 +2611,7 @@ void SkOpSegment::debugShowActiveSpans() const {
#endif
SkDebugf("%s id=%d", __FUNCTION__, fID);
SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
- for (int vIndex = 1; vIndex <= fVerb; ++vIndex) {
+ for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
}
const SkOpSpan* span = &fTs[i];
@@ -2640,7 +2640,7 @@ void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int
const SkPoint& pt = xyAtT(&span);
SkDebugf("%s id=%d", fun, fID);
SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
- for (int vIndex = 1; vIndex <= fVerb; ++vIndex) {
+ for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
}
SkASSERT(&span == &span.fOther->fTs[span.fOtherIndex].fOther->
@@ -2661,7 +2661,7 @@ void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan& span, int
const SkPoint& pt = xyAtT(&span);
SkDebugf("%s id=%d", fun, fID);
SkDebugf(" (%1.9g,%1.9g", fPts[0].fX, fPts[0].fY);
- for (int vIndex = 1; vIndex <= fVerb; ++vIndex) {
+ for (int vIndex = 1; vIndex <= SkPathOpsVerbToPoints(fVerb); ++vIndex) {
SkDebugf(" %1.9g,%1.9g", fPts[vIndex].fX, fPts[vIndex].fY);
}
SkASSERT(&span == &span.fOther->fTs[span.fOtherIndex].fOther->
@@ -2737,7 +2737,7 @@ void SkOpSegment::debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& an
angle.unsortable() ? "*** UNSORTABLE *** " : "");
#if COMPACT_DEBUG_SORT
SkDebugf("id=%d %s start=%d (%1.9g,%,1.9g) end=%d (%1.9g,%,1.9g)",
- segment.fID, kLVerbStr[segment.fVerb],
+ segment.fID, kLVerbStr[SkPathOpsVerbToPoints(segment.fVerb)],
start, segment.xAtT(&sSpan), segment.yAtT(&sSpan), end,
segment.xAtT(&eSpan), segment.yAtT(&eSpan));
#else
diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h
index d2322c8be1..e489acfb02 100644
--- a/src/pathops/SkOpSegment.h
+++ b/src/pathops/SkOpSegment.h
@@ -54,7 +54,7 @@ public:
}
SkVector dxdy(int index) const {
- return (*CurveSlopeAtT[fVerb])(fPts, fTs[index].fT);
+ return (*CurveSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, fTs[index].fT);
}
SkScalar dy(int index) const {
@@ -82,7 +82,7 @@ public:
}
bool isVertical(int start, int end) const {
- return (*CurveIsVertical[fVerb])(fPts, start, end);
+ return (*CurveIsVertical[SkPathOpsVerbToPoints(fVerb)])(fPts, start, end);
}
bool operand() const {
@@ -206,7 +206,7 @@ public:
// used only by right angle winding finding
SkPoint xyAtT(double mid) const {
- return (*CurvePointAtT[fVerb])(fPts, mid);
+ return (*CurvePointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, mid);
}
const SkPoint& xyAtT(int index) const {
diff --git a/src/pathops/SkPathOpsTypes.h b/src/pathops/SkPathOpsTypes.h
index 5a5394a0e7..0f689d818e 100644
--- a/src/pathops/SkPathOpsTypes.h
+++ b/src/pathops/SkPathOpsTypes.h
@@ -7,10 +7,13 @@
#ifndef SkPathOpsTypes_DEFINED
#define SkPathOpsTypes_DEFINED
+#define SK_CONIC_SUPPORT_ENABLED 1
+
#include <float.h> // for FLT_EPSILON
#include <math.h> // for fabs, sqrt
#include "SkFloatingPoint.h"
+#include "SkPath.h"
#include "SkPathOps.h"
#include "SkPathOpsDebug.h"
#include "SkScalar.h"
@@ -189,6 +192,47 @@ struct SkDTriangle;
struct SkDCubic;
struct SkDRect;
+#if SK_CONIC_SUPPORT_ENABLED
+
+inline SkPath::Verb SkPathOpsPointsToVerb(int points) {
+ int verb = (1 << points) >> 1;
+#ifdef SK_DEBUG
+ switch (points) {
+ case 0: SkASSERT(SkPath::kMove_Verb == verb); break;
+ case 1: SkASSERT(SkPath::kLine_Verb == verb); break;
+ case 2: SkASSERT(SkPath::kQuad_Verb == verb); break;
+ case 3: SkASSERT(SkPath::kCubic_Verb == verb); break;
+ default: SkASSERT(!"should not be here");
+ }
+#endif
+ return (SkPath::Verb)verb;
+}
+
+inline int SkPathOpsVerbToPoints(SkPath::Verb verb) {
+ int points = (int) verb - ((int) verb >> 2);
+#ifdef SK_DEBUG
+ switch (verb) {
+ case SkPath::kLine_Verb: SkASSERT(1 == points); break;
+ case SkPath::kQuad_Verb: SkASSERT(2 == points); break;
+ case SkPath::kCubic_Verb: SkASSERT(3 == points); break;
+ default: SkASSERT(!"should not get here");
+ }
+#endif
+ return points;
+}
+
+#else
+
+inline SkPath::Verb SkOpPointsToVerb(int points) {
+ return (SkPath::Verb) (points);
+}
+
+inline SkPath::Verb SkOpVerbToPoints(SkPath::Verb verb) {
+ return (int) verb ;
+}
+
+#endif
+
inline double SkDInterp(double A, double B, double t) {
return A + (B - A) * t;
}
diff --git a/src/pathops/SkReduceOrder.cpp b/src/pathops/SkReduceOrder.cpp
index 5410d35ec9..6d2339c276 100644
--- a/src/pathops/SkReduceOrder.cpp
+++ b/src/pathops/SkReduceOrder.cpp
@@ -437,7 +437,7 @@ SkPath::Verb SkReduceOrder::Quad(const SkPoint a[3], SkTDArray<SkPoint>* reduceP
pt->fY = SkDoubleToScalar(reducer.fLine[index].fY);
}
}
- return (SkPath::Verb) (order - 1);
+ return SkPathOpsPointsToVerb(order - 1);
}
SkPath::Verb SkReduceOrder::Cubic(const SkPoint a[4], SkTDArray<SkPoint>* reducePts) {
@@ -452,5 +452,5 @@ SkPath::Verb SkReduceOrder::Cubic(const SkPoint a[4], SkTDArray<SkPoint>* reduce
pt->fY = SkDoubleToScalar(reducer.fQuad[index].fY);
}
}
- return (SkPath::Verb) (order - 1);
+ return SkPathOpsPointsToVerb(order - 1);
}