From 0c9ffcfa1475dd6f8e42c4029d66ed6c82aa9d22 Mon Sep 17 00:00:00 2001 From: Stanislau Tsitsianok Date: Sun, 2 May 2021 17:12:07 +0300 Subject: [PATCH 1/2] Fixed #5432 --- src/libImaging/Draw.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libImaging/Draw.c b/src/libImaging/Draw.c index b6f63b7e8..004ff0fe5 100644 --- a/src/libImaging/Draw.c +++ b/src/libImaging/Draw.c @@ -1347,6 +1347,22 @@ pie_init(clip_ellipse_state *s, int32_t a, int32_t b, int32_t w, float al, float s->root->l = lc; s->root->r = rc; s->root->type = ar - al < 180 ? CT_AND : CT_OR; + + // add one more semiplane to avoid spikes + if (ar - al < 90) { + clip_node *old_root = s->root; + clip_node *spike_clipper = s->nodes + s->node_count++; + s->root = s->nodes + s->node_count++; + s->root->l = old_root; + s->root->r = spike_clipper; + s->root->type = CT_AND; + + spike_clipper->l = spike_clipper->r = NULL; + spike_clipper->type = CT_CLIP; + spike_clipper->a = (xl + xr) / 2.0; + spike_clipper->b = (yl + yr) / 2.0; + spike_clipper->c = 0; + } } void From ca67a0c1a2a9762f7f461d499d98f4a176729c2b Mon Sep 17 00:00:00 2001 From: Stanislau Tsitsianok Date: Sun, 2 May 2021 17:12:27 +0300 Subject: [PATCH 2/2] Added test for #5432 --- Tests/test_imagedraw.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Tests/test_imagedraw.py b/Tests/test_imagedraw.py index 7f31e1aaf..dbdd34bc8 100644 --- a/Tests/test_imagedraw.py +++ b/Tests/test_imagedraw.py @@ -538,6 +538,36 @@ def test_pieslice_wide(): assert_image_equal_tofile(im, "Tests/images/imagedraw_pieslice_wide.png") +def test_pieslice_no_spikes(): + im = Image.new("RGB", (161, 161), "white") + draw = ImageDraw.Draw(im) + cxs = ( + [140] * 3 + + list(range(140, 19, -20)) + + [20] * 5 + + list(range(20, 141, 20)) + + [140] * 2 + ) + cys = ( + list(range(80, 141, 20)) + + [140] * 5 + + list(range(140, 19, -20)) + + [20] * 5 + + list(range(20, 80, 20)) + ) + + for cx, cy, angle in zip(cxs, cys, range(0, 360, 15)): + draw.pieslice( + [cx - 100, cy - 100, cx + 100, cy + 100], angle, angle + 1, fill="black" + ) + draw.point([cx, cy], fill="red") + + im_pre_erase = im.copy() + draw.rectangle([21, 21, 139, 139], fill="white") + + assert_image_equal(im, im_pre_erase) + + def helper_point(points): # Arrange im = Image.new("RGB", (W, H))