diff options
-rw-r--r-- | pixman/pixman-linear-gradient.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c index b78a260..05eaf20 100644 --- a/pixman/pixman-linear-gradient.c +++ b/pixman/pixman-linear-gradient.c @@ -65,14 +65,27 @@ floored_divrem (int64_t a, int64_t b) inline static struct quorem floored_muldivrem (int64_t a, uint64_t x, int64_t b) { - struct quorem qr; - __int128_t xa = (__int128_t)x*a; - qr.quo = xa/b; - qr.rem = xa%b; - if ((xa>=0) != (b>=0) && qr.rem) { - qr.quo -= 1; - qr.rem += b; + struct quorem qr, tmp; + int i; + + qr.quo = 0; + qr.rem = -b; + tmp = floored_divrem (a, b); + + while (x) { + if (x & 1) + qr = quoremo_add (qr, tmp, b); + tmp.quo *= 2; + tmp.rem *= 2; + if (tmp.rem >= b) { + tmp.rem -= b; + tmp.quo++; + } + x >>= 1; } + + qr.rem += b; + return qr; } |