| 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;
|
| }
|
|
|