summaryrefslogtreecommitdiff
path: root/base/gxclip.c
diff options
context:
space:
mode:
authorRay Johnston <ray.johnston@artifex.com>2019-08-07 10:24:49 -0700
committerRay Johnston <ray.johnston@artifex.com>2019-08-07 10:40:43 -0700
commitd8f05309d5e54b6e75c2b78af9c0bcf5f62b493c (patch)
treebc5ff62a3d589075158e4e034e9b013f956839ab /base/gxclip.c
parentff856d0c44ce7d3f4d204f4a405857a6a6672a80 (diff)
downloadghostpdl-d8f05309d5e54b6e75c2b78af9c0bcf5f62b493c.tar.gz
Bug 701308: Fix clip transpose logic that resulted in garbled output.
This seems like it should have showed up earlier, but when the clip rectangle list was transposed, the _t1 and _s1 clip_fill_rectangle_ functions were confused about the coordinates being sent to the target device fill_rectangle. Also during debug, I found that if the clip list consisted of more than a single rectangle, clip_get_clipping_box was only using the first rect, rather than accumulating the outer_box for the entire list.
Diffstat (limited to 'base/gxclip.c')
-rw-r--r--base/gxclip.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/base/gxclip.c b/base/gxclip.c
index fbce42c5e..47a199653 100644
--- a/base/gxclip.c
+++ b/base/gxclip.c
@@ -491,7 +491,7 @@ clip_fill_rectangle_t1(gx_device * dev, int x, int y, int w, int h,
INCR(in_y);
if (x >= rptr->xmin && xe <= rptr->xmax) {
INCR(in);
- return dev_proc(tdev, fill_rectangle)(tdev, x, y, w, h, color);
+ return dev_proc(tdev, fill_rectangle)(tdev, y, x, w, h, color);
}
else if ((rptr->prev == 0 || rptr->prev->ymax != rptr->ymax) &&
(rptr->next == 0 || rptr->next->ymax != rptr->ymax)
@@ -503,7 +503,7 @@ clip_fill_rectangle_t1(gx_device * dev, int x, int y, int w, int h,
xe = rptr->xmax;
if (x >= xe)
return 0;
- return dev_proc(tdev, fill_rectangle)(tdev, y, x, h, xe - x, color);
+ return dev_proc(tdev, fill_rectangle)(tdev, y, x, w, xe - x, color);
}
}
ccdata.tdev = tdev;
@@ -565,7 +565,7 @@ clip_fill_rectangle_s1(gx_device * dev, int x, int y, int w, int h,
h -= y;
if (w <= 0 || h <= 0)
return 0;
- return dev_proc(tdev, fill_rectangle)(tdev, y, x, h, w, color);
+ return dev_proc(tdev, fill_rectangle)(tdev, x, y, w, h, color);
}
static int
clip_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
@@ -1423,10 +1423,35 @@ clip_get_clipping_box(gx_device * dev, gs_fixed_rect * pbox)
cbox.q.y = int2fixed(rdev->list.single.ymax);
} else {
/* The head and tail elements are dummies.... */
- cbox.p.x = int2fixed(rdev->list.xmin);
- cbox.p.y = int2fixed(rdev->list.head->next->ymin);
- cbox.q.x = int2fixed(rdev->list.xmax);
- cbox.q.y = int2fixed(rdev->list.tail->prev->ymax);
+ gx_clip_rect *curr = rdev->list.head->next;
+
+ cbox.p.x = cbox.p.y = max_int;
+ cbox.q.x = cbox.q.y = min_int;
+ /* scan the list for the outer bbox */
+ while (curr->next != NULL) { /* stop before tail */
+ if (curr->xmin < cbox.p.x)
+ cbox.p.x = curr->xmin;
+ if (curr->xmax > cbox.q.x)
+ cbox.q.x = curr->xmax;
+ if (curr->ymin < cbox.p.y)
+ cbox.p.y = curr->ymin;
+ if (curr->ymax > cbox.q.y)
+ cbox.q.y = curr->ymax;
+ curr = curr->next;
+ }
+ cbox.p.x = int2fixed(cbox.p.x);
+ cbox.q.x = int2fixed(cbox.q.x);
+ cbox.p.y = int2fixed(cbox.p.y);
+ cbox.q.y = int2fixed(cbox.q.y);
+ }
+ if (rdev->list.transpose) {
+ fixed temp = cbox.p.x;
+
+ cbox.p.x = cbox.p.y;
+ cbox.p.y = temp;
+ temp = cbox.q.x;
+ cbox.q.x = cbox.q.y;
+ cbox.q.y = temp;
}
rect_intersect(tbox, cbox);
}