Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(630)

Unified Diff: src/core/SkPath.cpp

Issue 975523002: add double precision convex test (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add this-> for directionChange Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/PathTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkPath.cpp
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 738edd9d232c79ea40e9aab40653f5396e971e2f..b92b47f5c6b00f20315618c766b15aff89f0d609 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)) {
+ 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);
- DirChange dir = direction_change(fLastPt, fCurrPt, fLastVec, vec);
+ DirChange dir = this->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
« no previous file with comments | « no previous file | tests/PathTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698