summaryrefslogtreecommitdiff
path: root/base/gxshade6.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-05-05 10:22:51 +0100
committerRobin Watts <robin.watts@artifex.com>2016-05-05 13:15:57 +0100
commit8e1d95eea940bca0892f016cd79d6ee72a2219ba (patch)
treee7e4f0d63783c59e99fb8926d899e4dc63ea9b1c /base/gxshade6.c
parent7032b71519c04432f2c56748103bd9dfe32ac6ff (diff)
downloadghostpdl-8e1d95eea940bca0892f016cd79d6ee72a2219ba.tar.gz
Bug 696703: Shading disappears at high dpi.
The Shading doesn't disappear, it simply plots solid white. This is due to an overflow in the tensor patch calculations. (fixed + fixed + fixed)/3 can overflow. Change this to be (int64_t + int64_t + int64_t)/3. For efficiency (and improved accuracy) we postpone the /3 until the end of the series of operations that use it (where it becomes a /9).
Diffstat (limited to 'base/gxshade6.c')
-rw-r--r--base/gxshade6.c90
1 files changed, 45 insertions, 45 deletions
diff --git a/base/gxshade6.c b/base/gxshade6.c
index c88390b42..31e2aa33b 100644
--- a/base/gxshade6.c
+++ b/base/gxshade6.c
@@ -4049,7 +4049,7 @@ fill_patch(patch_fill_state_t *pfs, const tensor_patch *p, int kv, int kv0, int
code = fill_patch(pfs, &s0, kv / 2, kv0 / 2, kv1 / 2);
if (code >= 0)
code = fill_patch(pfs, &s1, kv / 2, kv0 / 2, kv1 / 2);
- /* fixme : To privide the precise filling order, we must
+ /* fixme : To provide the precise filling order, we must
decompose left and right wedges into pieces by intersections
with stripes, and fill each piece with its stripe.
A lazy wedge list would be fine for storing
@@ -4059,14 +4059,14 @@ fill_patch(patch_fill_state_t *pfs, const tensor_patch *p, int kv, int kv0, int
the wedge color appears a constant, so the filling order
isn't important. The order is important for other
self-overlapping patches, but the visible effect is
- just a slight norrowing the patch (as its lower layer appears
+ just a slight narrowing of the patch (as its lower layer appears
visible through the upper layer near the side).
This kind of dropout isn't harmful, because
- contacring self-overlapping patches are painted
+ contacting self-overlapping patches are painted
one after one by definition, so that a side coverage break
appears unavoidable by definition.
- Delaying this improvement because it is low important.
+ Delaying this improvement because it is low importance.
*/
release_colors_inline(pfs, color_stack_ptr, 2);
pfs->inside = save_inside;
@@ -4074,15 +4074,15 @@ fill_patch(patch_fill_state_t *pfs, const tensor_patch *p, int kv, int kv0, int
}
}
-static inline fixed
-lcp1(fixed p0, fixed p3)
-{ /* Computing the 1st pole of a 3d order besier, which applears a line. */
- return (p0 + p0 + p3) / 3;
+static inline int64_t
+lcp1(int64_t p0, int64_t p3)
+{ /* Computing the 1st pole of a 3d order besier, which appears a line. */
+ return (p0 + p0 + p3);
}
-static inline fixed
-lcp2(fixed p0, fixed p3)
-{ /* Computing the 2nd pole of a 3d order besier, which applears a line. */
- return (p0 + p3 + p3) / 3;
+static inline int64_t
+lcp2(int64_t p0, int64_t p3)
+{ /* Computing the 2nd pole of a 3d order besier, which appears a line. */
+ return (p0 + p3 + p3);
}
static void
@@ -4119,39 +4119,39 @@ make_tensor_patch(const patch_fill_state_t *pfs, tensor_patch *p, const patch_cu
p->pole[2][2] = interior[2];
p->pole[2][1] = interior[3];
} else {
- p->pole[1][1].x = lcp1(p->pole[0][1].x, p->pole[3][1].x) +
- lcp1(p->pole[1][0].x, p->pole[1][3].x) -
- lcp1(lcp1(p->pole[0][0].x, p->pole[0][3].x),
- lcp1(p->pole[3][0].x, p->pole[3][3].x));
- p->pole[1][2].x = lcp1(p->pole[0][2].x, p->pole[3][2].x) +
- lcp2(p->pole[1][0].x, p->pole[1][3].x) -
- lcp1(lcp2(p->pole[0][0].x, p->pole[0][3].x),
- lcp2(p->pole[3][0].x, p->pole[3][3].x));
- p->pole[2][1].x = lcp2(p->pole[0][1].x, p->pole[3][1].x) +
- lcp1(p->pole[2][0].x, p->pole[2][3].x) -
- lcp2(lcp1(p->pole[0][0].x, p->pole[0][3].x),
- lcp1(p->pole[3][0].x, p->pole[3][3].x));
- p->pole[2][2].x = lcp2(p->pole[0][2].x, p->pole[3][2].x) +
- lcp2(p->pole[2][0].x, p->pole[2][3].x) -
- lcp2(lcp2(p->pole[0][0].x, p->pole[0][3].x),
- lcp2(p->pole[3][0].x, p->pole[3][3].x));
-
- p->pole[1][1].y = lcp1(p->pole[0][1].y, p->pole[3][1].y) +
- lcp1(p->pole[1][0].y, p->pole[1][3].y) -
- lcp1(lcp1(p->pole[0][0].y, p->pole[0][3].y),
- lcp1(p->pole[3][0].y, p->pole[3][3].y));
- p->pole[1][2].y = lcp1(p->pole[0][2].y, p->pole[3][2].y) +
- lcp2(p->pole[1][0].y, p->pole[1][3].y) -
- lcp1(lcp2(p->pole[0][0].y, p->pole[0][3].y),
- lcp2(p->pole[3][0].y, p->pole[3][3].y));
- p->pole[2][1].y = lcp2(p->pole[0][1].y, p->pole[3][1].y) +
- lcp1(p->pole[2][0].y, p->pole[2][3].y) -
- lcp2(lcp1(p->pole[0][0].y, p->pole[0][3].y),
- lcp1(p->pole[3][0].y, p->pole[3][3].y));
- p->pole[2][2].y = lcp2(p->pole[0][2].y, p->pole[3][2].y) +
- lcp2(p->pole[2][0].y, p->pole[2][3].y) -
- lcp2(lcp2(p->pole[0][0].y, p->pole[0][3].y),
- lcp2(p->pole[3][0].y, p->pole[3][3].y));
+ p->pole[1][1].x = (fixed)((3*(lcp1(p->pole[0][1].x, p->pole[3][1].x) +
+ lcp1(p->pole[1][0].x, p->pole[1][3].x)) -
+ lcp1(lcp1(p->pole[0][0].x, p->pole[0][3].x),
+ lcp1(p->pole[3][0].x, p->pole[3][3].x)))/9);
+ p->pole[1][2].x = (fixed)((3*(lcp1(p->pole[0][2].x, p->pole[3][2].x) +
+ lcp2(p->pole[1][0].x, p->pole[1][3].x)) -
+ lcp1(lcp2(p->pole[0][0].x, p->pole[0][3].x),
+ lcp2(p->pole[3][0].x, p->pole[3][3].x)))/9);
+ p->pole[2][1].x = (fixed)((3*(lcp2(p->pole[0][1].x, p->pole[3][1].x) +
+ lcp1(p->pole[2][0].x, p->pole[2][3].x)) -
+ lcp2(lcp1(p->pole[0][0].x, p->pole[0][3].x),
+ lcp1(p->pole[3][0].x, p->pole[3][3].x)))/9);
+ p->pole[2][2].x = (fixed)((3*(lcp2(p->pole[0][2].x, p->pole[3][2].x) +
+ lcp2(p->pole[2][0].x, p->pole[2][3].x)) -
+ lcp2(lcp2(p->pole[0][0].x, p->pole[0][3].x),
+ lcp2(p->pole[3][0].x, p->pole[3][3].x)))/9);
+
+ p->pole[1][1].y = (fixed)((3*(lcp1(p->pole[0][1].y, p->pole[3][1].y) +
+ lcp1(p->pole[1][0].y, p->pole[1][3].y)) -
+ lcp1(lcp1(p->pole[0][0].y, p->pole[0][3].y),
+ lcp1(p->pole[3][0].y, p->pole[3][3].y)))/9);
+ p->pole[1][2].y = (fixed)((3*(lcp1(p->pole[0][2].y, p->pole[3][2].y) +
+ lcp2(p->pole[1][0].y, p->pole[1][3].y)) -
+ lcp1(lcp2(p->pole[0][0].y, p->pole[0][3].y),
+ lcp2(p->pole[3][0].y, p->pole[3][3].y)))/9);
+ p->pole[2][1].y = (fixed)((3*(lcp2(p->pole[0][1].y, p->pole[3][1].y) +
+ lcp1(p->pole[2][0].y, p->pole[2][3].y)) -
+ lcp2(lcp1(p->pole[0][0].y, p->pole[0][3].y),
+ lcp1(p->pole[3][0].y, p->pole[3][3].y)))/9);
+ p->pole[2][2].y = (fixed)((3*(lcp2(p->pole[0][2].y, p->pole[3][2].y) +
+ lcp2(p->pole[2][0].y, p->pole[2][3].y)) -
+ lcp2(lcp2(p->pole[0][0].y, p->pole[0][3].y),
+ lcp2(p->pole[3][0].y, p->pole[3][3].y)))/9);
}
patch_set_color(pfs, p->c[0][0], curve[0].vertex.cc);
patch_set_color(pfs, p->c[1][0], curve[1].vertex.cc);