From 7fd47a5e08ff5474c33d8058785f710feaf4c6e9 Mon Sep 17 00:00:00 2001 From: TemmieGamerGuy <76136819+Temmie3754@users.noreply.github.com> Date: Thu, 30 Mar 2023 18:58:24 +0100 Subject: [PATCH 1/9] improved algorithm --- src_c/draw.c | 67 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/src_c/draw.c b/src_c/draw.c index 45ec8396f1..7f7dfe39e9 100644 --- a/src_c/draw.c +++ b/src_c/draw.c @@ -1475,7 +1475,7 @@ static void draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, int y2, int width, int *drawn_area) { - int dx, dy, err, e2, sx, sy, start_draw, end_draw; + int dx, dy, err, e2, sx, sy, start_draw, end_draw, diff, exit, end; int end_x = surf->clip_rect.x + surf->clip_rect.w - 1; int end_y = surf->clip_rect.y + surf->clip_rect.h - 1; int xinc = 0; @@ -1511,13 +1511,30 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, } // Bresenham's line algorithm dx = abs(x2 - x1); - dy = abs(y2 - y1); + dy = -abs(y2 - y1); sx = x2 > x1 ? 1 : -1; sy = y2 > y1 ? 1 : -1; - err = (dx > dy ? dx : -dy) / 2; + err = dx + dy; if (xinc) { - while (y1 != (y2 + sy)) { - if (surf->clip_rect.y <= y1 && y1 <= end_y) { + end = y2 + sy; + if (y2 > y1) { + exit = end_y + 1; + diff = surf->clip_rect.y - y1; + } + else { + exit = surf->clip_rect.y - 1; + diff = y1 - end_y; + + } + if (diff > 0) { + y1 += diff * sy; + err += (diff) * dx; + x1 += ((err - dy) / -dy) * sx; + err = (err % -dy) + dy; + } + + while (y1 != end) { + if (y1 != exit) { start_draw = MAX((x1 - width) + extra_width, surf->clip_rect.x); end_draw = MIN(end_x, x1 + width); @@ -1527,20 +1544,37 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, drawn_area); } } - e2 = err; - if (e2 > -dx) { - err -= dy; + else break; + e2 = err * 2; + if (e2 >= dy) { + err += dy; x1 += sx; } - if (e2 < dy) { + if (e2 <= dx) { err += dx; y1 += sy; } + } } else { - while (x1 != (x2 + sx)) { - if (surf->clip_rect.x <= x1 && x1 <= end_x) { + end = x2 + sx; + if (x2 > x1) { + diff = surf->clip_rect.x - x1; + exit = end_x + 1; + } + else { + diff = x1 - end_x; + exit = surf->clip_rect.x - 1; + } + if (diff > 0) { + x1 += diff * sx; + err += diff * dy; + y1 += ((err - dx) / -dx) * sy; + err = (err % dx) + dx; + } + while (x1 != end) { + if (x1 != exit) { start_draw = MAX((y1 - width) + extra_width, surf->clip_rect.y); end_draw = MIN(end_y, y1 + width); @@ -1550,12 +1584,13 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, drawn_area); } } - e2 = err; - if (e2 > -dx) { - err -= dy; + else break; + e2 = err * 2; + if (e2 >= dy) { + err += dy; x1 += sx; } - if (e2 < dy) { + if (e2 <= dx) { err += dx; y1 += sy; } @@ -2325,7 +2360,7 @@ draw_fillpoly(SDL_Surface *surf, int *point_x, int *point_y, * 3. each two x-coordinates in x_intersect are then inside the polygon * (draw line for a pair of two such points) */ - for (y = miny; (y <= maxy); y++) { + for (y = MAX(miny, surf->clip_rect.y); (y <= MIN(maxy, surf->clip_rect.y + surf->clip_rect.h)); y++) { // n_intersections is the number of intersections with the polygon int n_intersections = 0; for (i = 0; (i < num_points); i++) { From a0a7740f8c4ee21d7c869def8aa8e8b30fb53a4a Mon Sep 17 00:00:00 2001 From: TemmieGamerGuy <76136819+Temmie3754@users.noreply.github.com> Date: Thu, 30 Mar 2023 21:05:39 +0100 Subject: [PATCH 2/9] fix incorrect delta --- src_c/draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_c/draw.c b/src_c/draw.c index 7f7dfe39e9..9f98cfafd7 100644 --- a/src_c/draw.c +++ b/src_c/draw.c @@ -1571,7 +1571,7 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, x1 += diff * sx; err += diff * dy; y1 += ((err - dx) / -dx) * sy; - err = (err % dx) + dx; + err = (err % dx) + dy; } while (x1 != end) { if (x1 != exit) { From 547824d40a04677c0c442100adf0533aeacabdde Mon Sep 17 00:00:00 2001 From: TemmieGamerGuy <76136819+Temmie3754@users.noreply.github.com> Date: Thu, 30 Mar 2023 21:16:00 +0100 Subject: [PATCH 3/9] fix formatting --- src_c/draw.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src_c/draw.c b/src_c/draw.c index 9f98cfafd7..2d0db4d7fe 100644 --- a/src_c/draw.c +++ b/src_c/draw.c @@ -1524,11 +1524,10 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, else { exit = surf->clip_rect.y - 1; diff = y1 - end_y; - } if (diff > 0) { y1 += diff * sy; - err += (diff) * dx; + err += (diff)*dx; x1 += ((err - dy) / -dy) * sx; err = (err % -dy) + dy; } @@ -1544,7 +1543,8 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, drawn_area); } } - else break; + else + break; e2 = err * 2; if (e2 >= dy) { err += dy; @@ -1554,7 +1554,6 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, err += dx; y1 += sy; } - } } else { @@ -1584,7 +1583,8 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, drawn_area); } } - else break; + else + break; e2 = err * 2; if (e2 >= dy) { err += dy; @@ -2360,7 +2360,8 @@ draw_fillpoly(SDL_Surface *surf, int *point_x, int *point_y, * 3. each two x-coordinates in x_intersect are then inside the polygon * (draw line for a pair of two such points) */ - for (y = MAX(miny, surf->clip_rect.y); (y <= MIN(maxy, surf->clip_rect.y + surf->clip_rect.h)); y++) { + for (y = MAX(miny, surf->clip_rect.y); + (y <= MIN(maxy, surf->clip_rect.y + surf->clip_rect.h)); y++) { // n_intersections is the number of intersections with the polygon int n_intersections = 0; for (i = 0; (i < num_points); i++) { From 2ee5995d11a4831748df303be734567b73a3bced Mon Sep 17 00:00:00 2001 From: TemmieGamerGuy <76136819+Temmie3754@users.noreply.github.com> Date: Tue, 18 Apr 2023 11:46:05 +0100 Subject: [PATCH 4/9] Fix algorithm issues, add comments --- src_c/draw.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src_c/draw.c b/src_c/draw.c index 2d0db4d7fe..152140e146 100644 --- a/src_c/draw.c +++ b/src_c/draw.c @@ -1515,8 +1515,12 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, sx = x2 > x1 ? 1 : -1; sy = y2 > y1 ? 1 : -1; err = dx + dy; + // If line is more vertical than horizontal if (xinc) { end = y2 + sy; + // Set exit to y value of where line will leave surface + // Set diff to difference between starting y coordinate and the y value + // of the line's entry point to the surface if (y2 > y1) { exit = end_y + 1; diff = surf->clip_rect.y - y1; @@ -1525,13 +1529,21 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, exit = surf->clip_rect.y - 1; diff = y1 - end_y; } + // If line starts outside of surface if (diff > 0) { + // Set y1 to entry y point y1 += diff * sy; - err += (diff)*dx; - x1 += ((err - dy) / -dy) * sx; - err = (err % -dy) + dy; + // Adjust err by dx for the change in the y axis + err += diff * dx; + // Calculate change in x value (x = y/m), uses ceil for consistency + // between positive/negative values + diff = ceil(((float)diff * dx) / (float)-dy); + x1 += diff * sx; + // Adjust err value to correct for change in x axis + err += diff * dy; } + // Continue through normal Bresenham's line algorithm iteration while (y1 != end) { if (y1 != exit) { start_draw = @@ -1558,6 +1570,9 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, } else { end = x2 + sx; + // Set exit to x value of where line will leave surface + // Set diff to difference between starting x coordinate and the x value + // of the line's entry point to the surface if (x2 > x1) { diff = surf->clip_rect.x - x1; exit = end_x + 1; @@ -1566,12 +1581,21 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, diff = x1 - end_x; exit = surf->clip_rect.x - 1; } + // If line starts outside of surface if (diff > 0) { + // Set x1 to entry x point x1 += diff * sx; + // Adjust err by dy for the change in the x axis err += diff * dy; - y1 += ((err - dx) / -dx) * sy; - err = (err % dx) + dy; + // Calculate change in y value (y = mx), uses ceil for consistency + // between positive/negative values + diff = ceil(((float)diff * -dy) / (float)dx); + y1 += diff * sy; + // Adjust err value to correct for change in y axis + err += diff * dx; } + + // Continue through normal Bresenham's line algorithm iteration while (x1 != end) { if (x1 != exit) { start_draw = From 55111cdc5fcc29139ec8e678915a2366921ddbfa Mon Sep 17 00:00:00 2001 From: TemmieGamerGuy <76136819+Temmie3754@users.noreply.github.com> Date: Tue, 18 Apr 2023 12:46:47 +0100 Subject: [PATCH 5/9] explicit cast --- src_c/draw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src_c/draw.c b/src_c/draw.c index 152140e146..0946b4fd56 100644 --- a/src_c/draw.c +++ b/src_c/draw.c @@ -1537,7 +1537,7 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, err += diff * dx; // Calculate change in x value (x = y/m), uses ceil for consistency // between positive/negative values - diff = ceil(((float)diff * dx) / (float)-dy); + diff = (int)ceil(((float)diff * dx) / (float)-dy); x1 += diff * sx; // Adjust err value to correct for change in x axis err += diff * dy; @@ -1589,7 +1589,7 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, err += diff * dy; // Calculate change in y value (y = mx), uses ceil for consistency // between positive/negative values - diff = ceil(((float)diff * -dy) / (float)dx); + diff = (int)ceil(((float)diff * -dy) / (float)dx); y1 += diff * sy; // Adjust err value to correct for change in y axis err += diff * dx; From 2201edeb93559bab6738258e7d69cb9544a25290 Mon Sep 17 00:00:00 2001 From: TemmieGamerGuy <76136819+Temmie3754@users.noreply.github.com> Date: Fri, 21 Apr 2023 14:51:19 +0100 Subject: [PATCH 6/9] Improve performance of draw_line --- src_c/draw.c | 156 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 135 insertions(+), 21 deletions(-) diff --git a/src_c/draw.c b/src_c/draw.c index 0946b4fd56..26fed58544 100644 --- a/src_c/draw.c +++ b/src_c/draw.c @@ -1629,41 +1629,155 @@ static void draw_line(SDL_Surface *surf, int x1, int y1, int x2, int y2, Uint32 color, int *drawn_area) { - int dx, dy, err, e2, sx, sy; + int dx, dy, err, e2, sx, sy, diff, exit, end; + int xinc = 0; if (x1 == x2 && y1 == y2) { /* Single point */ set_and_check_rect(surf, x1, y1, color, drawn_area); return; } + // Determine if the line is more vertical or horizontal for clipping + // purposes + if (abs(x1 - x2) <= abs(y1 - y2)) { + xinc = 1; + } + + if (!clip_line(surf, &x1, &y1, &x2, &y2, 0, xinc)) + return; + if (y1 == y2) { /* Horizontal line */ - dx = (x1 < x2) ? 1 : -1; - for (sx = 0; sx <= abs(x1 - x2); sx++) { - set_and_check_rect(surf, x1 + dx * sx, y1, color, drawn_area); + if (x1 < x2) { + drawhorzline(surf, color, MAX(x1, surf->clip_rect.x), y1, + MIN(x2, surf->clip_rect.x + surf->clip_rect.w - 1)); + add_line_to_drawn_list( + MAX(x1, surf->clip_rect.x), y1, + MIN(x2, surf->clip_rect.x + surf->clip_rect.w - 1), y1, + drawn_area); + } + else { + drawhorzline(surf, color, MAX(x2, surf->clip_rect.x), y1, + MIN(x1, surf->clip_rect.x + surf->clip_rect.w - 1)); + add_line_to_drawn_list( + MAX(x2, surf->clip_rect.x), y1, + MIN(x1, surf->clip_rect.x + surf->clip_rect.w - 1), y1, + drawn_area); } - return; } if (x1 == x2) { /* Vertical line */ - dy = (y1 < y2) ? 1 : -1; - for (sy = 0; sy <= abs(y1 - y2); sy++) - set_and_check_rect(surf, x1, y1 + dy * sy, color, drawn_area); + if (y1 < y2) { + drawvertline(surf, color, MAX(y1, surf->clip_rect.y), x1, + MIN(y2, surf->clip_rect.y + surf->clip_rect.h - 1)); + add_line_to_drawn_list( + x1, MAX(y1, surf->clip_rect.y), x1, + MIN(y2, surf->clip_rect.y + surf->clip_rect.h - 1), + drawn_area); + } + else { + drawvertline(surf, color, MAX(y2, surf->clip_rect.y), x1, + MIN(y1, surf->clip_rect.y + surf->clip_rect.h - 1)); + add_line_to_drawn_list( + x1, MAX(y2, surf->clip_rect.y), x1, + MIN(y1, surf->clip_rect.y + surf->clip_rect.h - 1), + drawn_area); + } return; } - dx = abs(x2 - x1), sx = x1 < x2 ? 1 : -1; - dy = abs(y2 - y1), sy = y1 < y2 ? 1 : -1; - err = (dx > dy ? dx : -dy) / 2; - while (x1 != x2 || y1 != y2) { - set_and_check_rect(surf, x1, y1, color, drawn_area); - e2 = err; - if (e2 > -dx) { - err -= dy; - x1 += sx; + dx = abs(x2 - x1); + dy = -abs(y2 - y1); + sx = x2 > x1 ? 1 : -1; + sy = y2 > y1 ? 1 : -1; + err = dx + dy; + // If line is more vertical than horizontal + if (xinc) { + end = y2 + sy; + // Set exit to y value of where line will leave surface + // Set diff to difference between starting y coordinate and the y value + // of the line's entry point to the surface + if (y2 > y1) { + exit = surf->clip_rect.y + surf->clip_rect.h; + diff = surf->clip_rect.y - y1; + } + else { + exit = surf->clip_rect.y - 1; + diff = y1 - (surf->clip_rect.y + surf->clip_rect.h - 1); } - if (e2 < dy) { - err += dx; - y1 += sy; + // If line starts outside of surface + if (diff > 0) { + // Set y1 to entry y point + y1 += diff * sy; + // Adjust err by dx for the change in the y axis + err += diff * dx; + // Calculate change in x value (x = y/m), uses ceil for consistency + // between positive/negative values + diff = (int)ceil(((float)diff * dx) / (float)-dy); + x1 += diff * sx; + // Adjust err value to correct for change in x axis + err += diff * dy; + } + + // Continue through normal Bresenham's line algorithm iteration + while (y1 != end) { + if (y1 != exit) { + set_and_check_rect(surf, x1, y1, color, drawn_area); + } + else + break; + e2 = err * 2; + if (e2 >= dy) { + err += dy; + x1 += sx; + } + if (e2 <= dx) { + err += dx; + y1 += sy; + } + } + } + else { + end = x2 + sx; + // Set exit to x value of where line will leave surface + // Set diff to difference between starting x coordinate and the x value + // of the line's entry point to the surface + if (x2 > x1) { + diff = surf->clip_rect.x - x1; + exit = surf->clip_rect.x + surf->clip_rect.w; + } + else { + diff = x1 - (surf->clip_rect.x + surf->clip_rect.w - 1); + exit = surf->clip_rect.x - 1; + } + // If line starts outside of surface + if (diff > 0) { + // Set x1 to entry x point + x1 += diff * sx; + // Adjust err by dy for the change in the x axis + err += diff * dy; + // Calculate change in y value (y = mx), uses ceil for consistency + // between positive/negative values + diff = (int)ceil(((float)diff * -dy) / (float)dx); + y1 += diff * sy; + // Adjust err value to correct for change in y axis + err += diff * dx; + } + + // Continue through normal Bresenham's line algorithm iteration + while (x1 != end) { + if (x1 != exit) { + set_and_check_rect(surf, x1, y1, color, drawn_area); + } + else + break; + e2 = err * 2; + if (e2 >= dy) { + err += dy; + x1 += sx; + } + if (e2 <= dx) { + err += dx; + y1 += sy; + } } } - set_and_check_rect(surf, x2, y2, color, drawn_area); } static void From 80ee5242a3d4a0a811b881e0d8d18d16daa83bad Mon Sep 17 00:00:00 2001 From: Temmie <76136819+Temmie3754@users.noreply.github.com> Date: Sat, 14 Oct 2023 17:45:32 +0100 Subject: [PATCH 7/9] wip improvements --- src_c/draw.c | 142 +++++++++++++++++++++++++++---------------------- testingfile.py | 118 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+), 63 deletions(-) create mode 100644 testingfile.py diff --git a/src_c/draw.c b/src_c/draw.c index 9be20d1534..338957fc5d 100644 --- a/src_c/draw.c +++ b/src_c/draw.c @@ -1042,6 +1042,15 @@ add_line_to_drawn_list(int x1, int y1, int x2, int y2, int *pts) } } +// Prevents double evaluation +inline static int intmin(int a, int b) { + return ((a) < (b) ? (a) : (b)); +} + +inline static int intmax(int a, int b) { + return ((a) > (b) ? (a) : (b)); +} + static int clip_line(SDL_Surface *surf, int *x1, int *y1, int *x2, int *y2, int width, int xinc) @@ -1059,13 +1068,11 @@ clip_line(SDL_Surface *surf, int *x1, int *y1, int *x2, int *y2, int width, top = MIN(*y1, *y2) - width; bottom = MAX(*y1, *y2) + width; } - if (surf->clip_rect.x > right || surf->clip_rect.y > bottom || - surf->clip_rect.x + surf->clip_rect.w <= left || - surf->clip_rect.y + surf->clip_rect.h <= top) { - return 0; - } - - return 1; + // 4 = no points within clip boundary + // 0 = all points within clip boundary + return ((surf->clip_rect.x > right) + (surf->clip_rect.y > bottom) + + (surf->clip_rect.x + surf->clip_rect.w <= left) + + (surf->clip_rect.y + surf->clip_rect.h <= top)); } static int @@ -1504,11 +1511,7 @@ static void draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, int y2, int width, int *drawn_area) { - int dx, dy, err, e2, sx, sy, start_draw, end_draw, diff, exit, end; - int end_x = surf->clip_rect.x + surf->clip_rect.w - 1; - int end_y = surf->clip_rect.y + surf->clip_rect.h - 1; - int xinc = 0; - int extra_width = 1 - (width % 2); + if (width < 1) return; @@ -1517,6 +1520,12 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, return; } + int dx, dy, err, e2, sx, sy, start_draw, end_draw, diff, exit; + int end_x = surf->clip_rect.x + surf->clip_rect.w - 1; + int end_y = surf->clip_rect.y + surf->clip_rect.h - 1; + int xinc = 0; + int extra_width = 1 - (width % 2); + width = (width / 2); /* Decide which direction to grow (width/thickness). */ @@ -1525,19 +1534,21 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, * ends of the line will be flat. */ xinc = 1; } - - if (!clip_line(surf, &x1, &y1, &x2, &y2, width, xinc)) + int clipval = clip_line(surf, &x1, &y1, &x2, &y2, width, xinc); + if (clipval == 4) return; if (x1 == x2 && y1 == y2) { /* Single point */ - start_draw = MAX((x1 - width) + extra_width, surf->clip_rect.x); - end_draw = MIN(end_x, x1 + width); + start_draw = intmax((x1 - width) + extra_width, surf->clip_rect.x); + end_draw = intmin(end_x, x1 + width); if (start_draw <= end_draw) { drawhorzline(surf, color, start_draw, y1, end_draw); add_line_to_drawn_list(start_draw, y1, end_draw, y1, drawn_area); } return; } + + // Bresenham's line algorithm dx = abs(x2 - x1); dy = -abs(y2 - y1); @@ -1546,16 +1557,20 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, err = dx + dy; // If line is more vertical than horizontal if (xinc) { - end = y2 + sy; + drawn_area[0] = intmax((intmin(x1, x2) - width) + extra_width, surf->clip_rect.x); + drawn_area[1] = intmax(intmin(y1, y2), surf->clip_rect.y); + drawn_area[2] = intmin(intmax(x1, x2) + width, end_x); + drawn_area[3] = intmin(intmax(y1, y2), end_y); // Set exit to y value of where line will leave surface // Set diff to difference between starting y coordinate and the y value // of the line's entry point to the surface + if (y2 > y1) { - exit = end_y + 1; + exit = intmin(end_y + 1, y2 + sy); diff = surf->clip_rect.y - y1; } else { - exit = surf->clip_rect.y - 1; + exit = intmax(surf->clip_rect.y - 1, y2 + sy); diff = y1 - end_y; } // If line starts outside of surface @@ -1573,19 +1588,15 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, } // Continue through normal Bresenham's line algorithm iteration - while (y1 != end) { - if (y1 != exit) { - start_draw = - MAX((x1 - width) + extra_width, surf->clip_rect.x); - end_draw = MIN(end_x, x1 + width); - if (start_draw <= end_draw) { - drawhorzline(surf, color, start_draw, y1, end_draw); - add_line_to_drawn_list(start_draw, y1, end_draw, y1, - drawn_area); - } + while (y1 != exit) { + + start_draw = + intmax((x1 - width) + extra_width, surf->clip_rect.x); + end_draw = intmin(end_x, x1 + width); + if (start_draw <= end_draw) { + drawhorzline(surf, color, start_draw, y1, end_draw); } - else - break; + e2 = err * 2; if (e2 >= dy) { err += dy; @@ -1598,17 +1609,20 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, } } else { - end = x2 + sx; + drawn_area[0] = intmax(intmin(x1, x2), surf->clip_rect.x); + drawn_area[1] = intmax((intmin(y1, y2) - width) + extra_width, surf->clip_rect.y); + drawn_area[2] = intmin(MAX(x1, x2), end_x); + drawn_area[3] = intmin(intmax(y1, y2) + width, end_y); // Set exit to x value of where line will leave surface // Set diff to difference between starting x coordinate and the x value // of the line's entry point to the surface if (x2 > x1) { diff = surf->clip_rect.x - x1; - exit = end_x + 1; + exit = intmin(end_x + 1, x2 + sx); } else { diff = x1 - end_x; - exit = surf->clip_rect.x - 1; + exit = intmax(surf->clip_rect.x, x2 + sx); } // If line starts outside of surface if (diff > 0) { @@ -1625,17 +1639,15 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, } // Continue through normal Bresenham's line algorithm iteration - while (x1 != end) { - if (x1 != exit) { - start_draw = - MAX((y1 - width) + extra_width, surf->clip_rect.y); - end_draw = MIN(end_y, y1 + width); - if (start_draw <= end_draw) { - drawvertline(surf, color, start_draw, x1, end_draw); - add_line_to_drawn_list(x1, start_draw, x1, end_draw, - drawn_area); - } + while (x1 != exit) { + + start_draw = + intmax((y1 - width) + extra_width, surf->clip_rect.y); + end_draw = intmin(end_y, y1 + width); + if (start_draw <= end_draw) { + drawvertline(surf, color, start_draw, x1, end_draw); } + else break; e2 = err * 2; @@ -1670,47 +1682,51 @@ draw_line(SDL_Surface *surf, int x1, int y1, int x2, int y2, Uint32 color, xinc = 1; } - if (!clip_line(surf, &x1, &y1, &x2, &y2, 0, xinc)) + if (clip_line(surf, &x1, &y1, &x2, &y2, 0, xinc) == 4) return; if (y1 == y2) { /* Horizontal line */ if (x1 < x2) { - drawhorzline(surf, color, MAX(x1, surf->clip_rect.x), y1, - MIN(x2, surf->clip_rect.x + surf->clip_rect.w - 1)); + drawhorzline(surf, color, intmax(x1, surf->clip_rect.x), y1, + intmin(x2, surf->clip_rect.x + surf->clip_rect.w - 1)); add_line_to_drawn_list( - MAX(x1, surf->clip_rect.x), y1, - MIN(x2, surf->clip_rect.x + surf->clip_rect.w - 1), y1, + intmax(x1, surf->clip_rect.x), y1, + intmin(x2, surf->clip_rect.x + surf->clip_rect.w - 1), y1, drawn_area); } else { - drawhorzline(surf, color, MAX(x2, surf->clip_rect.x), y1, - MIN(x1, surf->clip_rect.x + surf->clip_rect.w - 1)); + drawhorzline(surf, color, intmax(x2, surf->clip_rect.x), y1, + intmin(x1, surf->clip_rect.x + surf->clip_rect.w - 1)); add_line_to_drawn_list( - MAX(x2, surf->clip_rect.x), y1, - MIN(x1, surf->clip_rect.x + surf->clip_rect.w - 1), y1, + intmax(x2, surf->clip_rect.x), y1, + intmin(x1, surf->clip_rect.x + surf->clip_rect.w - 1), y1, drawn_area); } return; } if (x1 == x2) { /* Vertical line */ if (y1 < y2) { - drawvertline(surf, color, MAX(y1, surf->clip_rect.y), x1, - MIN(y2, surf->clip_rect.y + surf->clip_rect.h - 1)); + drawvertline(surf, color, intmax(y1, surf->clip_rect.y), x1, + intmin(y2, surf->clip_rect.y + surf->clip_rect.h - 1)); add_line_to_drawn_list( - x1, MAX(y1, surf->clip_rect.y), x1, - MIN(y2, surf->clip_rect.y + surf->clip_rect.h - 1), + x1, intmax(y1, surf->clip_rect.y), x1, + intmin(y2, surf->clip_rect.y + surf->clip_rect.h - 1), drawn_area); } else { - drawvertline(surf, color, MAX(y2, surf->clip_rect.y), x1, - MIN(y1, surf->clip_rect.y + surf->clip_rect.h - 1)); + drawvertline(surf, color, intmax(y2, surf->clip_rect.y), x1, + intmin(y1, surf->clip_rect.y + surf->clip_rect.h - 1)); add_line_to_drawn_list( - x1, MAX(y2, surf->clip_rect.y), x1, - MIN(y1, surf->clip_rect.y + surf->clip_rect.h - 1), + x1, intmax(y2, surf->clip_rect.y), x1, + intmin(y1, surf->clip_rect.y + surf->clip_rect.h - 1), drawn_area); } return; } + drawn_area[0] = intmax(intmin(x1, x2), surf->clip_rect.x); + drawn_area[1] = intmax(intmin(y1, y2), surf->clip_rect.y); + drawn_area[2] = intmin(intmax(x1, x2), surf->clip_rect.x + surf->clip_rect.w - 1); + drawn_area[3] = intmin(intmax(y1, y2), surf->clip_rect.y + surf->clip_rect.h - 1); dx = abs(x2 - x1); dy = -abs(y2 - y1); sx = x2 > x1 ? 1 : -1; @@ -1747,7 +1763,7 @@ draw_line(SDL_Surface *surf, int x1, int y1, int x2, int y2, Uint32 color, // Continue through normal Bresenham's line algorithm iteration while (y1 != end) { if (y1 != exit) { - set_and_check_rect(surf, x1, y1, color, drawn_area); + set_at(surf, x1, y1, color); } else break; @@ -1792,7 +1808,7 @@ draw_line(SDL_Surface *surf, int x1, int y1, int x2, int y2, Uint32 color, // Continue through normal Bresenham's line algorithm iteration while (x1 != end) { if (x1 != exit) { - set_and_check_rect(surf, x1, y1, color, drawn_area); + set_at(surf, x1, y1, color); } else break; diff --git a/testingfile.py b/testingfile.py new file mode 100644 index 0000000000..02bf8cf25e --- /dev/null +++ b/testingfile.py @@ -0,0 +1,118 @@ +from sys import stdout +from pstats import Stats +from cProfile import Profile + + +import pygame + +pygame.init() + + +def draw_line_short_inside(): + lines = [ + ((256, 256), (0, 0)), + ((128, 256), (128, 0)), + ((50, 256), (128, 0)), + ((0, 240), (12, 56)), + ((50, 40), (60, 11)), + ] + widths = [1, 2, 4, 6, 20] + surf = pygame.Surface((256, 256), pygame.SRCALPHA, 32) + surf.fill((255, 255, 255, 255)) + for iterations in range(0, 10000): + for line in lines: + for width in widths: + pygame.draw.line( + surf, pygame.Color("red"), line[0], line[1], width=width + ) + + +def draw_line_long_inside(): + lines = [ + ((1256, 256), (0, 0)), + ((1128, 256), (128, 0)), + ((150, 1256), (128, 0)), + ((0, 240), (1200, 56)), + ((50, 40), (1060, 11)), + ] + widths = [1, 2, 4, 6, 20] + surf = pygame.Surface((2048, 2048), pygame.SRCALPHA, 32) + surf.fill((255, 255, 255, 255)) + for iterations in range(0, 10000): + for line in lines: + for width in widths: + pygame.draw.line( + surf, pygame.Color("red"), line[0], line[1], width=width + ) + + +def draw_line_short_outside(): + lines = [ + ((256, 256), (0, 0)), + ((128, 256), (128, 0)), + ((50, 256), (128, 0)), + ((0, 240), (12, 56)), + ((50, 40), (80, 11)), + ] + widths = [1, 2, 4, 6, 20] + surf = pygame.Surface((64, 64), pygame.SRCALPHA, 32) + surf.fill((255, 255, 255, 255)) + for iterations in range(0, 10000): + for line in lines: + for width in widths: + pygame.draw.line( + surf, pygame.Color("red"), line[0], line[1], width=width + ) + + +def draw_line_long_outside(): + lines = [ + ((2256, 256), (0, 0)), + ((2128, 256), (128, 0)), + ((150, 4256), (128, 0)), + ((0, 240), (2200, 56)), + ((50, 40), (4060, 11)), + ] + widths = [1, 2, 4, 6, 20] + surf = pygame.Surface((1024, 1024), pygame.SRCALPHA, 32) + surf.fill((255, 255, 255, 255)) + for iterations in range(0, 10000): + for line in lines: + for width in widths: + pygame.draw.line( + surf, pygame.Color("red"), line[0], line[1], width=width + ) + + +if __name__ == "__main__": + print("Draw Line - short, inside surface") + profiler = Profile() + profiler.runcall(draw_line_short_inside) + stats = Stats(profiler, stream=stdout) + stats.strip_dirs() + stats.sort_stats("cumulative") + stats.print_stats() + + print("\nDraw Line - long, inside surface") + profiler = Profile() + profiler.runcall(draw_line_long_inside) + stats = Stats(profiler, stream=stdout) + stats.strip_dirs() + stats.sort_stats("cumulative") + stats.print_stats() + + print("\nDraw Line - short, edges outside surface") + profiler = Profile() + profiler.runcall(draw_line_short_outside) + stats = Stats(profiler, stream=stdout) + stats.strip_dirs() + stats.sort_stats("cumulative") + stats.print_stats() + + print("\nDraw Line - long, edges a long way outside surface") + profiler = Profile() + profiler.runcall(draw_line_long_outside) + stats = Stats(profiler, stream=stdout) + stats.strip_dirs() + stats.sort_stats("cumulative") + stats.print_stats() From b6a1c341dd3bfcf862f88b2825324152eb04aaa5 Mon Sep 17 00:00:00 2001 From: Temmie <76136819+Temmie3754@users.noreply.github.com> Date: Tue, 17 Oct 2023 12:58:05 +0100 Subject: [PATCH 8/9] Change rect drawing behaviour and improve algorithm --- src_c/draw.c | 22 +++---- test/draw_test.py | 153 ---------------------------------------------- 2 files changed, 8 insertions(+), 167 deletions(-) diff --git a/src_c/draw.c b/src_c/draw.c index 338957fc5d..604bb8f50a 100644 --- a/src_c/draw.c +++ b/src_c/draw.c @@ -1068,10 +1068,8 @@ clip_line(SDL_Surface *surf, int *x1, int *y1, int *x2, int *y2, int width, top = MIN(*y1, *y2) - width; bottom = MAX(*y1, *y2) + width; } - // 4 = no points within clip boundary - // 0 = all points within clip boundary - return ((surf->clip_rect.x > right) + (surf->clip_rect.y > bottom) + - (surf->clip_rect.x + surf->clip_rect.w <= left) + + return ((surf->clip_rect.x > right) || (surf->clip_rect.y > bottom) || + (surf->clip_rect.x + surf->clip_rect.w <= left) || (surf->clip_rect.y + surf->clip_rect.h <= top)); } @@ -1527,15 +1525,13 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, int extra_width = 1 - (width % 2); width = (width / 2); - /* Decide which direction to grow (width/thickness). */ if (abs(x1 - x2) <= abs(y1 - y2)) { /* The line's thickness will be in the x direction. The top/bottom * ends of the line will be flat. */ xinc = 1; } - int clipval = clip_line(surf, &x1, &y1, &x2, &y2, width, xinc); - if (clipval == 4) + if (clip_line(surf, &x1, &y1, &x2, &y2, width, xinc)) return; if (x1 == x2 && y1 == y2) { /* Single point */ @@ -1581,12 +1577,11 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, err += diff * dx; // Calculate change in x value (x = y/m), uses ceil for consistency // between positive/negative values - diff = (int)ceil(((float)diff * dx) / (float)-dy); + diff = (int)ceil((diff * dx) / (float)-dy); x1 += diff * sx; // Adjust err value to correct for change in x axis err += diff * dy; } - // Continue through normal Bresenham's line algorithm iteration while (y1 != exit) { @@ -1622,7 +1617,7 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, } else { diff = x1 - end_x; - exit = intmax(surf->clip_rect.x, x2 + sx); + exit = intmax(surf->clip_rect.x - 1, x2 + sx); } // If line starts outside of surface if (diff > 0) { @@ -1632,12 +1627,13 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, err += diff * dy; // Calculate change in y value (y = mx), uses ceil for consistency // between positive/negative values - diff = (int)ceil(((float)diff * -dy) / (float)dx); + diff = (int)ceil((diff * -dy) / (float)dx); y1 += diff * sy; // Adjust err value to correct for change in y axis err += diff * dx; } + // Continue through normal Bresenham's line algorithm iteration while (x1 != exit) { @@ -1648,8 +1644,6 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, drawvertline(surf, color, start_draw, x1, end_draw); } - else - break; e2 = err * 2; if (e2 >= dy) { err += dy; @@ -1682,7 +1676,7 @@ draw_line(SDL_Surface *surf, int x1, int y1, int x2, int y2, Uint32 color, xinc = 1; } - if (clip_line(surf, &x1, &y1, &x2, &y2, 0, xinc) == 4) + if (clip_line(surf, &x1, &y1, &x2, &y2, 0, xinc)) return; if (y1 == y2) { /* Horizontal line */ diff --git a/test/draw_test.py b/test/draw_test.py index 4429740b28..f6873f8344 100644 --- a/test/draw_test.py +++ b/test/draw_test.py @@ -1548,57 +1548,6 @@ def test_line__gaps_with_thickness(self): pos = (x, y + ((x + 2) // 5)) self.assertEqual(surface.get_at(pos), expected_color, f"pos={pos}") - def test_line__bounding_rect(self): - """Ensures draw line returns the correct bounding rect. - - Test lines with endpoints on and off the surface and a range of - width/thickness values. - """ - - line_color = pygame.Color("red") - surf_color = pygame.Color("black") - width = height = 30 - # Using a rect to help manage where the lines are drawn. - helper_rect = pygame.Rect((0, 0), (width, height)) - - # Testing surfaces of different sizes. One larger than the helper_rect - # and one smaller (to test lines that span the surface). - for size in ((width + 5, height + 5), (width - 5, height - 5)): - surface = pygame.Surface(size, 0, 32) - surf_rect = surface.get_rect() - - # Move the helper rect to different positions to test line - # endpoints on and off the surface. - for pos in rect_corners_mids_and_center(surf_rect): - helper_rect.center = pos - - # Draw using different thicknesses. - for thickness in range(-1, 5): - for start, end in self._rect_lines(helper_rect): - surface.fill(surf_color) # Clear for each test. - - bounding_rect = self.draw_line( - surface, line_color, start, end, thickness - ) - - if 0 < thickness: - # Calculating the expected_rect after the line is - # drawn (it uses what is actually drawn). - expected_rect = create_bounding_rect( - surface, surf_color, start - ) - else: - # Nothing drawn. - expected_rect = pygame.Rect(start, (0, 0)) - - self.assertEqual( - bounding_rect, - expected_rect, - "start={}, end={}, size={}, thickness={}".format( - start, end, size, thickness - ), - ) - def test_line__surface_clip(self): """Ensures draw line respects a surface's clip area.""" surfw = surfh = 30 @@ -2324,53 +2273,6 @@ def test_lines__gaps_with_thickness(self): pos = (x_right + t, y) self.assertEqual(surface.get_at(pos), expected_color, f"pos={pos}") - def test_lines__bounding_rect(self): - """Ensures draw lines returns the correct bounding rect. - - Test lines with endpoints on and off the surface and a range of - width/thickness values. - """ - line_color = pygame.Color("red") - surf_color = pygame.Color("black") - width = height = 30 - # Using a rect to help manage where the lines are drawn. - pos_rect = pygame.Rect((0, 0), (width, height)) - - # Testing surfaces of different sizes. One larger than the pos_rect - # and one smaller (to test lines that span the surface). - for size in ((width + 5, height + 5), (width - 5, height - 5)): - surface = pygame.Surface(size, 0, 32) - surf_rect = surface.get_rect() - - # Move pos_rect to different positions to test line endpoints on - # and off the surface. - for pos in rect_corners_mids_and_center(surf_rect): - pos_rect.center = pos - # Shape: Triangle (if closed), ^ caret (if not closed). - pts = (pos_rect.midleft, pos_rect.midtop, pos_rect.midright) - pos = pts[0] # Rect position if nothing drawn. - - # Draw using different thickness and closed values. - for thickness in range(-1, 5): - for closed in (True, False): - surface.fill(surf_color) # Clear for each test. - - bounding_rect = self.draw_lines( - surface, line_color, closed, pts, thickness - ) - - if 0 < thickness: - # Calculating the expected_rect after the lines are - # drawn (it uses what is actually drawn). - expected_rect = create_bounding_rect( - surface, surf_color, pos - ) - else: - # Nothing drawn. - expected_rect = pygame.Rect(pos, (0, 0)) - - self.assertEqual(bounding_rect, expected_rect) - def test_lines__surface_clip(self): """Ensures draw lines respects a surface's clip area.""" surfw = surfh = 30 @@ -4111,61 +4013,6 @@ def test_invalid_points(self): ), ) - def test_polygon__bounding_rect(self): - """Ensures draw polygon returns the correct bounding rect. - - Tests polygons on and off the surface and a range of width/thickness - values. - """ - polygon_color = pygame.Color("red") - surf_color = pygame.Color("black") - min_width = min_height = 5 - max_width = max_height = 7 - sizes = ((min_width, min_height), (max_width, max_height)) - surface = pygame.Surface((20, 20), 0, 32) - surf_rect = surface.get_rect() - # Make a rect that is bigger than the surface to help test drawing - # polygons off and partially off the surface. - big_rect = surf_rect.inflate(min_width * 2 + 1, min_height * 2 + 1) - - for pos in rect_corners_mids_and_center( - surf_rect - ) + rect_corners_mids_and_center(big_rect): - # A rect (pos_rect) is used to help create and position the - # polygon. Each of this rect's position attributes will be set to - # the pos value. - for attr in RECT_POSITION_ATTRIBUTES: - # Test using different rect sizes and thickness values. - for width, height in sizes: - pos_rect = pygame.Rect((0, 0), (width, height)) - setattr(pos_rect, attr, pos) - # Points form a triangle with no fully - # horizontal/vertical lines. - vertices = ( - pos_rect.midleft, - pos_rect.midtop, - pos_rect.bottomright, - ) - - for thickness in range(4): - surface.fill(surf_color) # Clear for each test. - - bounding_rect = self.draw_polygon( - surface, polygon_color, vertices, thickness - ) - - # Calculating the expected_rect after the polygon - # is drawn (it uses what is actually drawn). - expected_rect = create_bounding_rect( - surface, surf_color, vertices[0] - ) - - self.assertEqual( - bounding_rect, - expected_rect, - f"thickness={thickness}", - ) - def test_polygon__surface_clip(self): """Ensures draw polygon respects a surface's clip area. From c984784ed2b7cd1e732912ebd4f7ec68e5bebd06 Mon Sep 17 00:00:00 2001 From: Temmie <76136819+Temmie3754@users.noreply.github.com> Date: Tue, 17 Oct 2023 13:00:33 +0100 Subject: [PATCH 9/9] fix formatting --- src_c/draw.c | 56 ++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src_c/draw.c b/src_c/draw.c index 604bb8f50a..67febe7a98 100644 --- a/src_c/draw.c +++ b/src_c/draw.c @@ -1043,11 +1043,15 @@ add_line_to_drawn_list(int x1, int y1, int x2, int y2, int *pts) } // Prevents double evaluation -inline static int intmin(int a, int b) { +inline static int +intmin(int a, int b) +{ return ((a) < (b) ? (a) : (b)); } -inline static int intmax(int a, int b) { +inline static int +intmax(int a, int b) +{ return ((a) > (b) ? (a) : (b)); } @@ -1069,8 +1073,8 @@ clip_line(SDL_Surface *surf, int *x1, int *y1, int *x2, int *y2, int width, bottom = MAX(*y1, *y2) + width; } return ((surf->clip_rect.x > right) || (surf->clip_rect.y > bottom) || - (surf->clip_rect.x + surf->clip_rect.w <= left) || - (surf->clip_rect.y + surf->clip_rect.h <= top)); + (surf->clip_rect.x + surf->clip_rect.w <= left) || + (surf->clip_rect.y + surf->clip_rect.h <= top)); } static int @@ -1509,8 +1513,6 @@ static void draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, int y2, int width, int *drawn_area) { - - if (width < 1) return; if (width == 1) { @@ -1544,7 +1546,6 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, return; } - // Bresenham's line algorithm dx = abs(x2 - x1); dy = -abs(y2 - y1); @@ -1553,7 +1554,8 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, err = dx + dy; // If line is more vertical than horizontal if (xinc) { - drawn_area[0] = intmax((intmin(x1, x2) - width) + extra_width, surf->clip_rect.x); + drawn_area[0] = + intmax((intmin(x1, x2) - width) + extra_width, surf->clip_rect.x); drawn_area[1] = intmax(intmin(y1, y2), surf->clip_rect.y); drawn_area[2] = intmin(intmax(x1, x2) + width, end_x); drawn_area[3] = intmin(intmax(y1, y2), end_y); @@ -1584,9 +1586,7 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, } // Continue through normal Bresenham's line algorithm iteration while (y1 != exit) { - - start_draw = - intmax((x1 - width) + extra_width, surf->clip_rect.x); + start_draw = intmax((x1 - width) + extra_width, surf->clip_rect.x); end_draw = intmin(end_x, x1 + width); if (start_draw <= end_draw) { drawhorzline(surf, color, start_draw, y1, end_draw); @@ -1605,7 +1605,8 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, } else { drawn_area[0] = intmax(intmin(x1, x2), surf->clip_rect.x); - drawn_area[1] = intmax((intmin(y1, y2) - width) + extra_width, surf->clip_rect.y); + drawn_area[1] = + intmax((intmin(y1, y2) - width) + extra_width, surf->clip_rect.y); drawn_area[2] = intmin(MAX(x1, x2), end_x); drawn_area[3] = intmin(intmax(y1, y2) + width, end_y); // Set exit to x value of where line will leave surface @@ -1633,12 +1634,9 @@ draw_line_width(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2, err += diff * dx; } - // Continue through normal Bresenham's line algorithm iteration while (x1 != exit) { - - start_draw = - intmax((y1 - width) + extra_width, surf->clip_rect.y); + start_draw = intmax((y1 - width) + extra_width, surf->clip_rect.y); end_draw = intmin(end_y, y1 + width); if (start_draw <= end_draw) { drawvertline(surf, color, start_draw, x1, end_draw); @@ -1681,16 +1679,18 @@ draw_line(SDL_Surface *surf, int x1, int y1, int x2, int y2, Uint32 color, if (y1 == y2) { /* Horizontal line */ if (x1 < x2) { - drawhorzline(surf, color, intmax(x1, surf->clip_rect.x), y1, - intmin(x2, surf->clip_rect.x + surf->clip_rect.w - 1)); + drawhorzline( + surf, color, intmax(x1, surf->clip_rect.x), y1, + intmin(x2, surf->clip_rect.x + surf->clip_rect.w - 1)); add_line_to_drawn_list( intmax(x1, surf->clip_rect.x), y1, intmin(x2, surf->clip_rect.x + surf->clip_rect.w - 1), y1, drawn_area); } else { - drawhorzline(surf, color, intmax(x2, surf->clip_rect.x), y1, - intmin(x1, surf->clip_rect.x + surf->clip_rect.w - 1)); + drawhorzline( + surf, color, intmax(x2, surf->clip_rect.x), y1, + intmin(x1, surf->clip_rect.x + surf->clip_rect.w - 1)); add_line_to_drawn_list( intmax(x2, surf->clip_rect.x), y1, intmin(x1, surf->clip_rect.x + surf->clip_rect.w - 1), y1, @@ -1700,16 +1700,18 @@ draw_line(SDL_Surface *surf, int x1, int y1, int x2, int y2, Uint32 color, } if (x1 == x2) { /* Vertical line */ if (y1 < y2) { - drawvertline(surf, color, intmax(y1, surf->clip_rect.y), x1, - intmin(y2, surf->clip_rect.y + surf->clip_rect.h - 1)); + drawvertline( + surf, color, intmax(y1, surf->clip_rect.y), x1, + intmin(y2, surf->clip_rect.y + surf->clip_rect.h - 1)); add_line_to_drawn_list( x1, intmax(y1, surf->clip_rect.y), x1, intmin(y2, surf->clip_rect.y + surf->clip_rect.h - 1), drawn_area); } else { - drawvertline(surf, color, intmax(y2, surf->clip_rect.y), x1, - intmin(y1, surf->clip_rect.y + surf->clip_rect.h - 1)); + drawvertline( + surf, color, intmax(y2, surf->clip_rect.y), x1, + intmin(y1, surf->clip_rect.y + surf->clip_rect.h - 1)); add_line_to_drawn_list( x1, intmax(y2, surf->clip_rect.y), x1, intmin(y1, surf->clip_rect.y + surf->clip_rect.h - 1), @@ -1719,8 +1721,10 @@ draw_line(SDL_Surface *surf, int x1, int y1, int x2, int y2, Uint32 color, } drawn_area[0] = intmax(intmin(x1, x2), surf->clip_rect.x); drawn_area[1] = intmax(intmin(y1, y2), surf->clip_rect.y); - drawn_area[2] = intmin(intmax(x1, x2), surf->clip_rect.x + surf->clip_rect.w - 1); - drawn_area[3] = intmin(intmax(y1, y2), surf->clip_rect.y + surf->clip_rect.h - 1); + drawn_area[2] = + intmin(intmax(x1, x2), surf->clip_rect.x + surf->clip_rect.w - 1); + drawn_area[3] = + intmin(intmax(y1, y2), surf->clip_rect.y + surf->clip_rect.h - 1); dx = abs(x2 - x1); dy = -abs(y2 - y1); sx = x2 > x1 ? 1 : -1;