From 38baab24c242dde9905f5c5530599294f44365aa Mon Sep 17 00:00:00 2001
From: Andrew Coffey <andrewryancoffey@hotmail.com>
Date: Sun, 30 Jun 2024 11:51:13 -0500
Subject: [PATCH] set_at now take a long long for y instead of int

---
 src_c/draw.c      | 9 ++++++---
 test/draw_test.py | 8 ++++++++
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/src_c/draw.c b/src_c/draw.c
index c7750664d6..4fe53a4fd6 100644
--- a/src_c/draw.c
+++ b/src_c/draw.c
@@ -1209,8 +1209,11 @@ clip_line(SDL_Surface *surf, int *x1, int *y1, int *x2, int *y2, int width,
 }
 
 static int
-set_at(SDL_Surface *surf, int x, int y, Uint32 color)
+set_at(SDL_Surface *surf, int x, long long y, Uint32 color)
 {
+    // y should be long long so that y * surf->pitch doesn't overflow the int
+    // bounds in the case of very large surfaces and drawing on the edge of
+    // them
     SDL_PixelFormat *format = surf->format;
     Uint8 *pixels = (Uint8 *)surf->pixels;
     Uint8 *byte_buf, rgb[4];
@@ -1250,7 +1253,7 @@ static void
 set_and_check_rect(SDL_Surface *surf, int x, int y, Uint32 color,
                    int *drawn_area)
 {
-    if (set_at(surf, x, y, color))
+    if (set_at(surf, x, (long long)y, color))
         add_pixel_to_drawn_list(x, y, drawn_area);
 }
 
@@ -1544,7 +1547,7 @@ drawhorzlineclip(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2)
         return;
 
     if (x1 == x2) {
-        set_at(surf, x1, y1, color);
+        set_at(surf, x1, (long long)y1, color);
         return;
     }
     drawhorzline(surf, color, x1, y1, x2);
diff --git a/test/draw_test.py b/test/draw_test.py
index 3f00a9319e..b6755fb7da 100644
--- a/test/draw_test.py
+++ b/test/draw_test.py
@@ -1847,6 +1847,14 @@ def test_line_clipping_with_thickness(self):
                 "start={}, end={}".format(end_points[n], start_points[n]),
             )
 
+    def test_line_draw_large_surf_regression(self):
+        """Regression test for https://github.com/pygame-community/pygame-ce/issues/2961"""
+        surface = pygame.Surface((43371, 43371))
+
+        point1 = [30021, 37135]
+        point2 = [30022, 37136]
+        pygame.draw.line(surface, (255, 255, 255), point1, point2, 1)
+
 
 ### Lines Testing #############################################################