Index: src/core/SkPathMeasure.cpp |
diff --git a/src/core/SkPathMeasure.cpp b/src/core/SkPathMeasure.cpp |
index 5ca5ebd1435326c02b6a9160dbe2d5b14ce4fe01..b8026746ce7869eb2bc240458fc963e073601ea6 100644 |
--- a/src/core/SkPathMeasure.cpp |
+++ b/src/core/SkPathMeasure.cpp |
@@ -7,18 +7,11 @@ |
#include "SkPathMeasure.h" |
+#include "SkPathMeasurePriv.h" |
#include "SkGeometry.h" |
#include "SkPath.h" |
#include "SkTSearch.h" |
-// these must be 0,1,2,3 since they are in our 2-bit field |
-enum { |
- kLine_SegType, |
- kQuad_SegType, |
- kCubic_SegType, |
- kConic_SegType, |
-}; |
- |
#define kMaxTValue 0x3FFFFFFF |
static inline SkScalar tValue2Scalar(int t) { |
@@ -40,6 +33,97 @@ const SkPathMeasure::Segment* SkPathMeasure::NextSegment(const Segment* seg) { |
return seg; |
} |
+void SkPathMeasure_segTo(const SkPoint pts[], unsigned segType, |
+ SkScalar startT, SkScalar stopT, SkPath* dst) { |
+ SkASSERT(startT >= 0 && startT <= SK_Scalar1); |
+ SkASSERT(stopT >= 0 && stopT <= SK_Scalar1); |
+ SkASSERT(startT <= stopT); |
+ |
+ if (startT == stopT) { |
+ /* if the dash as a zero-length on segment, add a corresponding zero-length line. |
+ The stroke code will add end caps to zero length lines as appropriate */ |
+ SkPoint lastPt; |
+ SkAssertResult(dst->getLastPt(&lastPt)); |
+ dst->lineTo(lastPt); |
+ return; |
+ } |
+ |
+ SkPoint tmp0[7], tmp1[7]; |
+ |
+ switch (segType) { |
+ case kLine_SegType: |
+ if (SK_Scalar1 == stopT) { |
+ dst->lineTo(pts[1]); |
+ } else { |
+ dst->lineTo(SkScalarInterp(pts[0].fX, pts[1].fX, stopT), |
+ SkScalarInterp(pts[0].fY, pts[1].fY, stopT)); |
+ } |
+ break; |
+ case kQuad_SegType: |
+ if (0 == startT) { |
+ if (SK_Scalar1 == stopT) { |
+ dst->quadTo(pts[1], pts[2]); |
+ } else { |
+ SkChopQuadAt(pts, tmp0, stopT); |
+ dst->quadTo(tmp0[1], tmp0[2]); |
+ } |
+ } else { |
+ SkChopQuadAt(pts, tmp0, startT); |
+ if (SK_Scalar1 == stopT) { |
+ dst->quadTo(tmp0[3], tmp0[4]); |
+ } else { |
+ SkChopQuadAt(&tmp0[2], tmp1, (stopT - startT) / (1 - startT)); |
+ dst->quadTo(tmp1[1], tmp1[2]); |
+ } |
+ } |
+ break; |
+ case kConic_SegType: { |
+ SkConic conic(pts[0], pts[2], pts[3], pts[1].fX); |
+ |
+ if (0 == startT) { |
+ if (SK_Scalar1 == stopT) { |
+ dst->conicTo(conic.fPts[1], conic.fPts[2], conic.fW); |
+ } else { |
+ SkConic tmp[2]; |
+ conic.chopAt(stopT, tmp); |
+ dst->conicTo(tmp[0].fPts[1], tmp[0].fPts[2], tmp[0].fW); |
+ } |
+ } else { |
+ if (SK_Scalar1 == stopT) { |
+ SkConic tmp1[2]; |
+ conic.chopAt(startT, tmp1); |
+ dst->conicTo(tmp1[1].fPts[1], tmp1[1].fPts[2], tmp1[1].fW); |
+ } else { |
+ SkConic tmp; |
+ conic.chopAt(startT, stopT, &tmp); |
+ dst->conicTo(tmp.fPts[1], tmp.fPts[2], tmp.fW); |
+ } |
+ } |
+ } break; |
+ case kCubic_SegType: |
+ if (0 == startT) { |
+ if (SK_Scalar1 == stopT) { |
+ dst->cubicTo(pts[1], pts[2], pts[3]); |
+ } else { |
+ SkChopCubicAt(pts, tmp0, stopT); |
+ dst->cubicTo(tmp0[1], tmp0[2], tmp0[3]); |
+ } |
+ } else { |
+ SkChopCubicAt(pts, tmp0, startT); |
+ if (SK_Scalar1 == stopT) { |
+ dst->cubicTo(tmp0[4], tmp0[5], tmp0[6]); |
+ } else { |
+ SkChopCubicAt(&tmp0[3], tmp1, (stopT - startT) / (1 - startT)); |
+ dst->cubicTo(tmp1[1], tmp1[2], tmp1[3]); |
+ } |
+ } |
+ break; |
+ default: |
+ SkDEBUGFAIL("unknown segType"); |
+ sk_throw(); |
+ } |
+} |
+ |
/////////////////////////////////////////////////////////////////////////////// |
static inline int tspan_big_enough(int tspan) { |
@@ -345,7 +429,7 @@ void SkPathMeasure::buildSegments() { |
#endif |
} |
-static void compute_pos_tan(const SkPoint pts[], int segType, |
+static void compute_pos_tan(const SkPoint pts[], unsigned segType, |
SkScalar t, SkPoint* pos, SkVector* tangent) { |
switch (segType) { |
case kLine_SegType: |
@@ -380,96 +464,6 @@ static void compute_pos_tan(const SkPoint pts[], int segType, |
} |
} |
-static void seg_to(const SkPoint pts[], int segType, |
- SkScalar startT, SkScalar stopT, SkPath* dst) { |
- SkASSERT(startT >= 0 && startT <= SK_Scalar1); |
- SkASSERT(stopT >= 0 && stopT <= SK_Scalar1); |
- SkASSERT(startT <= stopT); |
- |
- if (startT == stopT) { |
- /* if the dash as a zero-length on segment, add a corresponding zero-length line. |
- The stroke code will add end caps to zero length lines as appropriate */ |
- SkPoint lastPt; |
- SkAssertResult(dst->getLastPt(&lastPt)); |
- dst->lineTo(lastPt); |
- return; |
- } |
- |
- SkPoint tmp0[7], tmp1[7]; |
- |
- switch (segType) { |
- case kLine_SegType: |
- if (SK_Scalar1 == stopT) { |
- dst->lineTo(pts[1]); |
- } else { |
- dst->lineTo(SkScalarInterp(pts[0].fX, pts[1].fX, stopT), |
- SkScalarInterp(pts[0].fY, pts[1].fY, stopT)); |
- } |
- break; |
- case kQuad_SegType: |
- if (0 == startT) { |
- if (SK_Scalar1 == stopT) { |
- dst->quadTo(pts[1], pts[2]); |
- } else { |
- SkChopQuadAt(pts, tmp0, stopT); |
- dst->quadTo(tmp0[1], tmp0[2]); |
- } |
- } else { |
- SkChopQuadAt(pts, tmp0, startT); |
- if (SK_Scalar1 == stopT) { |
- dst->quadTo(tmp0[3], tmp0[4]); |
- } else { |
- SkChopQuadAt(&tmp0[2], tmp1, (stopT - startT) / (1 - startT)); |
- dst->quadTo(tmp1[1], tmp1[2]); |
- } |
- } |
- break; |
- case kConic_SegType: { |
- SkConic conic(pts[0], pts[2], pts[3], pts[1].fX); |
- |
- if (0 == startT) { |
- if (SK_Scalar1 == stopT) { |
- dst->conicTo(conic.fPts[1], conic.fPts[2], conic.fW); |
- } else { |
- SkConic tmp[2]; |
- conic.chopAt(stopT, tmp); |
- dst->conicTo(tmp[0].fPts[1], tmp[0].fPts[2], tmp[0].fW); |
- } |
- } else { |
- if (SK_Scalar1 == stopT) { |
- SkConic tmp1[2]; |
- conic.chopAt(startT, tmp1); |
- dst->conicTo(tmp1[1].fPts[1], tmp1[1].fPts[2], tmp1[1].fW); |
- } else { |
- SkConic tmp; |
- conic.chopAt(startT, stopT, &tmp); |
- dst->conicTo(tmp.fPts[1], tmp.fPts[2], tmp.fW); |
- } |
- } |
- } break; |
- case kCubic_SegType: |
- if (0 == startT) { |
- if (SK_Scalar1 == stopT) { |
- dst->cubicTo(pts[1], pts[2], pts[3]); |
- } else { |
- SkChopCubicAt(pts, tmp0, stopT); |
- dst->cubicTo(tmp0[1], tmp0[2], tmp0[3]); |
- } |
- } else { |
- SkChopCubicAt(pts, tmp0, startT); |
- if (SK_Scalar1 == stopT) { |
- dst->cubicTo(tmp0[4], tmp0[5], tmp0[6]); |
- } else { |
- SkChopCubicAt(&tmp0[3], tmp1, (stopT - startT) / (1 - startT)); |
- dst->cubicTo(tmp1[1], tmp1[2], tmp1[3]); |
- } |
- } |
- break; |
- default: |
- SkDEBUGFAIL("unknown segType"); |
- sk_throw(); |
- } |
-} |
//////////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
@@ -667,14 +661,14 @@ bool SkPathMeasure::getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, |
} |
if (seg->fPtIndex == stopSeg->fPtIndex) { |
- seg_to(&fPts[seg->fPtIndex], seg->fType, startT, stopT, dst); |
+ SkPathMeasure_segTo(&fPts[seg->fPtIndex], seg->fType, startT, stopT, dst); |
} else { |
do { |
- seg_to(&fPts[seg->fPtIndex], seg->fType, startT, SK_Scalar1, dst); |
+ SkPathMeasure_segTo(&fPts[seg->fPtIndex], seg->fType, startT, SK_Scalar1, dst); |
seg = SkPathMeasure::NextSegment(seg); |
startT = 0; |
} while (seg->fPtIndex < stopSeg->fPtIndex); |
- seg_to(&fPts[seg->fPtIndex], seg->fType, 0, stopT, dst); |
+ SkPathMeasure_segTo(&fPts[seg->fPtIndex], seg->fType, 0, stopT, dst); |
} |
return true; |
} |