diff options
-rw-r--r-- | fuzz/FuzzScaleToSides.cpp | 13 | ||||
-rw-r--r-- | src/core/SkScaleToSides.h | 13 | ||||
-rw-r--r-- | tests/ScaleToSidesTest.cpp | 57 |
3 files changed, 46 insertions, 37 deletions
diff --git a/fuzz/FuzzScaleToSides.cpp b/fuzz/FuzzScaleToSides.cpp index 88a2b920b0..de98562225 100644 --- a/fuzz/FuzzScaleToSides.cpp +++ b/fuzz/FuzzScaleToSides.cpp @@ -19,23 +19,22 @@ DEF_FUZZ(ScaleToSides, fuzz) { float radius1 = fuzz->nextF(), radius2 = fuzz->nextF(), width = fuzz->nextF(); - SkDebugf("%g %g %g\n", radius1, radius2, width); if (!std::isfinite(radius1) || !std::isfinite(radius2) || - !std::isfinite(width)) + !std::isfinite(width) || + radius1 <= 0.0f || + radius2 <= 0.0f || + width <= 0.0f) { fuzz->signalBoring(); } - if (width <= 0.0f) { - fuzz->signalBoring(); - } - double scale = (double)width / ((double)radius1 + (double)radius2); - if (scale >= 1.0) { + if (scale >= 1.0 || scale <= 0.0) { fuzz->signalBoring(); } + SkDebugf("%g %g %g %g\n", radius1, radius2, width, scale); ScaleToSides::AdjustRadii(width, scale, &radius1, &radius2); // TODO(mtklein): add fuzz->keepResult() diff --git a/src/core/SkScaleToSides.h b/src/core/SkScaleToSides.h index 77637a3ac2..c3fa172f67 100644 --- a/src/core/SkScaleToSides.h +++ b/src/core/SkScaleToSides.h @@ -14,7 +14,7 @@ class ScaleToSides { public: - // This code assumes that a and b fit in in a float, and therefore the resulting smaller value + // This code assumes that a and b fit in a float, and therefore the resulting smaller value // of a and b will fit in a float. The side of the rectangle may be larger than a float. // Scale must be less than or equal to the ratio limit / (*a + *b). // This code assumes that NaN and Inf are never passed in. @@ -24,8 +24,7 @@ public: *a = (float)((double)*a * scale); *b = (float)((double)*b * scale); - // This check is conservative. (double)*a + (double)*b >= (double)(*a + *b) - if ((double)*a + (double)*b > limit) { + if (*a + *b > limit) { float* minRadius = a; float* maxRadius = b; @@ -48,14 +47,16 @@ public: // reduced by one ULP to be less than limit - newMinRadius. // Note: nexttowardf is a c99 call and should be std::nexttoward, but this is not // implemented in the ARM compiler. - if ((double)newMaxRadius + (double)newMinRadius > limit) { + if (newMaxRadius + newMinRadius > limit) { newMaxRadius = nexttowardf(newMaxRadius, 0.0); } *maxRadius = newMaxRadius; } - SkASSERTF(*a >= 0.0f && *b >= 0.0f, "a: %g, b: %g", *a, *b); - SkASSERTF((*a + *b) <= limit, "limit: %g, a: %g, b: %g", limit, *a, *b); + SkASSERTF(*a >= 0.0f && *b >= 0.0f, "a: %g, b: %g, limit: %g, scale: %g", *a, *b, limit, + scale); + SkASSERTF(*a + *b <= limit, "\nlimit: %.10f, a: %.10f, b: %.10f, scale: %.20f", + limit, *a, *b, scale); } }; #endif // ScaleToSides_DEFINED diff --git a/tests/ScaleToSidesTest.cpp b/tests/ScaleToSidesTest.cpp index 60e82be529..513f0c98b6 100644 --- a/tests/ScaleToSidesTest.cpp +++ b/tests/ScaleToSidesTest.cpp @@ -7,23 +7,27 @@ #include "SkScaleToSides.h" -#include <cfloat> +#include <algorithm> #include "Test.h" DEF_TEST(ScaleToSides, reporter) { - float interestingValues[] = { - 0.0f, - 0.5f, - 1.0f, - 2.0f, - 3.0f, - 33.0f, - 33554430.0f, - 33554431.0f, - 33554464.0f, - 333333332.0f, - 333333333.0f, - 333333334.0f, + double interestingValues[] = { + // From skp bitbucket + 111.60000228881836, + 55.800003051757813, + 0.99999996581812677920, + 0.0, + 0.5, + 1.0, + 2.0, + 3.0, + 33.0, + 33554430.0, + 33554431.0, + 33554464.0, + 333333332.0, + 333333333.0, + 333333334.0, FLT_MAX, FLT_EPSILON, FLT_MIN @@ -31,16 +35,21 @@ DEF_TEST(ScaleToSides, reporter) { int numInterestingValues = (int)SK_ARRAY_COUNT(interestingValues); - for (int i = 0; i < numInterestingValues; i++) { - for (int j = 0; j < numInterestingValues; j++) { - for (int k = 0; k < numInterestingValues; k++) { - float radius1 = interestingValues[i]; - float radius2 = interestingValues[j]; - float width = interestingValues[k]; - if (width > 0.0f) { - double scale = (double)width / ((double)radius1 + (double)radius2); - if (scale < 1.0) { - ScaleToSides::AdjustRadii(width, scale, &radius1, &radius2); + for (int s = 0; s <= numInterestingValues; s++) { + for (int i = 0; i < numInterestingValues; i++) { + for (int j = 0; j < numInterestingValues; j++) { + for (int k = 0; k < numInterestingValues; k++) { + float radius1 = (float)interestingValues[i]; + float radius2 = (float)interestingValues[j]; + double width = interestingValues[k]; + double scale = width / ((double)radius1 + (double)radius2); + if (width > 0.0) { + if (s != 0) { + scale = std::min(scale, interestingValues[s-1]); + } + if (scale < 1.0 && scale > 0.0) { + ScaleToSides::AdjustRadii(width, scale, &radius1, &radius2); + } } } } |