diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp index 492f3f6ac4..fc698530ec 100644 --- a/src/core/SkMatrix.cpp +++ b/src/core/SkMatrix.cpp @@ -1568,15 +1568,21 @@ template bool get_scale_factor(SkMatrix::TypeMask results[1] = apluscdiv2 + x; } } - if (SkScalarIsNaN(results[0])) { + if (!SkScalarIsFinite(results[0])) { return false; } + if (results[0] < 0 && results[0] > -SK_ScalarNearlyZero) { + results[0] = 0; + } SkASSERT(results[0] >= 0); results[0] = SkScalarSqrt(results[0]); if (kBoth_MinMaxOrBoth == MIN_MAX_OR_BOTH) { - if (SkScalarIsNaN(results[1])) { + if (!SkScalarIsFinite(results[1])) { return false; } + if (results[1] < 0 && results[1] > -SK_ScalarNearlyZero) { + results[1] = 0; + } SkASSERT(results[1] >= 0); results[1] = SkScalarSqrt(results[1]); } diff --git a/tests/MatrixTest.cpp b/tests/MatrixTest.cpp index c4eb9c7011..414aab2f9a 100644 --- a/tests/MatrixTest.cpp +++ b/tests/MatrixTest.cpp @@ -213,11 +213,17 @@ static void test_matrix_min_max_scale(skiatest::Reporter* reporter) { big.setAll(2.39394089e+36f, 8.85347779e+36f, 9.26526204e+36f, 3.9159619e+36f, 1.44823453e+37f, 1.51559342e+37f, 0.f, 0.f, 1.f); - REPORTER_ASSERT(reporter, -SK_Scalar1 == perspX.getMinScale()); - REPORTER_ASSERT(reporter, -SK_Scalar1 == perspX.getMaxScale()); success = big.getMinMaxScales(scales); REPORTER_ASSERT(reporter, !success); + // skbug.com/4718 + SkMatrix givingNegativeNearlyZeros; + givingNegativeNearlyZeros.setAll(0.00436534f, 0.114138f, 0.37141f, + 0.00358857f, 0.0936228f, -0.0174198f, + 0.f, 0.f, 1.f); + success = givingNegativeNearlyZeros.getMinMaxScales(scales); + REPORTER_ASSERT(reporter, success && 0 == scales[0]); + SkMatrix perspY; perspY.reset(); perspY.setPerspY(-SK_Scalar1 / 500);