From 0fdde549825bcf6931aadbc292a91403ea15bb63 Mon Sep 17 00:00:00 2001 From: Florin Malita <fmalita@chromium.org> Date: Mon, 14 Nov 2016 15:54:04 -0500 Subject: [PATCH] Fix Sk4fLinearGradient initial interval pinning For repeat/mirror mode, fx tiling needs to ensure the value doesn't collapse to the open interval value due to float arithmetic. Clamp to the next lower representable value. BUG=skia:5955 R=reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4784 Change-Id: I635394d15a80276e88c18a499f93f3047464f190 Reviewed-on: https://skia-review.googlesource.com/4784 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Florin Malita <fmalita@chromium.org> --- src/effects/gradients/Sk4fLinearGradient.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/effects/gradients/Sk4fLinearGradient.cpp b/src/effects/gradients/Sk4fLinearGradient.cpp index 29d9088425..45083f725c 100644 --- a/src/effects/gradients/Sk4fLinearGradient.cpp +++ b/src/effects/gradients/Sk4fLinearGradient.cpp @@ -92,14 +92,24 @@ SkScalar pinFx<SkShader::kClamp_TileMode>(SkScalar fx) { template<> SkScalar pinFx<SkShader::kRepeat_TileMode>(SkScalar fx) { - const SkScalar f = SkScalarFraction(fx); - return f < 0 ? f + 1 : f; + SkScalar f = SkScalarFraction(fx); + if (f < 0) { + f = SkTMin(f + 1, nextafterf(1, 0)); + } + SkASSERT(f >= 0); + SkASSERT(f < 1.0f); + return f; } template<> SkScalar pinFx<SkShader::kMirror_TileMode>(SkScalar fx) { - const SkScalar f = SkScalarMod(fx, 2.0f); - return f < 0 ? f + 2 : f; + SkScalar f = SkScalarMod(fx, 2.0f); + if (f < 0) { + f = SkTMin(f + 2, nextafterf(2, 0)); + } + SkASSERT(f >= 0); + SkASSERT(f < 2.0f); + return f; } // true when x is in [k1,k2), or [k2, k1) when the interval is reversed.