Chromium Code Reviews| Index: src/core/SkPath.cpp |
| diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp |
| index 738edd9d232c79ea40e9aab40653f5396e971e2f..f8d7baa02d7bc380211c345c4c6f23cf667a8d4a 100644 |
| --- a/src/core/SkPath.cpp |
| +++ b/src/core/SkPath.cpp |
| @@ -2099,30 +2099,11 @@ static bool almost_equal(SkScalar compA, SkScalar compB) { |
| return aBits < bBits + epsilon && bBits < aBits + epsilon; |
| } |
| -static DirChange direction_change(const SkPoint& lastPt, const SkVector& curPt, |
| - const SkVector& lastVec, const SkVector& curVec) { |
| - SkScalar cross = SkPoint::CrossProduct(lastVec, curVec); |
| - |
| - SkScalar smallest = SkTMin(curPt.fX, SkTMin(curPt.fY, SkTMin(lastPt.fX, lastPt.fY))); |
| - SkScalar largest = SkTMax(curPt.fX, SkTMax(curPt.fY, SkTMax(lastPt.fX, lastPt.fY))); |
| - largest = SkTMax(largest, -smallest); |
| - |
| - if (!almost_equal(largest, largest + cross)) { |
| - int sign = SkScalarSignAsInt(cross); |
| - if (sign) { |
| - return (1 == sign) ? kRight_DirChange : kLeft_DirChange; |
| - } |
| - } |
| - |
| - if (!SkScalarNearlyZero(lastVec.lengthSqd(), SK_ScalarNearlyZero*SK_ScalarNearlyZero) && |
| - !SkScalarNearlyZero(curVec.lengthSqd(), SK_ScalarNearlyZero*SK_ScalarNearlyZero) && |
| - lastVec.dot(curVec) < 0.0f) { |
| - return kBackwards_DirChange; |
| - } |
| - |
| - return kStraight_DirChange; |
| +static bool approximately_zero_when_compared_to(double x, double y) { |
| + return x == 0 || fabs(x) < fabs(y * FLT_EPSILON); |
| } |
| + |
| // only valid for a single contour |
| struct Convexicator { |
| Convexicator() |
| @@ -2161,6 +2142,7 @@ struct Convexicator { |
| if (!SkScalarIsFinite(lengthSqd)) { |
| fIsFinite = false; |
| } else if (!SkScalarNearlyZero(lengthSqd, SK_ScalarNearlyZero*SK_ScalarNearlyZero)) { |
| + fPriorPt = fLastPt; |
| fLastPt = fCurrPt; |
| fCurrPt = pt; |
| if (++fPtCount == 2) { |
| @@ -2190,6 +2172,44 @@ struct Convexicator { |
| } |
| } |
| + DirChange directionChange(const SkVector& curVec) { |
| + SkScalar cross = SkPoint::CrossProduct(fLastVec, curVec); |
| + |
| + SkScalar smallest = SkTMin(fCurrPt.fX, SkTMin(fCurrPt.fY, SkTMin(fLastPt.fX, fLastPt.fY))); |
| + SkScalar largest = SkTMax(fCurrPt.fX, SkTMax(fCurrPt.fY, SkTMax(fLastPt.fX, fLastPt.fY))); |
| + largest = SkTMax(largest, -smallest); |
| + |
| + if (!almost_equal(largest, largest + cross)) { |
|
reed1
2015/03/02 19:38:03
can we reorg this a little, and possible save any
caryclark
2015/03/02 20:24:47
Done, but not sure it's an improvement. (When I tr
|
| + int sign = SkScalarSignAsInt(cross); |
| + if (sign) { |
| + return (1 == sign) ? kRight_DirChange : kLeft_DirChange; |
| + } |
| + } |
| + |
| + if (cross) { |
| + double dLastVecX = SkScalarToDouble(fLastPt.fX) - SkScalarToDouble(fPriorPt.fX); |
| + double dLastVecY = SkScalarToDouble(fLastPt.fY) - SkScalarToDouble(fPriorPt.fY); |
| + double dCurrVecX = SkScalarToDouble(fCurrPt.fX) - SkScalarToDouble(fLastPt.fX); |
| + double dCurrVecY = SkScalarToDouble(fCurrPt.fY) - SkScalarToDouble(fLastPt.fY); |
| + double dCross = dLastVecX * dCurrVecY - dLastVecY * dCurrVecX; |
| + if (!approximately_zero_when_compared_to(dCross, SkScalarToDouble(largest))) { |
| + int sign = SkScalarSignAsInt(SkDoubleToScalar(dCross)); |
| + if (sign) { |
| + return (1 == sign) ? kRight_DirChange : kLeft_DirChange; |
| + } |
| + } |
| + } |
| + |
| + if (!SkScalarNearlyZero(fLastVec.lengthSqd(), SK_ScalarNearlyZero*SK_ScalarNearlyZero) && |
| + !SkScalarNearlyZero(curVec.lengthSqd(), SK_ScalarNearlyZero*SK_ScalarNearlyZero) && |
| + fLastVec.dot(curVec) < 0.0f) { |
| + return kBackwards_DirChange; |
| + } |
| + |
| + return kStraight_DirChange; |
| + } |
| + |
| + |
| bool isFinite() const { |
| return fIsFinite; |
| } |
| @@ -2201,7 +2221,7 @@ struct Convexicator { |
| private: |
| void addVec(const SkVector& vec) { |
| SkASSERT(vec.fX || vec.fY); |
|
robertphillips
2015/03/02 20:29:31
this-> ?
caryclark
2015/03/02 20:48:33
Done.
|
| - DirChange dir = direction_change(fLastPt, fCurrPt, fLastVec, vec); |
| + DirChange dir = directionChange(vec); |
| switch (dir) { |
| case kLeft_DirChange: // fall through |
| case kRight_DirChange: |
| @@ -2230,6 +2250,7 @@ private: |
| } |
| } |
| + SkPoint fPriorPt; |
| SkPoint fLastPt; |
| SkPoint fCurrPt; |
| // fLastVec does not necessarily start at fLastPt. We only advance it when the cross product |