| Index: src/pathops/SkPathOpsTypes.cpp
|
| diff --git a/src/pathops/SkPathOpsTypes.cpp b/src/pathops/SkPathOpsTypes.cpp
|
| index 8135c57025757fa0b2f2d815a052b39e53b5e7e5..2d7388b8822329f48ac91d512082f476835b2901 100644
|
| --- a/src/pathops/SkPathOpsTypes.cpp
|
| +++ b/src/pathops/SkPathOpsTypes.cpp
|
| @@ -7,34 +7,52 @@
|
| #include "SkFloatBits.h"
|
| #include "SkPathOpsTypes.h"
|
|
|
| -
|
| -
|
| // from http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
|
| // FIXME: move to SkFloatBits.h
|
| static bool equal_ulps(float a, float b, int epsilon) {
|
| - SkFloatIntUnion floatIntA, floatIntB;
|
| - floatIntA.fFloat = a;
|
| - floatIntB.fFloat = b;
|
| - // Different signs means they do not match.
|
| - if ((floatIntA.fSignBitInt < 0) != (floatIntB.fSignBitInt < 0)) {
|
| - // Check for equality to make sure +0 == -0
|
| - return a == b;
|
| + if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) {
|
| + return false;
|
| }
|
| + int aBits = SkFloatAs2sCompliment(a);
|
| + int bBits = SkFloatAs2sCompliment(b);
|
| // Find the difference in ULPs.
|
| - int ulpsDiff = abs(floatIntA.fSignBitInt - floatIntB.fSignBitInt);
|
| - return ulpsDiff <= epsilon;
|
| + return aBits < bBits + epsilon && bBits < aBits + epsilon;
|
| +}
|
| +
|
| +static bool not_equal_ulps(float a, float b, int epsilon) {
|
| + if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) {
|
| + return false;
|
| + }
|
| + int aBits = SkFloatAs2sCompliment(a);
|
| + int bBits = SkFloatAs2sCompliment(b);
|
| + // Find the difference in ULPs.
|
| + return aBits >= bBits + epsilon || bBits >= aBits + epsilon;
|
| }
|
|
|
| static bool less_ulps(float a, float b, int epsilon) {
|
| - SkFloatIntUnion floatIntA, floatIntB;
|
| - floatIntA.fFloat = a;
|
| - floatIntB.fFloat = b;
|
| - // Check different signs with float epsilon since we only care if they're both close to 0.
|
| - if ((floatIntA.fSignBitInt < 0) != (floatIntB.fSignBitInt < 0)) {
|
| - return a <= b + FLT_EPSILON * epsilon;
|
| + if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) {
|
| + return false;
|
| }
|
| + int aBits = SkFloatAs2sCompliment(a);
|
| + int bBits = SkFloatAs2sCompliment(b);
|
| // Find the difference in ULPs.
|
| - return floatIntA.fSignBitInt <= floatIntB.fSignBitInt + epsilon;
|
| + return aBits <= bBits - epsilon;
|
| +}
|
| +
|
| +static bool less_or_equal_ulps(float a, float b, int epsilon) {
|
| + if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) {
|
| + return false;
|
| + }
|
| + int aBits = SkFloatAs2sCompliment(a);
|
| + int bBits = SkFloatAs2sCompliment(b);
|
| + // Find the difference in ULPs.
|
| + return aBits < bBits + epsilon;
|
| +}
|
| +
|
| +// equality using the same error term as between
|
| +bool AlmostBequalUlps(float a, float b) {
|
| + const int UlpsEpsilon = 2;
|
| + return equal_ulps(a, b, UlpsEpsilon);
|
| }
|
|
|
| bool AlmostEqualUlps(float a, float b) {
|
| @@ -42,18 +60,36 @@ bool AlmostEqualUlps(float a, float b) {
|
| return equal_ulps(a, b, UlpsEpsilon);
|
| }
|
|
|
| +bool NotAlmostEqualUlps(float a, float b) {
|
| + const int UlpsEpsilon = 16;
|
| + return not_equal_ulps(a, b, UlpsEpsilon);
|
| +}
|
| +
|
| bool RoughlyEqualUlps(float a, float b) {
|
| const int UlpsEpsilon = 256;
|
| return equal_ulps(a, b, UlpsEpsilon);
|
| }
|
|
|
| bool AlmostBetweenUlps(float a, float b, float c) {
|
| - const int UlpsEpsilon = 1;
|
| - return a <= c ? less_ulps(a, b, UlpsEpsilon) && less_ulps(b, c, UlpsEpsilon)
|
| - : less_ulps(b, a, UlpsEpsilon) && less_ulps(c, b, UlpsEpsilon);
|
| + const int UlpsEpsilon = 2;
|
| + return a <= c ? less_or_equal_ulps(a, b, UlpsEpsilon) && less_or_equal_ulps(b, c, UlpsEpsilon)
|
| + : less_or_equal_ulps(b, a, UlpsEpsilon) && less_or_equal_ulps(c, b, UlpsEpsilon);
|
| +}
|
| +
|
| +bool AlmostLessUlps(float a, float b) {
|
| + const int UlpsEpsilon = 16;
|
| + return less_ulps(a, b, UlpsEpsilon);
|
| +}
|
| +
|
| +bool AlmostLessOrEqualUlps(float a, float b) {
|
| + const int UlpsEpsilon = 16;
|
| + return less_or_equal_ulps(a, b, UlpsEpsilon);
|
| }
|
|
|
| int UlpsDistance(float a, float b) {
|
| + if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) {
|
| + return SK_MaxS32;
|
| + }
|
| SkFloatIntUnion floatIntA, floatIntB;
|
| floatIntA.fFloat = a;
|
| floatIntB.fFloat = b;
|
|
|