Skip to content

Commit c89cdcd

Browse files
authored
fixed banding bug with draw.circle (#2032)
* fixed banding bug with draw.circle when center of circle is to the left of the screen * formatting * expanded the test to test all 4 directions * cleaned up test some more * added test for regression for upstream bug * removed redundant variable * changed comment to be a message in the asserts
1 parent 4fc37dd commit c89cdcd

File tree

2 files changed

+63
-8
lines changed

2 files changed

+63
-8
lines changed

src_c/draw.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,11 +1992,10 @@ draw_circle_filled(SDL_Surface *surf, int x0, int y0, int radius, Uint32 color,
19921992
int ddF_y = -2 * radius;
19931993
int x = 0;
19941994
int y = radius;
1995-
int xmin = INT_MAX;
19961995
int xmax = INT_MIN;
19971996

19981997
if (x0 < 0) {
1999-
xmin = x0 + INT_MAX + 1;
1998+
xmax = x0 + INT_MAX + 1;
20001999
}
20012000
else {
20022001
xmax = INT_MAX - x0;
@@ -2015,15 +2014,14 @@ draw_circle_filled(SDL_Surface *surf, int x0, int y0, int radius, Uint32 color,
20152014
/* optimisation to avoid overdrawing and repeated return rect checks:
20162015
only draw a line if y-step is about to be decreased. */
20172016
if (f >= 0) {
2018-
drawhorzlineclipbounding(surf, color, x0 - MIN(x, xmin),
2019-
y0 + y - 1, x0 + MIN(x - 1, xmax),
2020-
drawn_area);
2021-
drawhorzlineclipbounding(surf, color, x0 - MIN(x, xmin), y0 - y,
2017+
drawhorzlineclipbounding(surf, color, x0 - x, y0 + y - 1,
2018+
x0 + MIN(x - 1, xmax), drawn_area);
2019+
drawhorzlineclipbounding(surf, color, x0 - x, y0 - y,
20222020
x0 + MIN(x - 1, xmax), drawn_area);
20232021
}
2024-
drawhorzlineclipbounding(surf, color, x0 - MIN(y, xmin), y0 + x - 1,
2022+
drawhorzlineclipbounding(surf, color, x0 - y, y0 + x - 1,
20252023
x0 + MIN(y - 1, xmax), drawn_area);
2026-
drawhorzlineclipbounding(surf, color, x0 - MIN(y, xmin), y0 - x,
2024+
drawhorzlineclipbounding(surf, color, x0 - y, y0 - x,
20272025
x0 + MIN(y - 1, xmax), drawn_area);
20282026
}
20292027
}

test/draw_test.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5673,6 +5673,63 @@ def test_circle__diameter(self):
56735673
self.assertEqual(bounding_rect.width, radius * 2)
56745674
self.assertEqual(bounding_rect.height, radius * 2)
56755675

5676+
def test_circle__offscreen(self):
5677+
"""Ensures that drawing a circle completely off-screen doesn't create
5678+
a solid band across the screen
5679+
see https://github.com/pygame/pygame/issues/3143
5680+
"""
5681+
width = 200
5682+
height = 200
5683+
surf = pygame.Surface((width, height))
5684+
surf_center = surf.get_rect().center
5685+
radius = 10
5686+
5687+
# way way outside the screen
5688+
test_centers = [
5689+
(-1e30, height / 2),
5690+
(1e30, height / 2),
5691+
(width / 2, -1e30),
5692+
(width / 2, 1e30),
5693+
]
5694+
for center in test_centers:
5695+
surf.fill("black")
5696+
self.draw_circle(surf, "white", center, radius)
5697+
5698+
self.assertEqual(
5699+
surf.get_at(surf_center)[0:3],
5700+
(0, 0, 0),
5701+
msg="pixel at center should be black, not white",
5702+
)
5703+
5704+
def test_circle__no_band(self):
5705+
"""Ensures that drawing a circle with the center off-screen doesn't create a
5706+
solid band across the screen
5707+
This tests a bug introduced in
5708+
https://github.com/pygame-community/pygame-ce/commit/c88a1d8f7b31099cec84dc5cb7aeebdada783e83
5709+
"""
5710+
width = 200
5711+
height = 200
5712+
surf = pygame.Surface((width, height))
5713+
surf_center = surf.get_rect().center
5714+
radius = 10
5715+
5716+
# one pixel outside the screen on the center of each edge
5717+
test_centers = [
5718+
(-1, height / 2),
5719+
(width + 1, height / 2),
5720+
(width / 2, -1),
5721+
(width / 2, height + 1),
5722+
]
5723+
for center in test_centers:
5724+
surf.fill("black")
5725+
self.draw_circle(surf, "white", center, radius)
5726+
5727+
self.assertEqual(
5728+
surf.get_at(surf_center)[0:3],
5729+
(0, 0, 0),
5730+
msg="pixel at center should be black, not white",
5731+
)
5732+
56765733

56775734
class DrawCircleTest(DrawCircleMixin, DrawTestCase):
56785735
"""Test draw module function circle.

0 commit comments

Comments
 (0)