diff --git a/docs/reST/ref/code_examples/draw_module_example.png b/docs/reST/ref/code_examples/draw_module_example.png
index 6e3e6af13c..7997a68a1b 100644
Binary files a/docs/reST/ref/code_examples/draw_module_example.png and b/docs/reST/ref/code_examples/draw_module_example.png differ
diff --git a/src_c/draw.c b/src_c/draw.c
index ab5e30c76b..f4486b35f5 100644
--- a/src_c/draw.c
+++ b/src_c/draw.c
@@ -44,16 +44,15 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2,
 static void
 draw_line(SDL_Surface *surf, int x1, int y1, int x2, int y2, Uint32 color,
           int *drawn_area);
-void
-line_width_corners(float from_x, float from_y, float to_x, float to_y,
-                   int width, float *x1, float *y1, float *x2, float *y2,
-                   float *x3, float *y3, float *x4, float *y4);
 static void
 draw_aaline(SDL_Surface *surf, Uint32 color, float startx, float starty,
             float endx, float endy, int *drawn_area,
             int disable_first_endpoint, int disable_second_endpoint,
             int extra_pixel_for_aalines);
 static void
+draw_aaline_width(SDL_Surface *surf, Uint32 color, float from_x, float from_y,
+                  float to_x, float to_y, int width, int *drawn_area);
+static void
 draw_arc(SDL_Surface *surf, int x_center, int y_center, int radius1,
          int radius2, int width, double angle_start, double angle_stop,
          Uint32 color, int *drawn_area);
@@ -171,13 +170,8 @@ aaline(PyObject *self, PyObject *arg, PyObject *kwargs)
     }
 
     if (width > 1) {
-        float x1, y1, x2, y2, x3, y3, x4, y4;
-        line_width_corners(startx, starty, endx, endy, width, &x1, &y1, &x2,
-                           &y2, &x3, &y3, &x4, &y4);
-        draw_line_width(surf, color, (int)startx, (int)starty, (int)endx,
-                        (int)endy, width, drawn_area);
-        draw_aaline(surf, color, x1, y1, x2, y2, drawn_area, 0, 0, 0);
-        draw_aaline(surf, color, x3, y3, x4, y4, drawn_area, 0, 0, 0);
+        draw_aaline_width(surf, color, startx, starty, endx, endy, width,
+                          drawn_area);
     }
     else {
         draw_aaline(surf, color, startx, starty, endx, endy, drawn_area, 0, 0,
@@ -1698,6 +1692,35 @@ drawhorzlineclipbounding(SDL_Surface *surf, Uint32 color, int x1, int y1,
     drawhorzline(surf, color, x1, y1, x2);
 }
 
+static void
+drawvertlineclipbounding(SDL_Surface *surf, Uint32 color, int y1, int x1,
+                         int y2, int *pts)
+{
+    if (x1 < surf->clip_rect.x || x1 >= surf->clip_rect.x + surf->clip_rect.w)
+        return;
+
+    if (y2 < y1) {
+        int temp = y1;
+        y1 = y2;
+        y2 = temp;
+    }
+
+    y1 = MAX(y1, surf->clip_rect.y);
+    y2 = MIN(y2, surf->clip_rect.y + surf->clip_rect.h - 1);
+
+    if (y2 < surf->clip_rect.y || y1 >= surf->clip_rect.y + surf->clip_rect.h)
+        return;
+
+    if (y1 == y2) {
+        set_and_check_rect(surf, x1, y1, color, pts);
+        return;
+    }
+
+    add_line_to_drawn_list(x1, y1, x1, y2, pts);
+
+    drawvertline(surf, color, y1, x1, y2);
+}
+
 void
 swap_coordinates(int *x1, int *y1, int *x2, int *y2)
 {
@@ -1850,36 +1873,273 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2,
     }
 }
 
-// Calculates 4 points, representing corners of draw_line_width()
-// first two points assemble left line and second two - right line
-void
-line_width_corners(float from_x, float from_y, float to_x, float to_y,
-                   int width, float *x1, float *y1, float *x2, float *y2,
-                   float *x3, float *y3, float *x4, float *y4)
+static void
+draw_aaline_width(SDL_Surface *surf, Uint32 color, float from_x, float from_y,
+                  float to_x, float to_y, int width, int *drawn_area)
 {
-    float aa_width = (float)width / 2;
-    float extra_width = (1.0f - (width % 2)) / 2;
-    int steep = fabs(to_x - from_x) <= fabs(to_y - from_y);
+    float gradient, dx, dy, intersect_y, brightness;
+    int x, x_pixel_start, x_pixel_end, start_draw, end_draw;
+    Uint32 pixel_color;
+    float y_endpoint, clip_left, clip_right, clip_top, clip_bottom;
+    int steep, y;
+    int extra_width = 1 - (width % 2);
+
+    width = (width / 2);
+
+    dx = to_x - from_x;
+    dy = to_y - from_y;
+    steep = fabs(dx) < fabs(dy);
+
+    /* Single point.
+     * A line with length 0 is drawn as a single pixel at full brightness. */
+    if (fabs(dx) < 0.0001 && fabs(dy) < 0.0001) {
+        x = (int)floor(from_x + 0.5);
+        y = (int)floor(from_y + 0.5);
+        pixel_color = get_antialiased_color(surf, x, y, color, 1);
+        set_and_check_rect(surf, x, y, pixel_color, drawn_area);
+        if (dx != 0 && dy != 0) {
+            if (steep) {
+                start_draw = (int)(x - width + extra_width);
+                end_draw = (int)(x + width) - 1;
+                drawhorzlineclipbounding(surf, color, start_draw, y, end_draw,
+                                         drawn_area);
+            }
+            else {
+                start_draw = (int)(y - width + extra_width);
+                end_draw = (int)(y + width) - 1;
+                drawvertlineclipbounding(surf, color, start_draw, x, end_draw,
+                                         drawn_area);
+            }
+        }
+        return;
+    }
+
+    /* To draw correctly the pixels at the border of the clipping area when
+     * the line crosses it, we need to clip it one pixel wider in all four
+     * directions, and add width */
+    clip_left = (float)surf->clip_rect.x - 1.0f;
+    clip_right = (float)clip_left + surf->clip_rect.w + 1.0f;
+    clip_top = (float)surf->clip_rect.y - 1.0f;
+    clip_bottom = (float)clip_top + surf->clip_rect.h + 1.0f;
 
     if (steep) {
-        *x1 = from_x + extra_width + aa_width;
-        *y1 = from_y;
-        *x2 = to_x + extra_width + aa_width;
-        *y2 = to_y;
-        *x3 = from_x + extra_width - aa_width;
-        *y3 = from_y;
-        *x4 = to_x + extra_width - aa_width;
-        *y4 = to_y;
+        swap(&from_x, &from_y);
+        swap(&to_x, &to_y);
+        swap(&dx, &dy);
+        swap(&clip_left, &clip_top);
+        swap(&clip_right, &clip_bottom);
+    }
+    if (dx < 0) {
+        swap(&from_x, &to_x);
+        swap(&from_y, &to_y);
+        dx = -dx;
+        dy = -dy;
+    }
+
+    if (to_x <= clip_left || from_x >= clip_right) {
+        /* The line is completely to the side of the surface */
+        return;
+    }
+
+    /* Note. There is no need to guard against a division by zero here. If dx
+     * was zero then either we had a single point (and we've returned) or it
+     * has been swapped with a non-zero dy. */
+    gradient = dy / dx;
+
+    /* No need to waste CPU cycles on pixels not on the surface. */
+    if (from_x < clip_left + 1) {
+        from_y += gradient * (clip_left + 1 - from_x);
+        from_x = clip_left + 1;
+    }
+    if (to_x > clip_right - 1) {
+        to_y += gradient * (clip_right - 1 - to_x);
+        to_x = clip_right - 1;
+    }
+
+    if (gradient > 0.0f) {
+        if (from_x < clip_left + 1) {
+            /* from_ is the topmost endpoint */
+            if (to_y <= clip_top || from_y >= clip_bottom) {
+                /* The line does not enter the surface */
+                return;
+            }
+            if (from_y < clip_top - width) {
+                from_x += (clip_top - width - from_y) / gradient;
+                from_y = clip_top - width;
+            }
+            if (to_y > clip_bottom + width) {
+                to_x += (clip_bottom + width - to_y) / gradient;
+                to_y = clip_bottom + width;
+            }
+        }
     }
     else {
-        *x1 = from_x;
-        *y1 = from_y + extra_width + aa_width;
-        *x2 = to_x;
-        *y2 = to_y + extra_width + aa_width;
-        *x3 = from_x;
-        *y3 = from_y + extra_width - aa_width;
-        *x4 = to_x;
-        *y4 = to_y + extra_width - aa_width;
+        if (to_x > clip_right - 1) {
+            /* to_ is the topmost endpoint */
+            if (from_y <= clip_top || to_y >= clip_bottom) {
+                /* The line does not enter the surface */
+                return;
+            }
+            if (to_y < clip_top - width) {
+                to_x += (clip_top - width - to_y) / gradient;
+                to_y = clip_top - width;
+            }
+            if (from_y > clip_bottom + width) {
+                from_x += (clip_bottom + width - from_y) / gradient;
+                from_y = clip_bottom + width;
+            }
+        }
+    }
+
+    /* By moving the points one pixel down, we can assume y is never negative.
+     * That permit us to use (int)y to round down instead of having to use
+     * floor(y). We then draw the pixels one higher.*/
+    from_y += 1.0f;
+    to_y += 1.0f;
+
+    /* Handle endpoints separately */
+    /* First endpoint */
+    x_pixel_start = (int)from_x;
+    y_endpoint = intersect_y = from_y + gradient * (x_pixel_start - from_x);
+    if (to_x > clip_left + 1.0f) {
+        brightness = y_endpoint - (int)y_endpoint;
+        if (steep) {
+            x = (int)y_endpoint;
+            y = x_pixel_start;
+        }
+        else {
+            x = x_pixel_start;
+            y = (int)y_endpoint;
+        }
+        if ((int)y_endpoint < y_endpoint) {
+            if (steep) {
+                pixel_color = get_antialiased_color(surf, x + width, y, color,
+                                                    brightness);
+                set_and_check_rect(surf, x + width, y, pixel_color,
+                                   drawn_area);
+            }
+            else {
+                pixel_color = get_antialiased_color(surf, x, y + width, color,
+                                                    brightness);
+                set_and_check_rect(surf, x, y + width, pixel_color,
+                                   drawn_area);
+            }
+        }
+        brightness = 1 - brightness;
+        if (steep) {
+            pixel_color =
+                get_antialiased_color(surf, x - width, y, color, brightness);
+            set_and_check_rect(surf, x - width + extra_width - 1, y,
+                               pixel_color, drawn_area);
+            start_draw = (int)(x - width + extra_width);
+            end_draw = (int)(x + width) - 1;
+            drawhorzlineclipbounding(surf, color, start_draw, y, end_draw,
+                                     drawn_area);
+        }
+        else {
+            pixel_color = get_antialiased_color(
+                surf, x, y - width + extra_width - 1, color, brightness);
+            set_and_check_rect(surf, x, y - width + extra_width - 1,
+                               pixel_color, drawn_area);
+            start_draw = (int)(y - width + extra_width);
+            end_draw = (int)(y + width) - 1;
+            drawvertlineclipbounding(surf, color, start_draw, x, end_draw,
+                                     drawn_area);
+        }
+        intersect_y += gradient;
+        x_pixel_start++;
+    }
+
+    /* Second endpoint */
+    x_pixel_end = (int)ceil(to_x);
+    if (from_x < clip_right - 1.0f) {
+        y_endpoint = to_y + gradient * (x_pixel_end - to_x);
+        brightness = y_endpoint - (int)y_endpoint;
+        if (steep) {
+            x = (int)y_endpoint;
+            y = x_pixel_end;
+        }
+        else {
+            x = x_pixel_end;
+            y = (int)y_endpoint;
+        }
+        if ((int)y_endpoint < y_endpoint) {
+            if (steep) {
+                pixel_color = get_antialiased_color(surf, x + width, y, color,
+                                                    brightness);
+                set_and_check_rect(surf, x + width, y, pixel_color,
+                                   drawn_area);
+            }
+            else {
+                pixel_color = get_antialiased_color(surf, x, y + width, color,
+                                                    brightness);
+                set_and_check_rect(surf, x, y + width, pixel_color,
+                                   drawn_area);
+            }
+        }
+        brightness = 1 - brightness;
+        if (steep) {
+            pixel_color = get_antialiased_color(
+                surf, x - width + extra_width - 1, y, color, brightness);
+            set_and_check_rect(surf, x - width + extra_width - 1, y,
+                               pixel_color, drawn_area);
+            start_draw = (int)(x - width);
+            end_draw = (int)(x + width) - 1;
+            drawhorzlineclipbounding(surf, color, start_draw, y, end_draw,
+                                     drawn_area);
+        }
+        else {
+            pixel_color = get_antialiased_color(
+                surf, x, y - width + extra_width - 1, color, brightness);
+            set_and_check_rect(surf, x, y - width + extra_width - 1,
+                               pixel_color, drawn_area);
+            start_draw = (int)(y - width + extra_width);
+            end_draw = (int)(y + width) - 1;
+            drawvertlineclipbounding(surf, color, start_draw, x, end_draw,
+                                     drawn_area);
+        }
+    }
+
+    /* main line drawing loop */
+    for (x = x_pixel_start; x < x_pixel_end; x++) {
+        y = (int)intersect_y;
+        if (steep) {
+            brightness = 1 - intersect_y + y;
+            pixel_color = get_antialiased_color(
+                surf, y - width + extra_width - 1, x, color, brightness);
+            set_and_check_rect(surf, y - width + extra_width - 1, x,
+                               pixel_color, drawn_area);
+            if (y < intersect_y) {
+                brightness = 1 - brightness;
+                pixel_color = get_antialiased_color(surf, y + width, x, color,
+                                                    brightness);
+                set_and_check_rect(surf, y + width, x, pixel_color,
+                                   drawn_area);
+            }
+            start_draw = (int)(y - width + extra_width);
+            end_draw = (int)(y + width) - 1;
+            drawhorzlineclipbounding(surf, color, start_draw, x, end_draw,
+                                     drawn_area);
+        }
+        else {
+            brightness = 1 - intersect_y + y;
+            pixel_color = get_antialiased_color(
+                surf, x, y - width + extra_width - 1, color, brightness);
+            set_and_check_rect(surf, x, y - width + extra_width - 1,
+                               pixel_color, drawn_area);
+            if (y < intersect_y) {
+                brightness = 1 - brightness;
+                pixel_color = get_antialiased_color(surf, x, y + width, color,
+                                                    brightness);
+                set_and_check_rect(surf, x, y + width, pixel_color,
+                                   drawn_area);
+            }
+            start_draw = (int)(y - width + extra_width);
+            end_draw = (int)(y + width) - 1;
+            drawvertlineclipbounding(surf, color, start_draw, x, end_draw,
+                                     drawn_area);
+        }
+        intersect_y += gradient;
     }
 }
 
diff --git a/test/draw_test.py b/test/draw_test.py
index ffba331575..45355bba84 100644
--- a/test/draw_test.py
+++ b/test/draw_test.py
@@ -2879,20 +2879,22 @@ def test_aaline__gaps(self):
                 pos = (x, 0)
                 self.assertEqual(surface.get_at(pos), expected_color, f"pos={pos}")
 
-    def test_line__gaps_with_thickness(self):
+    def test_aaline__gaps_with_thickness(self):
         """Ensures a thick aaline is drawn without any gaps."""
-        expected_color = (255, 255, 255)
+        background_color = (0, 0, 0)
         thickness = 5
         for surface in self._create_surfaces():
             width = surface.get_width() - 1
             h = width // 5
             w = h * 5
-            self.draw_aaline(surface, expected_color, (0, 5), (w, 5 + h), thickness)
+            self.draw_aaline(surface, (255, 255, 255), (0, 5), (w, 5 + h), thickness)
 
             for x in range(w + 1):
                 for y in range(3, 8):
                     pos = (x, y + ((x + 2) // 5))
-                    self.assertEqual(surface.get_at(pos), expected_color, f"pos={pos}")
+                    self.assertNotEqual(
+                        surface.get_at(pos), background_color, f"pos={pos}"
+                    )
 
     def test_aaline__bounding_rect(self):
         """Ensures draw aaline returns the correct bounding rect.
@@ -2940,9 +2942,7 @@ def test_aaline__bounding_rect(self):
                         self.assertEqual(
                             bounding_rect,
                             expected_rect,
-                            "start={}, end={}, size={}, thickness={}".format(
-                                start, end, size, thickness
-                            ),
+                            f"start={start}, end={end}, size={size}, thickness={thickness}",
                         )
 
     def test_aaline__surface_clip(self):
@@ -2962,6 +2962,8 @@ def test_aaline__surface_clip(self):
             # drawing the aaline over the clip_rect's bounds.
             for center in rect_corners_mids_and_center(clip_rect):
                 pos_rect.center = center
+                start = pos_rect.midtop
+                end = pos_rect.midbottom
 
                 # Get the expected points by drawing the aaline without the
                 # clip area set.
@@ -2970,8 +2972,8 @@ def test_aaline__surface_clip(self):
                 self.draw_aaline(
                     surface,
                     aaline_color,
-                    pos_rect.midtop,
-                    pos_rect.midbottom,
+                    start,
+                    end,
                     thickness,
                 )
 
@@ -2987,8 +2989,8 @@ def test_aaline__surface_clip(self):
                 self.draw_aaline(
                     surface,
                     aaline_color,
-                    pos_rect.midtop,
-                    pos_rect.midbottom,
+                    start,
+                    end,
                     thickness,
                 )
 
@@ -2998,9 +3000,17 @@ def test_aaline__surface_clip(self):
                 # are not surface_color.
                 for pt in ((x, y) for x in range(surfw) for y in range(surfh)):
                     if pt in expected_pts:
-                        self.assertNotEqual(surface.get_at(pt), surface_color, pt)
+                        self.assertNotEqual(
+                            surface.get_at(pt),
+                            surface_color,
+                            f"start={start}, end={end}, thickness={thickness}, point={pt}",
+                        )
                     else:
-                        self.assertEqual(surface.get_at(pt), surface_color, pt)
+                        self.assertEqual(
+                            surface.get_at(pt),
+                            surface_color,
+                            f"start={start}, end={end}, thickness={thickness}, point={pt}",
+                        )
 
                 surface.unlock()