diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-05-31 15:17:50 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-05-31 15:17:50 +0000 |
commit | 277c3f87656c44e0a651ed0dd56efa16c0ab07b4 (patch) | |
tree | 863b9897fe1ab6263150dfbd8d391cb0f28ea655 /src/pathops | |
parent | 2d76d933ff8ba2090229599f32bdb2b17fb7ad50 (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.cpp | 16 | ||||
-rw-r--r-- | src/pathops/SkOpContour.h | 4 | ||||
-rw-r--r-- | src/pathops/SkOpEdgeBuilder.cpp | 12 | ||||
-rw-r--r-- | src/pathops/SkOpSegment.cpp | 38 | ||||
-rw-r--r-- | src/pathops/SkOpSegment.h | 6 | ||||
-rw-r--r-- | src/pathops/SkPathOpsTypes.h | 44 | ||||
-rw-r--r-- | src/pathops/SkReduceOrder.cpp | 4 |
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); } |