summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pixman/pixman-linear-gradient.c27
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;
}