From d0279cbd913fb9dcada3f7dc6a3435b862a82c47 Mon Sep 17 00:00:00 2001 From: Robin Watts <Robin.Watts@artifex.com> Date: Fri, 14 Oct 2022 08:51:02 +0100 Subject: [PATCH 154/155] Bug 705955: Restrict the vertical size of clipping accums for speed. Where possible, limit the vertical size of clipping accumulators. --- base/gxacpath.c | 18 ++++++++++++++---- base/gxstroke.c | 4 ++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/base/gxacpath.c b/base/gxacpath.c index 23c70a0da..df51b6c00 100644 --- a/base/gxacpath.c +++ b/base/gxacpath.c @@ -92,16 +92,26 @@ void gx_cpath_accum_set_cbox(gx_device_cpath_accum * padev, const gs_fixed_rect * pbox) { + /* fixed2int_var_ceiling(x) overflows for anything larger + * than max_fixed - fixed_scale - 1. So to protect against + * us doing bad things when passed a min_fixed/max_fixed box, + * clip appropriately. */ + fixed upperx = pbox->q.x; + fixed uppery = pbox->q.y; + if (upperx > max_fixed - fixed_scale - 1) + upperx = max_fixed - fixed_scale - 1; + if (uppery > max_fixed - fixed_scale - 1) + uppery = max_fixed - fixed_scale - 1; if (padev->list.transpose) { padev->clip_box.p.x = fixed2int_var(pbox->p.y); padev->clip_box.p.y = fixed2int_var(pbox->p.x); - padev->clip_box.q.x = fixed2int_var_ceiling(pbox->q.y); - padev->clip_box.q.y = fixed2int_var_ceiling(pbox->q.x); + padev->clip_box.q.x = fixed2int_var_ceiling(uppery); + padev->clip_box.q.y = fixed2int_var_ceiling(upperx); } else { padev->clip_box.p.x = fixed2int_var(pbox->p.x); padev->clip_box.p.y = fixed2int_var(pbox->p.y); - padev->clip_box.q.x = fixed2int_var_ceiling(pbox->q.x); - padev->clip_box.q.y = fixed2int_var_ceiling(pbox->q.y); + padev->clip_box.q.x = fixed2int_var_ceiling(upperx); + padev->clip_box.q.y = fixed2int_var_ceiling(uppery); } } diff --git a/base/gxstroke.c b/base/gxstroke.c index 345378437..d069cb6ee 100644 --- a/base/gxstroke.c +++ b/base/gxstroke.c @@ -345,6 +345,7 @@ gx_default_stroke_path_shading_or_pattern(gx_device * pdev, gx_device_color devc; gx_clip_path stroke_as_clip_path; int code; + gs_fixed_rect dev_clip_rect = { {min_fixed, min_fixed}, {max_fixed, max_fixed}}; /* We want to make a image of the stroke as a clip path, so * create an empty structure on the stack. */ @@ -353,6 +354,9 @@ gx_default_stroke_path_shading_or_pattern(gx_device * pdev, return code; /* Now we make an accumulator device that will fill that out. */ gx_cpath_accum_begin(&adev, stroke_as_clip_path.path.memory, false); + if (pdev != 0) + (*dev_proc(pdev, get_clipping_box))(pdev, &dev_clip_rect); + gx_cpath_accum_set_cbox(&adev, &dev_clip_rect); set_nonclient_dev_color(&devc, 0); /* arbitrary, but not transparent */ gs_set_logical_op_inline(pgs, lop_default); /* Stroke the path to the accumulator. */ -- 2.30.4