Index: src/pathops/SkPathOpsTypes.cpp |
diff --git a/src/pathops/SkPathOpsTypes.cpp b/src/pathops/SkPathOpsTypes.cpp |
index 2d7388b8822329f48ac91d512082f476835b2901..df73d11ce44e0122abf84f86318ef8011444f0b3 100644 |
--- a/src/pathops/SkPathOpsTypes.cpp |
+++ b/src/pathops/SkPathOpsTypes.cpp |
@@ -7,12 +7,30 @@ |
#include "SkFloatBits.h" |
#include "SkPathOpsTypes.h" |
+static bool arguments_denormalized(float a, float b, int epsilon) { |
+ float denomalizedCheck = FLT_EPSILON * epsilon / 2; |
+ return fabsf(a) <= denomalizedCheck && fabsf(b) <= denomalizedCheck; |
+} |
+ |
// 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) { |
if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) { |
return false; |
} |
+ if (arguments_denormalized(a, b, epsilon)) { |
+ return true; |
+ } |
+ int aBits = SkFloatAs2sCompliment(a); |
+ int bBits = SkFloatAs2sCompliment(b); |
+ // Find the difference in ULPs. |
+ return aBits < bBits + epsilon && bBits < aBits + epsilon; |
+} |
+ |
+static bool d_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. |
@@ -23,6 +41,19 @@ static bool not_equal_ulps(float a, float b, int epsilon) { |
if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) { |
return false; |
} |
+ if (arguments_denormalized(a, b, epsilon)) { |
+ return false; |
+ } |
+ int aBits = SkFloatAs2sCompliment(a); |
+ int bBits = SkFloatAs2sCompliment(b); |
+ // Find the difference in ULPs. |
+ return aBits >= bBits + epsilon || bBits >= aBits + epsilon; |
+} |
+ |
+static bool d_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. |
@@ -33,6 +64,9 @@ static bool less_ulps(float a, float b, int epsilon) { |
if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) { |
return false; |
} |
+ if (arguments_denormalized(a, b, epsilon)) { |
+ return a <= b - FLT_EPSILON * epsilon; |
+ } |
int aBits = SkFloatAs2sCompliment(a); |
int bBits = SkFloatAs2sCompliment(b); |
// Find the difference in ULPs. |
@@ -43,6 +77,9 @@ static bool less_or_equal_ulps(float a, float b, int epsilon) { |
if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) { |
return false; |
} |
+ if (arguments_denormalized(a, b, epsilon)) { |
+ return a < b + FLT_EPSILON * epsilon; |
+ } |
int aBits = SkFloatAs2sCompliment(a); |
int bBits = SkFloatAs2sCompliment(b); |
// Find the difference in ULPs. |
@@ -55,6 +92,11 @@ bool AlmostBequalUlps(float a, float b) { |
return equal_ulps(a, b, UlpsEpsilon); |
} |
+bool AlmostDequalUlps(float a, float b) { |
+ const int UlpsEpsilon = 16; |
+ return d_equal_ulps(a, b, UlpsEpsilon); |
+} |
+ |
bool AlmostEqualUlps(float a, float b) { |
const int UlpsEpsilon = 16; |
return equal_ulps(a, b, UlpsEpsilon); |
@@ -65,6 +107,11 @@ bool NotAlmostEqualUlps(float a, float b) { |
return not_equal_ulps(a, b, UlpsEpsilon); |
} |
+bool NotAlmostDequalUlps(float a, float b) { |
+ const int UlpsEpsilon = 16; |
+ return d_not_equal_ulps(a, b, UlpsEpsilon); |
+} |
+ |
bool RoughlyEqualUlps(float a, float b) { |
const int UlpsEpsilon = 256; |
return equal_ulps(a, b, UlpsEpsilon); |