diff options
Diffstat (limited to 'src/effects')
-rw-r--r-- | src/effects/gradients/SkClampRange.cpp | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/effects/gradients/SkClampRange.cpp b/src/effects/gradients/SkClampRange.cpp index f820a03710..efc93959d1 100644 --- a/src/effects/gradients/SkClampRange.cpp +++ b/src/effects/gradients/SkClampRange.cpp @@ -38,6 +38,22 @@ static bool sk_64_smul_check(int64_t count, int64_t dx, int64_t* result) { return true; } +static bool sk_64_sadd_check(int64_t a, int64_t b, int64_t* result) { + if (a > 0) { + if (b > std::numeric_limits<int64_t>::max() - a) { + return false; + } + } else { + if (b < std::numeric_limits<int64_t>::min() - a) { + return false; + } + } + + *result = a + b; + return true; +} + + /* * returns [0..count] for the number of steps (<= count) for which x0 <= edge * given each step is followed by x0 += dx @@ -87,16 +103,15 @@ void SkClampRange::init(SkGradFixed fx0, SkGradFixed dx0, int count, int v0, int int64_t dx = dx0; // start with ex equal to the last computed value - int64_t count_times_dx; - if (!sk_64_smul_check(count - 1, dx, &count_times_dx)) { + int64_t count_times_dx, ex; + if (!sk_64_smul_check(count - 1, dx, &count_times_dx) || + !sk_64_sadd_check(fx, count_times_dx, &ex)) { // we can't represent the computed end in 32.32, so just draw something (first color) fCount1 = fCount2 = 0; fCount0 = count; return; } - int64_t ex = fx + (count - 1) * dx; - if ((uint64_t)(fx | ex) <= kFracMax_SkGradFixed) { fCount0 = fCount2 = 0; fCount1 = count; |